From 4e568fe9e3164a0cbc0137a28180086099453545 Mon Sep 17 00:00:00 2001 From: naison <895703375@qq.com> Date: Thu, 10 Jul 2025 10:35:48 +0800 Subject: [PATCH] hotfix: fix CVE (#669) * hotfix: fix CVE * feat: prefer use cmd rather than magic dns to set dns on linux * feat: update go work sum * feat: update ut --- go.mod | 99 +- go.sum | 292 +- go.work.sum | 665 +- pkg/dns/coredns.go | 60 - pkg/dns/dns_linux.go | 66 +- .../{forwardserver.go => forward_server.go} | 0 ...dserver_test.go => forward_server_test.go} | 0 pkg/handler/function_test.go | 2 +- vendor/cloud.google.com/go/auth/CHANGES.md | 396 - vendor/cloud.google.com/go/auth/LICENSE | 202 - vendor/cloud.google.com/go/auth/README.md | 40 - vendor/cloud.google.com/go/auth/auth.go | 618 - .../go/auth/credentials/compute.go | 102 - .../go/auth/credentials/detect.go | 316 - .../go/auth/credentials/doc.go | 45 - .../go/auth/credentials/filetypes.go | 231 - .../internal/externalaccount/aws_provider.go | 531 - .../externalaccount/executable_provider.go | 284 - .../externalaccount/externalaccount.go | 428 - .../internal/externalaccount/file_provider.go | 78 - .../internal/externalaccount/info.go | 74 - .../externalaccount/programmatic_provider.go | 30 - .../internal/externalaccount/url_provider.go | 93 - .../internal/externalaccount/x509_provider.go | 63 - .../externalaccountuser.go | 115 - .../go/auth/credentials/internal/gdch/gdch.go | 191 - .../internal/impersonate/idtoken.go | 105 - .../internal/impersonate/impersonate.go | 156 - .../internal/stsexchange/sts_exchange.go | 167 - .../go/auth/credentials/selfsignedjwt.go | 89 - .../go/auth/httptransport/httptransport.go | 247 - .../go/auth/httptransport/transport.go | 234 - .../go/auth/internal/credsfile/credsfile.go | 107 - .../go/auth/internal/credsfile/filetype.go | 157 - .../go/auth/internal/credsfile/parse.go | 98 - .../go/auth/internal/internal.go | 225 - .../go/auth/internal/jwt/jwt.go | 171 - .../go/auth/internal/transport/cba.go | 385 - .../internal/transport/cert/default_cert.go | 65 - .../transport/cert/enterprise_cert.go | 54 - .../transport/cert/secureconnect_cert.go | 124 - .../internal/transport/cert/workload_cert.go | 114 - .../go/auth/internal/transport/s2a.go | 138 - .../go/auth/internal/transport/transport.go | 107 - .../go/auth/oauth2adapt/CHANGES.md | 75 - .../go/auth/oauth2adapt/LICENSE | 202 - .../go/auth/oauth2adapt/oauth2adapt.go | 200 - .../cloud.google.com/go/auth/threelegged.go | 382 - .../go/compute/metadata/CHANGES.md | 66 - .../go/compute/metadata/LICENSE | 202 - .../go/compute/metadata/README.md | 27 - .../go/compute/metadata/log.go | 149 - .../go/compute/metadata/metadata.go | 872 - .../go/compute/metadata/retry.go | 114 - .../go/compute/metadata/retry_linux.go | 31 - .../go/compute/metadata/syscheck.go | 26 - .../go/compute/metadata/syscheck_linux.go | 28 - .../go/compute/metadata/syscheck_windows.go | 38 - .../Azure/azure-sdk-for-go/LICENSE.txt | 21 - .../Azure/azure-sdk-for-go/NOTICE.txt | 29 - .../profiles/latest/dns/mgmt/dns/models.go | 128 - .../privatedns/mgmt/privatedns/models.go | 149 - .../dns/mgmt/2018-05-01/dns/CHANGELOG.md | 2 - .../dns/mgmt/2018-05-01/dns/_meta.json | 11 - .../dns/mgmt/2018-05-01/dns/client.go | 43 - .../services/dns/mgmt/2018-05-01/dns/enums.go | 53 - .../dns/mgmt/2018-05-01/dns/models.go | 961 - .../dns/mgmt/2018-05-01/dns/recordsets.go | 774 - .../mgmt/2018-05-01/dns/resourcereference.go | 107 - .../dns/mgmt/2018-05-01/dns/version.go | 19 - .../services/dns/mgmt/2018-05-01/dns/zones.go | 606 - .../mgmt/2020-06-01/privatedns/CHANGELOG.md | 2 - .../mgmt/2020-06-01/privatedns/_meta.json | 11 - .../mgmt/2020-06-01/privatedns/client.go | 43 - .../mgmt/2020-06-01/privatedns/enums.go | 72 - .../mgmt/2020-06-01/privatedns/models.go | 1352 - .../2020-06-01/privatedns/privatezones.go | 614 - .../mgmt/2020-06-01/privatedns/recordsets.go | 640 - .../mgmt/2020-06-01/privatedns/version.go | 19 - .../privatedns/virtualnetworklinks.go | 509 - .../Azure/azure-sdk-for-go/version/version.go | 7 - .../github.com/Azure/go-autorest/.gitignore | 32 - .../github.com/Azure/go-autorest/CHANGELOG.md | 1004 - .../github.com/Azure/go-autorest/GNUmakefile | 23 - .../github.com/Azure/go-autorest/Gopkg.lock | 324 - .../github.com/Azure/go-autorest/Gopkg.toml | 59 - vendor/github.com/Azure/go-autorest/LICENSE | 191 - vendor/github.com/Azure/go-autorest/README.md | 165 - .../Azure/go-autorest/autorest/LICENSE | 191 - .../Azure/go-autorest/autorest/adal/LICENSE | 191 - .../Azure/go-autorest/autorest/adal/README.md | 294 - .../Azure/go-autorest/autorest/adal/config.go | 151 - .../go-autorest/autorest/adal/devicetoken.go | 273 - .../autorest/adal/go_mod_tidy_hack.go | 25 - .../go-autorest/autorest/adal/persist.go | 135 - .../Azure/go-autorest/autorest/adal/sender.go | 101 - .../Azure/go-autorest/autorest/adal/token.go | 1430 - .../go-autorest/autorest/adal/token_1.13.go | 76 - .../go-autorest/autorest/adal/token_legacy.go | 75 - .../go-autorest/autorest/adal/version.go | 45 - .../go-autorest/autorest/authorization.go | 353 - .../go-autorest/autorest/authorization_sas.go | 66 - .../autorest/authorization_storage.go | 307 - .../Azure/go-autorest/autorest/autorest.go | 150 - .../Azure/go-autorest/autorest/azure/async.go | 995 - .../go-autorest/autorest/azure/auth/LICENSE | 191 - .../go-autorest/autorest/azure/auth/README.md | 152 - .../go-autorest/autorest/azure/auth/auth.go | 772 - .../autorest/azure/auth/go_mod_tidy_hack.go | 25 - .../Azure/go-autorest/autorest/azure/azure.go | 388 - .../go-autorest/autorest/azure/cli/LICENSE | 191 - .../autorest/azure/cli/go_mod_tidy_hack.go | 25 - .../go-autorest/autorest/azure/cli/profile.go | 83 - .../go-autorest/autorest/azure/cli/token.go | 227 - .../autorest/azure/environments.go | 330 - .../autorest/azure/metadata_environment.go | 245 - .../Azure/go-autorest/autorest/azure/rp.go | 204 - .../Azure/go-autorest/autorest/client.go | 327 - .../Azure/go-autorest/autorest/date/LICENSE | 191 - .../Azure/go-autorest/autorest/date/date.go | 96 - .../autorest/date/go_mod_tidy_hack.go | 24 - .../Azure/go-autorest/autorest/date/time.go | 103 - .../go-autorest/autorest/date/timerfc1123.go | 100 - .../go-autorest/autorest/date/unixtime.go | 123 - .../go-autorest/autorest/date/utility.go | 25 - .../Azure/go-autorest/autorest/error.go | 103 - .../go-autorest/autorest/go_mod_tidy_hack.go | 25 - .../Azure/go-autorest/autorest/preparer.go | 548 - .../Azure/go-autorest/autorest/responder.go | 268 - .../go-autorest/autorest/retriablerequest.go | 51 - .../autorest/retriablerequest_1.7.go | 55 - .../autorest/retriablerequest_1.8.go | 66 - .../Azure/go-autorest/autorest/sender.go | 458 - .../Azure/go-autorest/autorest/to/LICENSE | 191 - .../Azure/go-autorest/autorest/to/convert.go | 152 - .../autorest/to/go_mod_tidy_hack.go | 24 - .../Azure/go-autorest/autorest/utility.go | 231 - .../go-autorest/autorest/utility_1.13.go | 30 - .../go-autorest/autorest/utility_legacy.go | 32 - .../Azure/go-autorest/autorest/version.go | 41 - .../Azure/go-autorest/azure-pipelines.yml | 105 - vendor/github.com/Azure/go-autorest/doc.go | 18 - .../Azure/go-autorest/logger/LICENSE | 191 - .../go-autorest/logger/go_mod_tidy_hack.go | 24 - .../Azure/go-autorest/logger/logger.go | 337 - .../Azure/go-autorest/tracing/LICENSE | 191 - .../go-autorest/tracing/go_mod_tidy_hack.go | 24 - .../Azure/go-autorest/tracing/tracing.go | 67 - .../DataDog/appsec-internal-go/LICENSE | 200 - .../appsec-internal-go/appsec/config.go | 203 - .../appsec-internal-go/appsec/embed.go | 14 - .../appsec-internal-go/appsec/rules.go | 26 - .../appsec-internal-go/appsec/rules.json | 9779 ---- .../appsec-internal-go/httpsec/client_ip.go | 126 - .../appsec-internal-go/limiter/limiter.go | 147 - .../DataDog/appsec-internal-go/log/backend.go | 138 - .../DataDog/appsec-internal-go/log/log.go | 45 - .../DataDog/appsec-internal-go/netip/ip.go | 31 - .../datadog-agent/pkg/obfuscate/LICENSE | 200 - .../datadog-agent/pkg/obfuscate/cache.go | 90 - .../pkg/obfuscate/credit_cards.go | 269 - .../datadog-agent/pkg/obfuscate/http.go | 60 - .../datadog-agent/pkg/obfuscate/ip_address.go | 168 - .../datadog-agent/pkg/obfuscate/json.go | 234 - .../pkg/obfuscate/json_scanner.go | 560 - .../datadog-agent/pkg/obfuscate/memcached.go | 26 - .../datadog-agent/pkg/obfuscate/obfuscate.go | 354 - .../datadog-agent/pkg/obfuscate/redis.go | 301 - .../pkg/obfuscate/redis_tokenizer.go | 187 - .../datadog-agent/pkg/obfuscate/sql.go | 502 - .../pkg/obfuscate/sql_tokenizer.go | 929 - .../DataDog/datadog-agent/pkg/proto/LICENSE | 200 - .../pkg/proto/pbgo/trace/agent_payload.pb.go | 240 - .../pkg/proto/pbgo/trace/agent_payload_gen.go | 200 - .../pbgo/trace/agent_payload_vtproto.pb.go | 523 - .../pkg/proto/pbgo/trace/decoder_bytes.go | 275 - .../pkg/proto/pbgo/trace/decoder_v05.go | 223 - .../pkg/proto/pbgo/trace/span.pb.go | 448 - .../pkg/proto/pbgo/trace/span_gen.go | 577 - .../pkg/proto/pbgo/trace/span_utils.go | 53 - .../pkg/proto/pbgo/trace/span_vtproto.pb.go | 1445 - .../pkg/proto/pbgo/trace/stats.pb.go | 837 - .../pkg/proto/pbgo/trace/stats_gen.go | 1844 - .../pkg/proto/pbgo/trace/stats_vtproto.pb.go | 1968 - .../pkg/proto/pbgo/trace/trace.go | 52 - .../pkg/proto/pbgo/trace/trace_gen.go | 158 - .../pkg/proto/pbgo/trace/tracer_payload.pb.go | 391 - .../proto/pbgo/trace/tracer_payload_gen.go | 384 - .../proto/pbgo/trace/tracer_payload_utils.go | 35 - .../pbgo/trace/tracer_payload_vtproto.pb.go | 1066 - .../pkg/remoteconfig/state/LICENSE | 200 - .../pkg/remoteconfig/state/README.md | 5 - .../pkg/remoteconfig/state/agent_config.go | 159 - .../pkg/remoteconfig/state/configs.go | 123 - .../remoteconfig/state/configs_agent_task.go | 59 - .../pkg/remoteconfig/state/configs_asm.go | 166 - .../pkg/remoteconfig/state/path.go | 100 - .../pkg/remoteconfig/state/products.go | 84 - .../pkg/remoteconfig/state/repository.go | 444 - .../pkg/remoteconfig/state/tuf.go | 233 - .../DataDog/datadog-agent/pkg/trace/LICENSE | 200 - .../datadog-agent/pkg/trace/config/client.go | 70 - .../datadog-agent/pkg/trace/config/config.go | 621 - .../pkg/trace/config/peer_tags.go | 55 - .../pkg/trace/config/peer_tags.ini | 18 - .../datadog-agent/pkg/trace/log/buflogger.go | 97 - .../datadog-agent/pkg/trace/log/logger.go | 196 - .../datadog-agent/pkg/trace/log/throttled.go | 63 - .../pkg/trace/stats/aggregation.go | 130 - .../trace/stats/client_stats_aggregator.go | 438 - .../pkg/trace/stats/concentrator.go | 182 - .../pkg/trace/stats/otel_util.go | 149 - .../pkg/trace/stats/span_concentrator.go | 253 - .../datadog-agent/pkg/trace/stats/statsraw.go | 206 - .../datadog-agent/pkg/trace/stats/weight.go | 24 - .../pkg/trace/traceutil/azure.go | 166 - .../datadog-agent/pkg/trace/traceutil/doc.go | 8 - .../pkg/trace/traceutil/normalize.go | 356 - .../pkg/trace/traceutil/otel_util.go | 329 - .../pkg/trace/traceutil/processed_trace.go | 53 - .../datadog-agent/pkg/trace/traceutil/span.go | 175 - .../pkg/trace/traceutil/trace.go | 119 - .../pkg/trace/traceutil/truncate.go | 37 - .../pkg/trace/version/version.go | 78 - .../datadog-agent/pkg/trace/watchdog/cpu.go | 51 - .../pkg/trace/watchdog/cpu_aix.go | 111 - .../pkg/trace/watchdog/cpu_windows.go | 56 - .../datadog-agent/pkg/trace/watchdog/info.go | 99 - .../pkg/trace/watchdog/logonpanic.go | 49 - .../datadog-agent/pkg/util/log/LICENSE | 200 - .../pkg/util/log/klog_redirect.go | 59 - .../DataDog/datadog-agent/pkg/util/log/log.go | 1046 - .../datadog-agent/pkg/util/log/log_limit.go | 74 - .../pkg/util/log/log_not_serverless.go | 18 - .../pkg/util/log/log_serverless.go | 18 - .../pkg/util/log/log_test_init.go | 22 - .../datadog-agent/pkg/util/log/wrapper.go | 77 - .../datadog-agent/pkg/util/scrubber/LICENSE | 200 - .../pkg/util/scrubber/default.go | 378 - .../pkg/util/scrubber/json_scrubber.go | 33 - .../pkg/util/scrubber/scrubber.go | 196 - .../pkg/util/scrubber/yaml_scrubber.go | 117 - .../DataDog/datadog-go/v5/LICENSE.txt | 19 - .../DataDog/datadog-go/v5/statsd/README.md | 4 - .../datadog-go/v5/statsd/aggregator.go | 298 - .../DataDog/datadog-go/v5/statsd/buffer.go | 198 - .../datadog-go/v5/statsd/buffer_pool.go | 40 - .../v5/statsd/buffered_metric_context.go | 104 - .../DataDog/datadog-go/v5/statsd/container.go | 19 - .../datadog-go/v5/statsd/container_linux.go | 206 - .../datadog-go/v5/statsd/container_stub.go | 13 - .../datadog-go/v5/statsd/error_handler.go | 22 - .../DataDog/datadog-go/v5/statsd/event.go | 75 - .../DataDog/datadog-go/v5/statsd/fnv1a.go | 39 - .../DataDog/datadog-go/v5/statsd/format.go | 280 - .../DataDog/datadog-go/v5/statsd/metrics.go | 268 - .../DataDog/datadog-go/v5/statsd/noop.go | 118 - .../DataDog/datadog-go/v5/statsd/options.go | 413 - .../DataDog/datadog-go/v5/statsd/pipe.go | 13 - .../datadog-go/v5/statsd/pipe_windows.go | 81 - .../DataDog/datadog-go/v5/statsd/sender.go | 145 - .../datadog-go/v5/statsd/service_check.go | 57 - .../DataDog/datadog-go/v5/statsd/statsd.go | 919 - .../datadog-go/v5/statsd/statsd_direct.go | 69 - .../DataDog/datadog-go/v5/statsd/telemetry.go | 306 - .../DataDog/datadog-go/v5/statsd/udp.go | 39 - .../DataDog/datadog-go/v5/statsd/uds.go | 167 - .../datadog-go/v5/statsd/uds_windows.go | 15 - .../DataDog/datadog-go/v5/statsd/utils.go | 32 - .../DataDog/datadog-go/v5/statsd/worker.go | 158 - .../DataDog/go-libddwaf/v3/.gitattributes | 3 - .../DataDog/go-libddwaf/v3/.gitignore | 23 - .../DataDog/go-libddwaf/v3/CODEOWNERS | 2 - .../github.com/DataDog/go-libddwaf/v3/LICENSE | 200 - .../DataDog/go-libddwaf/v3/README.md | 151 - .../DataDog/go-libddwaf/v3/cgo_ref_pool.go | 106 - .../DataDog/go-libddwaf/v3/context.go | 327 - .../DataDog/go-libddwaf/v3/decoder.go | 253 - .../DataDog/go-libddwaf/v3/encoder.go | 507 - .../DataDog/go-libddwaf/v3/errors/support.go | 45 - .../DataDog/go-libddwaf/v3/errors/waf.go | 76 - .../DataDog/go-libddwaf/v3/handle.go | 258 - .../v3/internal/bindings/ctypes.go | 113 - .../go-libddwaf/v3/internal/bindings/safe.go | 48 - .../v3/internal/bindings/waf_dl.go | 238 - .../internal/bindings/waf_dl_unsupported.go | 55 - .../go-libddwaf/v3/internal/lib/.version | 1 - .../go-libddwaf/v3/internal/lib/README.md | 21 - .../go-libddwaf/v3/internal/lib/doc.go | 7 - .../v3/internal/lib/dump_waf_darwin.go | 57 - .../v3/internal/lib/dump_waf_linux.go | 58 - .../v3/internal/lib/lib_darwin_amd64.go | 15 - .../v3/internal/lib/lib_darwin_arm64.go | 15 - .../v3/internal/lib/lib_linux_amd64.go | 15 - .../v3/internal/lib/lib_linux_arm64.go | 15 - .../lib/libddwaf-darwin-amd64.dylib.gz | Bin 706738 -> 0 bytes .../lib/libddwaf-darwin-arm64.dylib.gz | Bin 651209 -> 0 bytes .../internal/lib/libddwaf-linux-amd64.so.gz | Bin 880887 -> 0 bytes .../internal/lib/libddwaf-linux-arm64.so.gz | Bin 832726 -> 0 bytes .../go-libddwaf/v3/internal/lib/version.go | 13 - .../go-libddwaf/v3/internal/log/ddwaf.h | 736 - .../go-libddwaf/v3/internal/log/log.go | 97 - .../go-libddwaf/v3/internal/log/log_cgo.go | 35 - .../go-libddwaf/v3/internal/log/log_purego.go | 37 - .../v3/internal/log/log_unsupported.go | 14 - .../v3/internal/support/waf_cgo_disabled.go | 16 - .../internal/support/waf_manually_disabled.go | 15 - .../v3/internal/support/waf_support.go | 21 - .../v3/internal/support/waf_unsupported_go.go | 15 - .../support/waf_unsupported_target.go | 20 - .../go-libddwaf/v3/internal/unsafe/utils.go | 107 - .../DataDog/go-libddwaf/v3/metrics.go | 140 - .../go-libddwaf/v3/timer/base_timer.go | 125 - .../DataDog/go-libddwaf/v3/timer/clock.go | 28 - .../DataDog/go-libddwaf/v3/timer/component.go | 28 - .../DataDog/go-libddwaf/v3/timer/config.go | 86 - .../go-libddwaf/v3/timer/node_timer.go | 147 - .../DataDog/go-libddwaf/v3/timer/timer.go | 115 - .../github.com/DataDog/go-libddwaf/v3/waf.go | 186 - .../go-runtime-metrics-internal/LICENSE | 201 - .../LICENSE-3rdparty.csv | 7 - .../go-runtime-metrics-internal/NOTICE | 4 - .../pkg/runtimemetrics/histogram.go | 195 - .../pkg/runtimemetrics/runtime_metrics.go | 306 - .../pkg/runtimemetrics/tags.go | 69 - .../github.com/DataDog/go-sqllexer/.gitignore | 21 - vendor/github.com/DataDog/go-sqllexer/LICENSE | 21 - .../github.com/DataDog/go-sqllexer/README.md | 90 - .../DataDog/go-sqllexer/normalizer.go | 350 - .../go-sqllexer/obfuscate_and_normalize.go | 43 - .../DataDog/go-sqllexer/obfuscator.go | 128 - .../DataDog/go-sqllexer/sqllexer.go | 485 - .../DataDog/go-sqllexer/sqllexer_utils.go | 265 - vendor/github.com/DataDog/go-tuf/LICENSE | 27 - .../DataDog/go-tuf/client/client.go | 955 - .../DataDog/go-tuf/client/delegations.go | 193 - .../DataDog/go-tuf/client/errors.go | 107 - .../DataDog/go-tuf/client/file_store.go | 90 - .../DataDog/go-tuf/client/local_store.go | 29 - .../DataDog/go-tuf/client/remote_store.go | 109 - .../DataDog/go-tuf/data/hex_bytes.go | 42 - .../github.com/DataDog/go-tuf/data/types.go | 348 - .../DataDog/go-tuf/internal/roles/roles.go | 48 - .../DataDog/go-tuf/internal/sets/strings.go | 24 - .../go-tuf/pkg/keys/deprecated_ecdsa.go | 101 - .../DataDog/go-tuf/pkg/keys/ecdsa.go | 173 - .../DataDog/go-tuf/pkg/keys/ed25519.go | 161 - .../DataDog/go-tuf/pkg/keys/keys.go | 82 - .../DataDog/go-tuf/pkg/keys/pkix.go | 56 - .../github.com/DataDog/go-tuf/pkg/keys/rsa.go | 162 - .../DataDog/go-tuf/pkg/targets/delegation.go | 102 - .../DataDog/go-tuf/pkg/targets/hash_bins.go | 113 - vendor/github.com/DataDog/go-tuf/util/util.go | 332 - vendor/github.com/DataDog/go-tuf/verify/db.go | 104 - .../DataDog/go-tuf/verify/errors.go | 73 - .../DataDog/go-tuf/verify/verify.go | 187 - .../pkg/otlp/attributes/LICENSE | 201 - .../pkg/otlp/attributes/attributes.go | 289 - .../pkg/otlp/attributes/azure/azure.go | 59 - .../pkg/otlp/attributes/ec2/ec2.go | 95 - .../pkg/otlp/attributes/gcp/gcp.go | 79 - .../pkg/otlp/attributes/process.go | 56 - .../pkg/otlp/attributes/source.go | 160 - .../otlp/attributes/source/source_provider.go | 51 - .../pkg/otlp/attributes/system.go | 36 - .../pkg/otlp/attributes/translator.go | 71 - vendor/github.com/DataDog/sketches-go/LICENSE | 13 - .../DataDog/sketches-go/LICENSE-3rdparty.csv | 3 - vendor/github.com/DataDog/sketches-go/NOTICE | 4 - .../DataDog/sketches-go/ddsketch/ddsketch.go | 767 - .../sketches-go/ddsketch/encoding/encoding.go | 208 - .../sketches-go/ddsketch/encoding/flag.go | 160 - .../ddsketch/mapping/bit_operation_helper.go | 35 - .../mapping/cubically_interpolated_mapping.go | 146 - .../ddsketch/mapping/index_mapping.go | 95 - .../mapping/linearly_interpolated_mapping.go | 142 - .../ddsketch/mapping/logarithmic_mapping.go | 119 - .../ddsketch/pb/sketchpb/ddsketch.pb.go | 448 - .../sketches-go/ddsketch/stat/summary.go | 171 - .../DataDog/sketches-go/ddsketch/store/bin.go | 28 - .../ddsketch/store/buffered_paginated.go | 667 - .../store/collapsing_highest_dense_store.go | 188 - .../store/collapsing_lowest_dense_store.go | 207 - .../sketches-go/ddsketch/store/dense_store.go | 330 - .../sketches-go/ddsketch/store/sparse.go | 184 - .../sketches-go/ddsketch/store/store.go | 153 - .../github.com/apparentlymart/go-cidr/LICENSE | 19 - .../apparentlymart/go-cidr/cidr/cidr.go | 236 - .../apparentlymart/go-cidr/cidr/wrangling.go | 37 - .../github.com/aws/aws-sdk-go-v2/LICENSE.txt | 202 - .../github.com/aws/aws-sdk-go-v2/NOTICE.txt | 3 - .../aws/accountid_endpoint_mode.go | 18 - .../aws/aws-sdk-go-v2/aws/checksum.go | 33 - .../aws/aws-sdk-go-v2/aws/config.go | 238 - .../aws/aws-sdk-go-v2/aws/context.go | 22 - .../aws/aws-sdk-go-v2/aws/credential_cache.go | 235 - .../aws/aws-sdk-go-v2/aws/credentials.go | 230 - .../aws/aws-sdk-go-v2/aws/defaults/auto.go | 38 - .../aws/defaults/configuration.go | 43 - .../aws-sdk-go-v2/aws/defaults/defaults.go | 50 - .../aws/aws-sdk-go-v2/aws/defaults/doc.go | 2 - .../aws/aws-sdk-go-v2/aws/defaultsmode.go | 95 - .../github.com/aws/aws-sdk-go-v2/aws/doc.go | 62 - .../aws/aws-sdk-go-v2/aws/endpoints.go | 247 - .../aws/aws-sdk-go-v2/aws/errors.go | 9 - .../aws/aws-sdk-go-v2/aws/from_ptr.go | 365 - .../aws-sdk-go-v2/aws/go_module_metadata.go | 6 - .../aws/aws-sdk-go-v2/aws/logging.go | 119 - .../aws/aws-sdk-go-v2/aws/logging_generate.go | 95 - .../aws-sdk-go-v2/aws/middleware/metadata.go | 213 - .../aws/middleware/middleware.go | 168 - .../aws-sdk-go-v2/aws/middleware/osname.go | 24 - .../aws/middleware/osname_go115.go | 24 - .../aws/middleware/recursion_detection.go | 94 - .../aws/middleware/request_id.go | 27 - .../aws/middleware/request_id_retriever.go | 57 - .../aws/middleware/user_agent.go | 391 - .../aws-sdk-go-v2/aws/protocol/query/array.go | 61 - .../aws/protocol/query/encoder.go | 80 - .../aws-sdk-go-v2/aws/protocol/query/map.go | 78 - .../aws/protocol/query/middleware.go | 62 - .../aws/protocol/query/object.go | 68 - .../aws-sdk-go-v2/aws/protocol/query/value.go | 117 - .../aws/protocol/restjson/decoder_util.go | 85 - .../aws/protocol/xml/error_utils.go | 48 - .../aws/aws-sdk-go-v2/aws/ratelimit/none.go | 20 - .../aws/ratelimit/token_bucket.go | 96 - .../aws/ratelimit/token_rate_limit.go | 83 - .../aws/aws-sdk-go-v2/aws/request.go | 25 - .../aws/aws-sdk-go-v2/aws/retry/adaptive.go | 156 - .../aws/retry/adaptive_ratelimit.go | 158 - .../aws/retry/adaptive_token_bucket.go | 83 - .../aws/retry/attempt_metrics.go | 51 - .../aws/aws-sdk-go-v2/aws/retry/doc.go | 80 - .../aws/aws-sdk-go-v2/aws/retry/errors.go | 20 - .../aws-sdk-go-v2/aws/retry/jitter_backoff.go | 49 - .../aws/aws-sdk-go-v2/aws/retry/metadata.go | 52 - .../aws/aws-sdk-go-v2/aws/retry/middleware.go | 418 - .../aws/aws-sdk-go-v2/aws/retry/retry.go | 90 - .../aws/retry/retryable_error.go | 228 - .../aws/aws-sdk-go-v2/aws/retry/standard.go | 269 - .../aws-sdk-go-v2/aws/retry/throttle_error.go | 60 - .../aws-sdk-go-v2/aws/retry/timeout_error.go | 52 - .../aws/aws-sdk-go-v2/aws/retryer.go | 127 - .../aws/aws-sdk-go-v2/aws/runtime.go | 14 - .../aws/signer/internal/v4/cache.go | 115 - .../aws/signer/internal/v4/const.go | 40 - .../aws/signer/internal/v4/header_rules.go | 82 - .../aws/signer/internal/v4/headers.go | 70 - .../aws/signer/internal/v4/hmac.go | 13 - .../aws/signer/internal/v4/host.go | 75 - .../aws/signer/internal/v4/scope.go | 13 - .../aws/signer/internal/v4/time.go | 36 - .../aws/signer/internal/v4/util.go | 80 - .../aws-sdk-go-v2/aws/signer/v4/middleware.go | 420 - .../aws/signer/v4/presign_middleware.go | 127 - .../aws/aws-sdk-go-v2/aws/signer/v4/stream.go | 86 - .../aws/aws-sdk-go-v2/aws/signer/v4/v4.go | 564 - .../aws/aws-sdk-go-v2/aws/to_ptr.go | 297 - .../aws/transport/http/client.go | 342 - .../aws/transport/http/content_type.go | 42 - .../aws/transport/http/response_error.go | 33 - .../http/response_error_middleware.go | 56 - .../aws/transport/http/timeout_read_closer.go | 104 - .../github.com/aws/aws-sdk-go-v2/aws/types.go | 42 - .../aws/aws-sdk-go-v2/aws/version.go | 8 - .../aws/aws-sdk-go-v2/config/CHANGELOG.md | 837 - .../aws/aws-sdk-go-v2/config/LICENSE.txt | 202 - .../aws/aws-sdk-go-v2/config/config.go | 228 - .../aws/aws-sdk-go-v2/config/defaultsmode.go | 47 - .../aws/aws-sdk-go-v2/config/doc.go | 20 - .../aws/aws-sdk-go-v2/config/env_config.go | 918 - .../aws/aws-sdk-go-v2/config/generate.go | 4 - .../config/go_module_metadata.go | 6 - .../aws/aws-sdk-go-v2/config/load_options.go | 1209 - .../aws/aws-sdk-go-v2/config/local.go | 51 - .../aws/aws-sdk-go-v2/config/provider.go | 755 - .../aws/aws-sdk-go-v2/config/resolve.go | 413 - .../config/resolve_bearer_token.go | 122 - .../config/resolve_credentials.go | 627 - .../aws/aws-sdk-go-v2/config/shared_config.go | 1680 - .../aws-sdk-go-v2/credentials/CHANGELOG.md | 736 - .../aws/aws-sdk-go-v2/credentials/LICENSE.txt | 202 - .../aws/aws-sdk-go-v2/credentials/doc.go | 4 - .../credentials/ec2rolecreds/doc.go | 58 - .../credentials/ec2rolecreds/provider.go | 241 - .../endpointcreds/internal/client/auth.go | 48 - .../endpointcreds/internal/client/client.go | 165 - .../internal/client/endpoints.go | 20 - .../internal/client/middleware.go | 164 - .../credentials/endpointcreds/provider.go | 207 - .../credentials/go_module_metadata.go | 6 - .../credentials/processcreds/doc.go | 92 - .../credentials/processcreds/provider.go | 296 - .../aws-sdk-go-v2/credentials/ssocreds/doc.go | 81 - .../credentials/ssocreds/sso_cached_token.go | 233 - .../ssocreds/sso_credentials_provider.go | 165 - .../ssocreds/sso_token_provider.go | 147 - .../credentials/static_provider.go | 63 - .../stscreds/assume_role_provider.go | 338 - .../stscreds/web_identity_provider.go | 181 - .../feature/ec2/imds/CHANGELOG.md | 435 - .../feature/ec2/imds/LICENSE.txt | 202 - .../feature/ec2/imds/api_client.go | 352 - .../feature/ec2/imds/api_op_GetDynamicData.go | 77 - .../feature/ec2/imds/api_op_GetIAMInfo.go | 103 - .../api_op_GetInstanceIdentityDocument.go | 110 - .../feature/ec2/imds/api_op_GetMetadata.go | 77 - .../feature/ec2/imds/api_op_GetRegion.go | 73 - .../feature/ec2/imds/api_op_GetToken.go | 119 - .../feature/ec2/imds/api_op_GetUserData.go | 61 - .../aws-sdk-go-v2/feature/ec2/imds/auth.go | 48 - .../aws/aws-sdk-go-v2/feature/ec2/imds/doc.go | 12 - .../feature/ec2/imds/endpoints.go | 20 - .../feature/ec2/imds/go_module_metadata.go | 6 - .../ec2/imds/internal/config/resolvers.go | 114 - .../feature/ec2/imds/request_middleware.go | 313 - .../feature/ec2/imds/token_provider.go | 261 - .../aws/aws-sdk-go-v2/internal/auth/auth.go | 45 - .../aws/aws-sdk-go-v2/internal/auth/scheme.go | 191 - .../auth/smithy/bearer_token_adapter.go | 43 - .../smithy/bearer_token_signer_adapter.go | 35 - .../auth/smithy/credentials_adapter.go | 46 - .../internal/auth/smithy/smithy.go | 2 - .../internal/auth/smithy/v4signer_adapter.go | 57 - .../internal/configsources/CHANGELOG.md | 400 - .../internal/configsources/LICENSE.txt | 202 - .../internal/configsources/config.go | 65 - .../internal/configsources/endpoints.go | 57 - .../configsources/go_module_metadata.go | 6 - .../aws-sdk-go-v2/internal/context/context.go | 52 - .../internal/endpoints/awsrulesfn/arn.go | 94 - .../internal/endpoints/awsrulesfn/doc.go | 3 - .../internal/endpoints/awsrulesfn/generate.go | 7 - .../internal/endpoints/awsrulesfn/host.go | 51 - .../endpoints/awsrulesfn/partition.go | 76 - .../endpoints/awsrulesfn/partitions.go | 403 - .../endpoints/awsrulesfn/partitions.json | 239 - .../internal/endpoints/endpoints.go | 201 - .../internal/endpoints/v2/CHANGELOG.md | 375 - .../internal/endpoints/v2/LICENSE.txt | 202 - .../internal/endpoints/v2/endpoints.go | 302 - .../endpoints/v2/go_module_metadata.go | 6 - .../aws-sdk-go-v2/internal/ini/CHANGELOG.md | 283 - .../aws-sdk-go-v2/internal/ini/LICENSE.txt | 202 - .../aws/aws-sdk-go-v2/internal/ini/errors.go | 22 - .../internal/ini/go_module_metadata.go | 6 - .../aws/aws-sdk-go-v2/internal/ini/ini.go | 56 - .../aws/aws-sdk-go-v2/internal/ini/parse.go | 109 - .../aws-sdk-go-v2/internal/ini/sections.go | 157 - .../aws/aws-sdk-go-v2/internal/ini/strings.go | 89 - .../aws/aws-sdk-go-v2/internal/ini/token.go | 32 - .../aws-sdk-go-v2/internal/ini/tokenize.go | 92 - .../aws/aws-sdk-go-v2/internal/ini/value.go | 93 - .../internal/middleware/middleware.go | 42 - .../aws/aws-sdk-go-v2/internal/rand/rand.go | 33 - .../aws-sdk-go-v2/internal/sdk/interfaces.go | 9 - .../aws/aws-sdk-go-v2/internal/sdk/time.go | 74 - .../aws/aws-sdk-go-v2/internal/sdkio/byte.go | 12 - .../internal/shareddefaults/shared_config.go | 47 - .../aws-sdk-go-v2/internal/strings/strings.go | 11 - .../internal/sync/singleflight/LICENSE | 28 - .../internal/sync/singleflight/docs.go | 7 - .../sync/singleflight/singleflight.go | 210 - .../internal/timeconv/duration.go | 13 - .../internal/accept-encoding/CHANGELOG.md | 164 - .../internal/accept-encoding/LICENSE.txt | 202 - .../accept-encoding/accept_encoding_gzip.go | 176 - .../service/internal/accept-encoding/doc.go | 22 - .../accept-encoding/go_module_metadata.go | 6 - .../internal/presigned-url/CHANGELOG.md | 427 - .../internal/presigned-url/LICENSE.txt | 202 - .../service/internal/presigned-url/context.go | 56 - .../service/internal/presigned-url/doc.go | 3 - .../presigned-url/go_module_metadata.go | 6 - .../internal/presigned-url/middleware.go | 110 - .../service/secretsmanager/CHANGELOG.md | 696 - .../service/secretsmanager/LICENSE.txt | 202 - .../service/secretsmanager/api_client.go | 959 - .../api_op_BatchGetSecretValue.go | 303 - .../api_op_CancelRotateSecret.go | 197 - .../secretsmanager/api_op_CreateSecret.go | 394 - .../api_op_DeleteResourcePolicy.go | 179 - .../secretsmanager/api_op_DeleteSecret.go | 236 - .../secretsmanager/api_op_DescribeSecret.go | 291 - .../api_op_GetRandomPassword.go | 196 - .../api_op_GetResourcePolicy.go | 188 - .../secretsmanager/api_op_GetSecretValue.go | 249 - .../api_op_ListSecretVersionIds.go | 308 - .../secretsmanager/api_op_ListSecrets.go | 300 - .../api_op_PutResourcePolicy.go | 212 - .../secretsmanager/api_op_PutSecretValue.go | 339 - .../api_op_RemoveRegionsFromReplication.go | 180 - .../api_op_ReplicateSecretToRegions.go | 187 - .../secretsmanager/api_op_RestoreSecret.go | 179 - .../secretsmanager/api_op_RotateSecret.go | 281 - .../api_op_StopReplicationToReplica.go | 175 - .../secretsmanager/api_op_TagResource.go | 196 - .../secretsmanager/api_op_UntagResource.go | 193 - .../secretsmanager/api_op_UpdateSecret.go | 327 - .../api_op_UpdateSecretVersionStage.go | 217 - .../api_op_ValidateResourcePolicy.go | 194 - .../service/secretsmanager/auth.go | 313 - .../service/secretsmanager/deserializers.go | 6094 -- .../service/secretsmanager/doc.go | 45 - .../service/secretsmanager/endpoints.go | 632 - .../service/secretsmanager/generated.json | 56 - .../secretsmanager/go_module_metadata.go | 6 - .../internal/endpoints/endpoints.go | 714 - .../service/secretsmanager/options.go | 236 - .../service/secretsmanager/serializers.go | 2156 - .../service/secretsmanager/types/enums.go | 72 - .../service/secretsmanager/types/errors.go | 339 - .../service/secretsmanager/types/types.go | 321 - .../service/secretsmanager/validators.go | 808 - .../aws-sdk-go-v2/service/sso/CHANGELOG.md | 594 - .../aws/aws-sdk-go-v2/service/sso/LICENSE.txt | 202 - .../aws-sdk-go-v2/service/sso/api_client.go | 943 - .../service/sso/api_op_GetRoleCredentials.go | 171 - .../service/sso/api_op_ListAccountRoles.go | 269 - .../service/sso/api_op_ListAccounts.go | 267 - .../service/sso/api_op_Logout.go | 170 - .../aws/aws-sdk-go-v2/service/sso/auth.go | 337 - .../service/sso/deserializers.go | 1182 - .../aws/aws-sdk-go-v2/service/sso/doc.go | 27 - .../aws-sdk-go-v2/service/sso/endpoints.go | 556 - .../aws-sdk-go-v2/service/sso/generated.json | 36 - .../service/sso/go_module_metadata.go | 6 - .../sso/internal/endpoints/endpoints.go | 566 - .../aws/aws-sdk-go-v2/service/sso/options.go | 232 - .../aws-sdk-go-v2/service/sso/serializers.go | 309 - .../aws-sdk-go-v2/service/sso/types/errors.go | 115 - .../aws-sdk-go-v2/service/sso/types/types.go | 63 - .../aws-sdk-go-v2/service/sso/validators.go | 175 - .../service/ssooidc/CHANGELOG.md | 585 - .../aws-sdk-go-v2/service/ssooidc/LICENSE.txt | 202 - .../service/ssooidc/api_client.go | 943 - .../service/ssooidc/api_op_CreateToken.go | 242 - .../ssooidc/api_op_CreateTokenWithIAM.go | 274 - .../service/ssooidc/api_op_RegisterClient.go | 212 - .../api_op_StartDeviceAuthorization.go | 194 - .../aws/aws-sdk-go-v2/service/ssooidc/auth.go | 331 - .../service/ssooidc/deserializers.go | 2188 - .../aws/aws-sdk-go-v2/service/ssooidc/doc.go | 49 - .../service/ssooidc/endpoints.go | 556 - .../service/ssooidc/generated.json | 36 - .../service/ssooidc/go_module_metadata.go | 6 - .../ssooidc/internal/endpoints/endpoints.go | 566 - .../aws-sdk-go-v2/service/ssooidc/options.go | 232 - .../service/ssooidc/serializers.go | 512 - .../service/ssooidc/types/errors.go | 428 - .../service/ssooidc/types/types.go | 9 - .../service/ssooidc/validators.go | 184 - .../aws-sdk-go-v2/service/sts/CHANGELOG.md | 631 - .../aws/aws-sdk-go-v2/service/sts/LICENSE.txt | 202 - .../aws-sdk-go-v2/service/sts/api_client.go | 1095 - .../service/sts/api_op_AssumeRole.go | 550 - .../service/sts/api_op_AssumeRoleWithSAML.go | 458 - .../sts/api_op_AssumeRoleWithWebIdentity.go | 478 - .../service/sts/api_op_AssumeRoot.go | 223 - .../sts/api_op_DecodeAuthorizationMessage.go | 195 - .../service/sts/api_op_GetAccessKeyInfo.go | 186 - .../service/sts/api_op_GetCallerIdentity.go | 198 - .../service/sts/api_op_GetFederationToken.go | 399 - .../service/sts/api_op_GetSessionToken.go | 245 - .../aws/aws-sdk-go-v2/service/sts/auth.go | 325 - .../service/sts/deserializers.go | 2719 - .../aws/aws-sdk-go-v2/service/sts/doc.go | 13 - .../aws-sdk-go-v2/service/sts/endpoints.go | 1136 - .../aws-sdk-go-v2/service/sts/generated.json | 43 - .../service/sts/go_module_metadata.go | 6 - .../sts/internal/endpoints/endpoints.go | 529 - .../aws/aws-sdk-go-v2/service/sts/options.go | 232 - .../aws-sdk-go-v2/service/sts/serializers.go | 1005 - .../aws-sdk-go-v2/service/sts/types/errors.go | 248 - .../aws-sdk-go-v2/service/sts/types/types.go | 144 - .../aws-sdk-go-v2/service/sts/validators.go | 347 - vendor/github.com/aws/aws-sdk-go/LICENSE.txt | 202 - vendor/github.com/aws/aws-sdk-go/NOTICE.txt | 3 - .../aws/aws-sdk-go/aws/auth/bearer/token.go | 50 - .../aws/aws-sdk-go/aws/awserr/error.go | 164 - .../aws/aws-sdk-go/aws/awserr/types.go | 221 - .../aws/aws-sdk-go/aws/awsutil/copy.go | 108 - .../aws/aws-sdk-go/aws/awsutil/equal.go | 27 - .../aws/aws-sdk-go/aws/awsutil/path_value.go | 221 - .../aws/aws-sdk-go/aws/awsutil/prettify.go | 123 - .../aws-sdk-go/aws/awsutil/string_value.go | 90 - .../aws/aws-sdk-go/aws/client/client.go | 94 - .../aws-sdk-go/aws/client/default_retryer.go | 177 - .../aws/aws-sdk-go/aws/client/logger.go | 206 - .../aws/client/metadata/client_info.go | 15 - .../aws-sdk-go/aws/client/no_op_retryer.go | 28 - .../github.com/aws/aws-sdk-go/aws/config.go | 670 - .../aws/aws-sdk-go/aws/context_1_5.go | 38 - .../aws/aws-sdk-go/aws/context_1_9.go | 12 - .../aws-sdk-go/aws/context_background_1_5.go | 23 - .../aws-sdk-go/aws/context_background_1_7.go | 21 - .../aws/aws-sdk-go/aws/context_sleep.go | 24 - .../aws/aws-sdk-go/aws/convert_types.go | 918 - .../aws/corehandlers/awsinternal.go | 4 - .../aws-sdk-go/aws/corehandlers/handlers.go | 232 - .../aws/corehandlers/param_validator.go | 17 - .../aws-sdk-go/aws/corehandlers/user_agent.go | 47 - .../aws/credentials/chain_provider.go | 100 - .../credentials/context_background_go1.5.go | 23 - .../credentials/context_background_go1.7.go | 21 - .../aws/credentials/context_go1.5.go | 40 - .../aws/credentials/context_go1.9.go | 14 - .../aws-sdk-go/aws/credentials/credentials.go | 383 - .../ec2rolecreds/ec2_role_provider.go | 188 - .../aws/credentials/endpointcreds/provider.go | 255 - .../aws/credentials/env_provider.go | 74 - .../aws-sdk-go/aws/credentials/example.ini | 12 - .../aws/credentials/processcreds/provider.go | 438 - .../shared_credentials_provider.go | 151 - .../aws/credentials/ssocreds/doc.go | 60 - .../aws-sdk-go/aws/credentials/ssocreds/os.go | 10 - .../aws/credentials/ssocreds/os_windows.go | 7 - .../aws/credentials/ssocreds/provider.go | 187 - .../credentials/ssocreds/sso_cached_token.go | 237 - .../credentials/ssocreds/token_provider.go | 148 - .../aws/credentials/static_provider.go | 57 - .../stscreds/assume_role_provider.go | 371 - .../stscreds/web_identity_provider.go | 182 - .../github.com/aws/aws-sdk-go/aws/csm/doc.go | 69 - .../aws/aws-sdk-go/aws/csm/enable.go | 89 - .../aws/aws-sdk-go/aws/csm/metric.go | 109 - .../aws/aws-sdk-go/aws/csm/metric_chan.go | 55 - .../aws-sdk-go/aws/csm/metric_exception.go | 26 - .../aws/aws-sdk-go/aws/csm/reporter.go | 264 - .../aws/aws-sdk-go/aws/defaults/defaults.go | 252 - .../aws-sdk-go/aws/defaults/shared_config.go | 27 - vendor/github.com/aws/aws-sdk-go/aws/doc.go | 56 - .../aws/aws-sdk-go/aws/ec2metadata/api.go | 250 - .../aws/aws-sdk-go/aws/ec2metadata/service.go | 245 - .../aws/ec2metadata/token_provider.go | 99 - .../aws/aws-sdk-go/aws/endpoints/decode.go | 193 - .../aws/aws-sdk-go/aws/endpoints/defaults.go | 48609 ---------------- .../aws/endpoints/dep_service_ids.go | 141 - .../aws/aws-sdk-go/aws/endpoints/doc.go | 65 - .../aws/aws-sdk-go/aws/endpoints/endpoints.go | 708 - .../aws/endpoints/legacy_regions.go | 24 - .../aws/aws-sdk-go/aws/endpoints/v3model.go | 594 - .../aws/endpoints/v3model_codegen.go | 412 - .../github.com/aws/aws-sdk-go/aws/errors.go | 13 - .../aws/aws-sdk-go/aws/jsonvalue.go | 12 - .../github.com/aws/aws-sdk-go/aws/logger.go | 121 - .../aws/request/connection_reset_error.go | 19 - .../aws/aws-sdk-go/aws/request/handlers.go | 346 - .../aws-sdk-go/aws/request/http_request.go | 24 - .../aws-sdk-go/aws/request/offset_reader.go | 65 - .../aws/aws-sdk-go/aws/request/request.go | 722 - .../aws/aws-sdk-go/aws/request/request_1_7.go | 40 - .../aws/aws-sdk-go/aws/request/request_1_8.go | 37 - .../aws-sdk-go/aws/request/request_context.go | 15 - .../aws/request/request_context_1_6.go | 15 - .../aws/request/request_pagination.go | 266 - .../aws/aws-sdk-go/aws/request/retryer.go | 309 - .../aws/request/timeout_read_closer.go | 94 - .../aws/aws-sdk-go/aws/request/validation.go | 286 - .../aws/aws-sdk-go/aws/request/waiter.go | 304 - .../aws/aws-sdk-go/aws/session/credentials.go | 333 - .../aws/session/custom_transport.go | 28 - .../aws/session/custom_transport_go1.12.go | 27 - .../aws/session/custom_transport_go1.5.go | 23 - .../aws/session/custom_transport_go1.6.go | 24 - .../aws/aws-sdk-go/aws/session/doc.go | 367 - .../aws/aws-sdk-go/aws/session/env_config.go | 499 - .../aws/aws-sdk-go/aws/session/session.go | 1005 - .../aws-sdk-go/aws/session/shared_config.go | 856 - .../aws-sdk-go/aws/signer/v4/header_rules.go | 81 - .../aws/aws-sdk-go/aws/signer/v4/options.go | 7 - .../aws/signer/v4/request_context_go1.5.go | 14 - .../aws/signer/v4/request_context_go1.7.go | 14 - .../aws/aws-sdk-go/aws/signer/v4/stream.go | 63 - .../aws/aws-sdk-go/aws/signer/v4/uri_path.go | 25 - .../aws/aws-sdk-go/aws/signer/v4/v4.go | 857 - vendor/github.com/aws/aws-sdk-go/aws/types.go | 264 - vendor/github.com/aws/aws-sdk-go/aws/url.go | 13 - .../github.com/aws/aws-sdk-go/aws/url_1_7.go | 30 - .../github.com/aws/aws-sdk-go/aws/version.go | 8 - .../internal/context/background_go1.5.go | 41 - .../aws/aws-sdk-go/internal/ini/ast.go | 120 - .../aws-sdk-go/internal/ini/comma_token.go | 11 - .../aws-sdk-go/internal/ini/comment_token.go | 35 - .../aws/aws-sdk-go/internal/ini/doc.go | 42 - .../aws-sdk-go/internal/ini/empty_token.go | 4 - .../aws/aws-sdk-go/internal/ini/expression.go | 24 - .../aws/aws-sdk-go/internal/ini/fuzz.go | 18 - .../aws/aws-sdk-go/internal/ini/ini.go | 51 - .../aws/aws-sdk-go/internal/ini/ini_lexer.go | 165 - .../aws/aws-sdk-go/internal/ini/ini_parser.go | 350 - .../aws-sdk-go/internal/ini/literal_tokens.go | 337 - .../aws-sdk-go/internal/ini/newline_token.go | 30 - .../aws-sdk-go/internal/ini/number_helper.go | 152 - .../aws/aws-sdk-go/internal/ini/op_tokens.go | 39 - .../aws-sdk-go/internal/ini/parse_error.go | 43 - .../aws-sdk-go/internal/ini/parse_stack.go | 60 - .../aws/aws-sdk-go/internal/ini/sep_tokens.go | 41 - .../aws/aws-sdk-go/internal/ini/skipper.go | 45 - .../aws/aws-sdk-go/internal/ini/statement.go | 35 - .../aws/aws-sdk-go/internal/ini/value_util.go | 284 - .../aws/aws-sdk-go/internal/ini/visitor.go | 169 - .../aws/aws-sdk-go/internal/ini/walker.go | 25 - .../aws/aws-sdk-go/internal/ini/ws_token.go | 24 - .../aws/aws-sdk-go/internal/sdkio/byte.go | 12 - .../aws/aws-sdk-go/internal/sdkio/io_go1.6.go | 11 - .../aws/aws-sdk-go/internal/sdkio/io_go1.7.go | 13 - .../aws/aws-sdk-go/internal/sdkmath/floor.go | 16 - .../internal/sdkmath/floor_go1.9.go | 57 - .../internal/sdkrand/locked_source.go | 29 - .../aws/aws-sdk-go/internal/sdkrand/read.go | 12 - .../aws-sdk-go/internal/sdkrand/read_1_5.go | 25 - .../aws/aws-sdk-go/internal/sdkuri/path.go | 23 - .../internal/shareddefaults/ecs_container.go | 12 - .../internal/shareddefaults/shared_config.go | 46 - .../shared_config_resolve_home.go | 18 - .../shared_config_resolve_home_go1.12.go | 13 - .../aws-sdk-go/internal/strings/strings.go | 11 - .../internal/sync/singleflight/LICENSE | 27 - .../sync/singleflight/singleflight.go | 120 - .../aws/aws-sdk-go/private/protocol/host.go | 104 - .../private/protocol/host_prefix.go | 54 - .../private/protocol/idempotency.go | 75 - .../private/protocol/json/jsonutil/build.go | 309 - .../protocol/json/jsonutil/unmarshal.go | 317 - .../private/protocol/jsonrpc/jsonrpc.go | 87 - .../protocol/jsonrpc/unmarshal_error.go | 160 - .../aws-sdk-go/private/protocol/jsonvalue.go | 76 - .../aws-sdk-go/private/protocol/payload.go | 81 - .../aws-sdk-go/private/protocol/protocol.go | 49 - .../private/protocol/query/build.go | 36 - .../protocol/query/queryutil/queryutil.go | 276 - .../private/protocol/query/unmarshal.go | 39 - .../private/protocol/query/unmarshal_error.go | 70 - .../aws-sdk-go/private/protocol/rest/build.go | 353 - .../private/protocol/rest/payload.go | 54 - .../private/protocol/rest/unmarshal.go | 276 - .../private/protocol/restjson/restjson.go | 59 - .../protocol/restjson/unmarshal_error.go | 157 - .../private/protocol/restxml/restxml.go | 79 - .../aws-sdk-go/private/protocol/timestamp.go | 134 - .../aws-sdk-go/private/protocol/unmarshal.go | 27 - .../private/protocol/unmarshal_error.go | 65 - .../private/protocol/xml/xmlutil/build.go | 345 - .../private/protocol/xml/xmlutil/sort.go | 32 - .../private/protocol/xml/xmlutil/unmarshal.go | 311 - .../protocol/xml/xmlutil/xml_to_struct.go | 173 - .../aws/aws-sdk-go/service/route53/api.go | 21300 ------- .../service/route53/customizations.go | 42 - .../aws/aws-sdk-go/service/route53/doc.go | 41 - .../aws/aws-sdk-go/service/route53/errors.go | 561 - .../service/route53/route53iface/interface.go | 368 - .../aws/aws-sdk-go/service/route53/service.go | 104 - .../service/route53/unmarshal_error.go | 106 - .../aws/aws-sdk-go/service/route53/waiters.go | 56 - .../aws/aws-sdk-go/service/sso/api.go | 1367 - .../aws/aws-sdk-go/service/sso/doc.go | 45 - .../aws/aws-sdk-go/service/sso/errors.go | 44 - .../aws/aws-sdk-go/service/sso/service.go | 106 - .../service/sso/ssoiface/interface.go | 86 - .../aws/aws-sdk-go/service/ssooidc/api.go | 2406 - .../aws/aws-sdk-go/service/ssooidc/doc.go | 67 - .../aws/aws-sdk-go/service/ssooidc/errors.go | 123 - .../aws/aws-sdk-go/service/ssooidc/service.go | 106 - .../aws/aws-sdk-go/service/sts/api.go | 3553 -- .../aws-sdk-go/service/sts/customizations.go | 11 - .../aws/aws-sdk-go/service/sts/doc.go | 31 - .../aws/aws-sdk-go/service/sts/errors.go | 84 - .../aws/aws-sdk-go/service/sts/service.go | 104 - .../service/sts/stsiface/interface.go | 96 - vendor/github.com/aws/smithy-go/.gitignore | 29 - vendor/github.com/aws/smithy-go/.travis.yml | 28 - vendor/github.com/aws/smithy-go/CHANGELOG.md | 292 - .../aws/smithy-go/CODE_OF_CONDUCT.md | 4 - .../github.com/aws/smithy-go/CONTRIBUTING.md | 90 - vendor/github.com/aws/smithy-go/LICENSE | 175 - vendor/github.com/aws/smithy-go/Makefile | 109 - vendor/github.com/aws/smithy-go/NOTICE | 1 - vendor/github.com/aws/smithy-go/README.md | 93 - vendor/github.com/aws/smithy-go/auth/auth.go | 3 - .../aws/smithy-go/auth/bearer/docs.go | 3 - .../aws/smithy-go/auth/bearer/middleware.go | 104 - .../aws/smithy-go/auth/bearer/token.go | 50 - .../aws/smithy-go/auth/bearer/token_cache.go | 208 - .../github.com/aws/smithy-go/auth/identity.go | 47 - .../github.com/aws/smithy-go/auth/option.go | 25 - .../aws/smithy-go/auth/scheme_id.go | 20 - .../aws/smithy-go/changelog-template.json | 9 - .../aws/smithy-go/context/suppress_expired.go | 81 - vendor/github.com/aws/smithy-go/doc.go | 2 - vendor/github.com/aws/smithy-go/document.go | 10 - .../github.com/aws/smithy-go/document/doc.go | 12 - .../aws/smithy-go/document/document.go | 153 - .../aws/smithy-go/document/errors.go | 75 - .../github.com/aws/smithy-go/encoding/doc.go | 4 - .../aws/smithy-go/encoding/encoding.go | 40 - .../smithy-go/encoding/httpbinding/encode.go | 123 - .../smithy-go/encoding/httpbinding/header.go | 122 - .../encoding/httpbinding/path_replace.go | 108 - .../smithy-go/encoding/httpbinding/query.go | 107 - .../aws/smithy-go/encoding/httpbinding/uri.go | 111 - .../aws/smithy-go/encoding/json/array.go | 35 - .../aws/smithy-go/encoding/json/constants.go | 15 - .../smithy-go/encoding/json/decoder_util.go | 139 - .../aws/smithy-go/encoding/json/encoder.go | 30 - .../aws/smithy-go/encoding/json/escape.go | 198 - .../aws/smithy-go/encoding/json/object.go | 40 - .../aws/smithy-go/encoding/json/value.go | 149 - .../aws/smithy-go/encoding/xml/array.go | 49 - .../aws/smithy-go/encoding/xml/constants.go | 10 - .../aws/smithy-go/encoding/xml/doc.go | 49 - .../aws/smithy-go/encoding/xml/element.go | 91 - .../aws/smithy-go/encoding/xml/encoder.go | 51 - .../aws/smithy-go/encoding/xml/error_utils.go | 51 - .../aws/smithy-go/encoding/xml/escape.go | 137 - .../aws/smithy-go/encoding/xml/map.go | 53 - .../aws/smithy-go/encoding/xml/value.go | 302 - .../aws/smithy-go/encoding/xml/xml_decoder.go | 154 - .../aws/smithy-go/endpoints/endpoint.go | 23 - vendor/github.com/aws/smithy-go/errors.go | 137 - .../aws/smithy-go/go_module_metadata.go | 6 - .../internal/sync/singleflight/LICENSE | 28 - .../internal/sync/singleflight/docs.go | 8 - .../sync/singleflight/singleflight.go | 210 - vendor/github.com/aws/smithy-go/io/byte.go | 12 - vendor/github.com/aws/smithy-go/io/doc.go | 2 - vendor/github.com/aws/smithy-go/io/reader.go | 16 - .../github.com/aws/smithy-go/io/ringbuffer.go | 94 - .../aws/smithy-go/local-mod-replace.sh | 39 - .../aws/smithy-go/logging/logger.go | 82 - .../aws/smithy-go/metrics/metrics.go | 136 - .../github.com/aws/smithy-go/metrics/nop.go | 67 - .../aws/smithy-go/middleware/context.go | 41 - .../aws/smithy-go/middleware/doc.go | 67 - .../aws/smithy-go/middleware/logging.go | 46 - .../aws/smithy-go/middleware/metadata.go | 65 - .../aws/smithy-go/middleware/middleware.go | 71 - .../aws/smithy-go/middleware/ordered_group.go | 268 - .../aws/smithy-go/middleware/stack.go | 209 - .../aws/smithy-go/middleware/stack_values.go | 100 - .../aws/smithy-go/middleware/step_build.go | 211 - .../smithy-go/middleware/step_deserialize.go | 217 - .../aws/smithy-go/middleware/step_finalize.go | 211 - .../smithy-go/middleware/step_initialize.go | 211 - .../smithy-go/middleware/step_serialize.go | 219 - vendor/github.com/aws/smithy-go/modman.toml | 10 - .../private/requestcompression/gzip.go | 30 - .../middleware_capture_request_compression.go | 52 - .../requestcompression/request_compression.go | 103 - vendor/github.com/aws/smithy-go/properties.go | 69 - vendor/github.com/aws/smithy-go/ptr/doc.go | 5 - .../github.com/aws/smithy-go/ptr/from_ptr.go | 601 - .../aws/smithy-go/ptr/gen_scalars.go | 83 - vendor/github.com/aws/smithy-go/ptr/to_ptr.go | 499 - vendor/github.com/aws/smithy-go/rand/doc.go | 3 - vendor/github.com/aws/smithy-go/rand/rand.go | 31 - vendor/github.com/aws/smithy-go/rand/uuid.go | 87 - vendor/github.com/aws/smithy-go/time/time.go | 134 - .../aws/smithy-go/tracing/context.go | 96 - .../github.com/aws/smithy-go/tracing/nop.go | 32 - .../aws/smithy-go/tracing/tracing.go | 95 - .../aws/smithy-go/transport/http/auth.go | 21 - .../smithy-go/transport/http/auth_schemes.go | 45 - .../transport/http/checksum_middleware.go | 70 - .../aws/smithy-go/transport/http/client.go | 161 - .../aws/smithy-go/transport/http/doc.go | 5 - .../smithy-go/transport/http/headerlist.go | 163 - .../aws/smithy-go/transport/http/host.go | 89 - .../transport/http/internal/io/safe.go | 75 - .../smithy-go/transport/http/md5_checksum.go | 25 - .../aws/smithy-go/transport/http/metrics.go | 198 - .../http/middleware_close_response_body.go | 79 - .../http/middleware_content_length.go | 84 - .../http/middleware_header_comment.go | 81 - .../transport/http/middleware_headers.go | 167 - .../transport/http/middleware_http_logging.go | 75 - .../transport/http/middleware_metadata.go | 51 - .../transport/http/middleware_min_proto.go | 79 - .../smithy-go/transport/http/properties.go | 80 - .../aws/smithy-go/transport/http/request.go | 188 - .../aws/smithy-go/transport/http/response.go | 34 - .../aws/smithy-go/transport/http/time.go | 13 - .../aws/smithy-go/transport/http/url.go | 44 - .../smithy-go/transport/http/user_agent.go | 37 - vendor/github.com/aws/smithy-go/validation.go | 140 - vendor/github.com/cihub/seelog/LICENSE.txt | 24 - .../github.com/cihub/seelog/README.markdown | 116 - .../cihub/seelog/archive/archive.go | 198 - .../cihub/seelog/archive/gzip/gzip.go | 64 - .../cihub/seelog/archive/tar/tar.go | 72 - .../cihub/seelog/archive/zip/zip.go | 89 - .../cihub/seelog/behavior_adaptivelogger.go | 129 - .../cihub/seelog/behavior_asynclogger.go | 142 - .../cihub/seelog/behavior_asynclooplogger.go | 69 - .../cihub/seelog/behavior_asynctimerlogger.go | 82 - .../cihub/seelog/behavior_synclogger.go | 75 - vendor/github.com/cihub/seelog/cfg_config.go | 212 - vendor/github.com/cihub/seelog/cfg_errors.go | 61 - .../github.com/cihub/seelog/cfg_logconfig.go | 141 - vendor/github.com/cihub/seelog/cfg_parser.go | 1269 - .../github.com/cihub/seelog/common_closer.go | 25 - .../cihub/seelog/common_constraints.go | 162 - .../github.com/cihub/seelog/common_context.go | 234 - .../cihub/seelog/common_exception.go | 194 - .../github.com/cihub/seelog/common_flusher.go | 31 - .../cihub/seelog/common_loglevel.go | 81 - .../cihub/seelog/dispatch_custom.go | 242 - .../cihub/seelog/dispatch_dispatcher.go | 189 - .../cihub/seelog/dispatch_filterdispatcher.go | 66 - .../cihub/seelog/dispatch_splitdispatcher.go | 47 - vendor/github.com/cihub/seelog/doc.go | 175 - vendor/github.com/cihub/seelog/format.go | 466 - .../cihub/seelog/internals_baseerror.go | 10 - .../cihub/seelog/internals_fsutils.go | 320 - .../cihub/seelog/internals_xmlnode.go | 175 - vendor/github.com/cihub/seelog/log.go | 307 - vendor/github.com/cihub/seelog/logger.go | 370 - .../cihub/seelog/writers_bufferedwriter.go | 161 - .../cihub/seelog/writers_connwriter.go | 144 - .../cihub/seelog/writers_consolewriter.go | 47 - .../cihub/seelog/writers_filewriter.go | 92 - .../cihub/seelog/writers_formattedwriter.go | 62 - .../cihub/seelog/writers_rollingfilewriter.go | 763 - .../cihub/seelog/writers_smtpwriter.go | 214 - .../github.com/coredns/caddy/.gitattributes | 21 - vendor/github.com/coredns/caddy/.gitignore | 22 - vendor/github.com/coredns/caddy/LICENSE.txt | 201 - vendor/github.com/coredns/caddy/README.md | 203 - vendor/github.com/coredns/caddy/assets.go | 48 - vendor/github.com/coredns/caddy/caddy.go | 1043 - .../coredns/caddy/caddyfile/dispenser.go | 260 - .../coredns/caddy/caddyfile/json.go | 198 - .../coredns/caddy/caddyfile/lexer.go | 153 - .../coredns/caddy/caddyfile/parse.go | 490 - vendor/github.com/coredns/caddy/commands.go | 133 - vendor/github.com/coredns/caddy/controller.go | 145 - .../coredns/caddy/onevent/hook/config.go | 20 - .../coredns/caddy/onevent/hook/hook.go | 41 - vendor/github.com/coredns/caddy/onevent/on.go | 71 - vendor/github.com/coredns/caddy/plugins.go | 450 - .../coredns/caddy/rlimit_nonposix.go | 22 - .../github.com/coredns/caddy/rlimit_posix.go | 37 - vendor/github.com/coredns/caddy/sigtrap.go | 103 - .../coredns/caddy/sigtrap_nonposix.go | 19 - .../github.com/coredns/caddy/sigtrap_posix.go | 106 - vendor/github.com/coredns/caddy/upgrade.go | 232 - vendor/github.com/coredns/coredns/LICENSE | 201 - .../coredns/coredns/core/dnsserver/address.go | 86 - .../coredns/coredns/core/dnsserver/config.go | 109 - .../coredns/coredns/core/dnsserver/https.go | 65 - .../coredns/core/dnsserver/onstartup.go | 57 - .../coredns/coredns/core/dnsserver/quic.go | 60 - .../coredns/core/dnsserver/register.go | 368 - .../coredns/coredns/core/dnsserver/server.go | 458 - .../coredns/core/dnsserver/server_grpc.go | 184 - .../coredns/core/dnsserver/server_https.go | 209 - .../coredns/core/dnsserver/server_quic.go | 346 - .../coredns/core/dnsserver/server_tls.go | 103 - .../coredns/coredns/core/dnsserver/view.go | 20 - .../coredns/core/dnsserver/zdirectives.go | 66 - .../coredns/coredns/core/plugin/zplugin.go | 60 - .../coredns/coredns/coremain/run.go | 198 - .../coredns/coredns/coremain/version.go | 8 - vendor/github.com/coredns/coredns/pb/Makefile | 20 - .../github.com/coredns/coredns/pb/dns.pb.go | 147 - .../github.com/coredns/coredns/pb/dns.proto | 12 - .../coredns/coredns/pb/dns_grpc.pb.go | 105 - .../coredns/coredns/plugin/acl/README.md | 110 - .../coredns/coredns/plugin/acl/acl.go | 151 - .../coredns/coredns/plugin/acl/metrics.go | 39 - .../coredns/coredns/plugin/acl/setup.go | 154 - .../coredns/coredns/plugin/any/README.md | 36 - .../coredns/coredns/plugin/any/any.go | 32 - .../coredns/coredns/plugin/any/setup.go | 20 - .../coredns/coredns/plugin/auto/README.md | 82 - .../coredns/coredns/plugin/auto/auto.go | 100 - .../coredns/coredns/plugin/auto/regexp.go | 20 - .../coredns/coredns/plugin/auto/setup.go | 177 - .../coredns/coredns/plugin/auto/walk.go | 107 - .../coredns/coredns/plugin/auto/xfr.go | 31 - .../coredns/coredns/plugin/auto/zone.go | 77 - .../coredns/coredns/plugin/autopath/README.md | 68 - .../coredns/plugin/autopath/autopath.go | 157 - .../coredns/coredns/plugin/autopath/cname.go | 25 - .../coredns/plugin/autopath/metrics.go | 18 - .../coredns/coredns/plugin/autopath/setup.go | 70 - .../coredns/coredns/plugin/azure/README.md | 60 - .../coredns/coredns/plugin/azure/azure.go | 352 - .../coredns/coredns/plugin/azure/setup.go | 144 - .../coredns/coredns/plugin/backend.go | 40 - .../coredns/coredns/plugin/backend_lookup.go | 562 - .../coredns/coredns/plugin/bind/README.md | 113 - .../coredns/coredns/plugin/bind/bind.go | 17 - .../coredns/coredns/plugin/bind/setup.go | 108 - .../coredns/coredns/plugin/bufsize/README.md | 43 - .../coredns/coredns/plugin/bufsize/bufsize.go | 27 - .../coredns/coredns/plugin/bufsize/setup.go | 52 - .../coredns/coredns/plugin/cache/README.md | 144 - .../coredns/coredns/plugin/cache/cache.go | 320 - .../coredns/coredns/plugin/cache/dnssec.go | 24 - .../coredns/coredns/plugin/cache/freq/freq.go | 55 - .../coredns/coredns/plugin/cache/fuzz.go | 12 - .../coredns/coredns/plugin/cache/handler.go | 157 - .../coredns/coredns/plugin/cache/item.go | 107 - .../coredns/coredns/plugin/cache/metrics.go | 67 - .../coredns/coredns/plugin/cache/setup.go | 261 - .../coredns/coredns/plugin/cancel/README.md | 47 - .../coredns/coredns/plugin/cancel/cancel.go | 66 - .../coredns/coredns/plugin/chaos/README.md | 51 - .../coredns/coredns/plugin/chaos/chaos.go | 58 - .../coredns/coredns/plugin/chaos/fuzz.go | 13 - .../coredns/coredns/plugin/chaos/setup.go | 66 - .../coredns/coredns/plugin/chaos/zowners.go | 4 - .../coredns/coredns/plugin/clouddns/README.md | 73 - .../coredns/plugin/clouddns/clouddns.go | 227 - .../coredns/coredns/plugin/clouddns/gcp.go | 40 - .../coredns/coredns/plugin/clouddns/setup.go | 108 - .../coredns/coredns/plugin/debug/README.md | 51 - .../coredns/coredns/plugin/debug/debug.go | 22 - .../coredns/coredns/plugin/debug/pcap.go | 72 - .../coredns/coredns/plugin/dns64/README.md | 106 - .../coredns/coredns/plugin/dns64/dns64.go | 208 - .../coredns/coredns/plugin/dns64/metrics.go | 18 - .../coredns/coredns/plugin/dns64/setup.go | 92 - .../coredns/coredns/plugin/dnssec/README.md | 119 - .../coredns/plugin/dnssec/black_lies.go | 79 - .../coredns/coredns/plugin/dnssec/cache.go | 48 - .../coredns/coredns/plugin/dnssec/dnskey.go | 169 - .../coredns/coredns/plugin/dnssec/dnssec.go | 179 - .../coredns/coredns/plugin/dnssec/handler.go | 50 - .../coredns/coredns/plugin/dnssec/metrics.go | 32 - .../coredns/plugin/dnssec/responsewriter.go | 43 - .../coredns/coredns/plugin/dnssec/rrsig.go | 53 - .../coredns/coredns/plugin/dnssec/setup.go | 159 - .../coredns/coredns/plugin/dnstap/README.md | 175 - .../coredns/coredns/plugin/dnstap/encoder.go | 40 - .../coredns/coredns/plugin/dnstap/handler.go | 87 - .../coredns/coredns/plugin/dnstap/io.go | 145 - .../coredns/coredns/plugin/dnstap/msg/msg.go | 97 - .../coredns/coredns/plugin/dnstap/setup.go | 152 - .../coredns/coredns/plugin/dnstap/writer.go | 44 - .../github.com/coredns/coredns/plugin/done.go | 13 - .../coredns/coredns/plugin/erratic/README.md | 89 - .../coredns/plugin/erratic/autopath.go | 8 - .../coredns/coredns/plugin/erratic/erratic.go | 109 - .../coredns/coredns/plugin/erratic/ready.go | 13 - .../coredns/coredns/plugin/erratic/setup.go | 113 - .../coredns/coredns/plugin/erratic/xfr.go | 57 - .../coredns/coredns/plugin/errors/README.md | 65 - .../coredns/coredns/plugin/errors/errors.go | 104 - .../coredns/coredns/plugin/errors/setup.go | 109 - .../coredns/coredns/plugin/etcd/README.md | 236 - .../coredns/coredns/plugin/etcd/etcd.go | 193 - .../coredns/coredns/plugin/etcd/handler.go | 82 - .../coredns/coredns/plugin/etcd/msg/path.go | 51 - .../coredns/plugin/etcd/msg/service.go | 176 - .../coredns/coredns/plugin/etcd/msg/type.go | 35 - .../coredns/coredns/plugin/etcd/setup.go | 126 - .../coredns/coredns/plugin/etcd/xfr.go | 17 - .../coredns/coredns/plugin/file/README.md | 112 - .../coredns/coredns/plugin/file/closest.go | 23 - .../coredns/coredns/plugin/file/dname.go | 44 - .../coredns/plugin/file/example_org.go | 113 - .../coredns/coredns/plugin/file/file.go | 167 - .../coredns/coredns/plugin/file/fuzz.go | 50 - .../coredns/coredns/plugin/file/lookup.go | 435 - .../coredns/coredns/plugin/file/notify.go | 33 - .../coredns/coredns/plugin/file/reload.go | 69 - .../coredns/plugin/file/rrutil/util.go | 18 - .../coredns/coredns/plugin/file/secondary.go | 198 - .../coredns/coredns/plugin/file/setup.go | 153 - .../coredns/coredns/plugin/file/shutdown.go | 9 - .../coredns/coredns/plugin/file/tree/all.go | 21 - .../coredns/plugin/file/tree/auth_walk.go | 58 - .../coredns/coredns/plugin/file/tree/elem.go | 101 - .../coredns/coredns/plugin/file/tree/glue.go | 44 - .../coredns/coredns/plugin/file/tree/less.go | 59 - .../coredns/coredns/plugin/file/tree/print.go | 62 - .../coredns/coredns/plugin/file/tree/tree.go | 453 - .../coredns/coredns/plugin/file/tree/walk.go | 33 - .../coredns/coredns/plugin/file/wildcard.go | 13 - .../coredns/coredns/plugin/file/xfr.go | 45 - .../coredns/coredns/plugin/file/zone.go | 178 - .../coredns/coredns/plugin/forward/README.md | 292 - .../coredns/coredns/plugin/forward/dnstap.go | 66 - .../coredns/coredns/plugin/forward/forward.go | 275 - .../coredns/coredns/plugin/forward/fuzz.go | 35 - .../coredns/coredns/plugin/forward/metrics.go | 25 - .../coredns/coredns/plugin/forward/policy.go | 69 - .../coredns/coredns/plugin/forward/setup.go | 322 - .../coredns/coredns/plugin/geoip/README.md | 117 - .../coredns/coredns/plugin/geoip/city.go | 58 - .../coredns/coredns/plugin/geoip/geoip.go | 107 - .../coredns/coredns/plugin/geoip/setup.go | 57 - .../coredns/coredns/plugin/grpc/README.md | 143 - .../coredns/coredns/plugin/grpc/grpc.go | 143 - .../coredns/coredns/plugin/grpc/metrics.go | 32 - .../coredns/coredns/plugin/grpc/policy.go | 68 - .../coredns/coredns/plugin/grpc/proxy.go | 82 - .../coredns/coredns/plugin/grpc/setup.go | 153 - .../coredns/coredns/plugin/header/README.md | 63 - .../coredns/coredns/plugin/header/handler.go | 27 - .../coredns/coredns/plugin/header/header.go | 95 - .../coredns/coredns/plugin/header/setup.go | 74 - .../coredns/coredns/plugin/health/README.md | 80 - .../coredns/coredns/plugin/health/health.go | 99 - .../coredns/plugin/health/overloaded.go | 84 - .../coredns/coredns/plugin/health/setup.go | 66 - .../coredns/coredns/plugin/hosts/README.md | 125 - .../coredns/coredns/plugin/hosts/hosts.go | 122 - .../coredns/coredns/plugin/hosts/hostsfile.go | 259 - .../coredns/coredns/plugin/hosts/metrics.go | 25 - .../coredns/coredns/plugin/hosts/setup.go | 158 - .../coredns/plugin/k8s_external/README.md | 132 - .../coredns/plugin/k8s_external/apex.go | 112 - .../coredns/plugin/k8s_external/external.go | 126 - .../coredns/plugin/k8s_external/msg_to_dns.go | 190 - .../coredns/plugin/k8s_external/setup.go | 88 - .../coredns/plugin/k8s_external/transfer.go | 150 - .../coredns/plugin/kubernetes/README.md | 249 - .../coredns/plugin/kubernetes/autopath.go | 62 - .../coredns/plugin/kubernetes/controller.go | 673 - .../coredns/plugin/kubernetes/external.go | 237 - .../coredns/plugin/kubernetes/handler.go | 94 - .../coredns/plugin/kubernetes/kubernetes.go | 537 - .../coredns/plugin/kubernetes/local.go | 37 - .../coredns/plugin/kubernetes/logger.go | 38 - .../coredns/plugin/kubernetes/metadata.go | 69 - .../coredns/plugin/kubernetes/metrics.go | 76 - .../plugin/kubernetes/metrics_test.backup | 203 - .../coredns/plugin/kubernetes/namespace.go | 24 - .../coredns/coredns/plugin/kubernetes/ns.go | 103 - .../plugin/kubernetes/object/endpoint.go | 182 - .../plugin/kubernetes/object/informer.go | 91 - .../plugin/kubernetes/object/metrics.go | 83 - .../plugin/kubernetes/object/namespace.go | 61 - .../plugin/kubernetes/object/object.go | 113 - .../coredns/plugin/kubernetes/object/pod.go | 80 - .../plugin/kubernetes/object/service.go | 120 - .../coredns/plugin/kubernetes/parse.go | 103 - .../coredns/plugin/kubernetes/ready.go | 4 - .../coredns/plugin/kubernetes/reverse.go | 55 - .../coredns/plugin/kubernetes/setup.go | 251 - .../coredns/coredns/plugin/kubernetes/xfr.go | 195 - .../coredns/plugin/loadbalance/README.md | 90 - .../coredns/plugin/loadbalance/handler.go | 25 - .../coredns/plugin/loadbalance/loadbalance.go | 91 - .../coredns/plugin/loadbalance/setup.go | 103 - .../coredns/plugin/loadbalance/weighted.go | 329 - .../coredns/coredns/plugin/local/README.md | 52 - .../coredns/coredns/plugin/local/local.go | 127 - .../coredns/coredns/plugin/local/metrics.go | 18 - .../coredns/coredns/plugin/local/setup.go | 20 - .../coredns/coredns/plugin/log/README.md | 155 - .../coredns/coredns/plugin/log/log.go | 74 - .../coredns/coredns/plugin/log/setup.go | 102 - .../coredns/coredns/plugin/loop/README.md | 93 - .../coredns/coredns/plugin/loop/loop.go | 109 - .../coredns/coredns/plugin/loop/setup.go | 87 - .../coredns/coredns/plugin/metadata/README.md | 49 - .../coredns/plugin/metadata/metadata.go | 44 - .../coredns/plugin/metadata/provider.go | 126 - .../coredns/coredns/plugin/metadata/setup.go | 44 - .../coredns/coredns/plugin/metrics/README.md | 91 - .../coredns/coredns/plugin/metrics/context.go | 37 - .../coredns/coredns/plugin/metrics/handler.go | 57 - .../coredns/coredns/plugin/metrics/metrics.go | 172 - .../coredns/plugin/metrics/recorder.go | 28 - .../coredns/plugin/metrics/registry.go | 28 - .../coredns/coredns/plugin/metrics/setup.go | 105 - .../coredns/plugin/metrics/vars/monitor.go | 36 - .../coredns/plugin/metrics/vars/report.go | 33 - .../coredns/plugin/metrics/vars/vars.go | 92 - .../coredns/coredns/plugin/minimal/README.md | 36 - .../coredns/coredns/plugin/minimal/minimal.go | 55 - .../coredns/coredns/plugin/minimal/setup.go | 24 - .../coredns/plugin/multisocket/README.md | 68 - .../coredns/plugin/multisocket/multisocket.go | 51 - .../coredns/coredns/plugin/normalize.go | 196 - .../coredns/coredns/plugin/nsid/README.md | 57 - .../coredns/coredns/plugin/nsid/nsid.go | 69 - .../coredns/coredns/plugin/nsid/setup.go | 45 - .../coredns/coredns/plugin/pkg/cache/cache.go | 157 - .../coredns/coredns/plugin/pkg/cidr/cidr.go | 83 - .../plugin/pkg/dnstest/multirecorder.go | 41 - .../coredns/plugin/pkg/dnstest/recorder.go | 54 - .../coredns/plugin/pkg/dnstest/server.go | 65 - .../coredns/plugin/pkg/dnsutil/cname.go | 15 - .../coredns/coredns/plugin/pkg/dnsutil/doc.go | 2 - .../coredns/plugin/pkg/dnsutil/join.go | 17 - .../coredns/plugin/pkg/dnsutil/reverse.go | 81 - .../coredns/coredns/plugin/pkg/dnsutil/ttl.go | 53 - .../coredns/plugin/pkg/dnsutil/zone.go | 20 - .../coredns/coredns/plugin/pkg/doh/doh.go | 133 - .../coredns/plugin/pkg/durations/durations.go | 26 - .../coredns/coredns/plugin/pkg/edns/edns.go | 71 - .../plugin/pkg/expression/expression.go | 47 - .../coredns/coredns/plugin/pkg/fall/fall.go | 70 - .../coredns/coredns/plugin/pkg/fuzz/do.go | 31 - .../coredns/plugin/pkg/log/listener.go | 141 - .../coredns/coredns/plugin/pkg/log/log.go | 105 - .../coredns/coredns/plugin/pkg/log/plugin.go | 91 - .../coredns/plugin/pkg/nonwriter/nonwriter.go | 21 - .../coredns/coredns/plugin/pkg/parse/host.go | 125 - .../coredns/coredns/plugin/pkg/parse/parse.go | 38 - .../coredns/plugin/pkg/parse/transport.go | 40 - .../coredns/plugin/pkg/proxy/connect.go | 188 - .../coredns/plugin/pkg/proxy/errors.go | 26 - .../coredns/plugin/pkg/proxy/health.go | 134 - .../coredns/plugin/pkg/proxy/metrics.go | 41 - .../coredns/plugin/pkg/proxy/persistent.go | 158 - .../coredns/coredns/plugin/pkg/proxy/proxy.go | 111 - .../coredns/coredns/plugin/pkg/proxy/type.go | 39 - .../coredns/coredns/plugin/pkg/rand/rand.go | 35 - .../coredns/coredns/plugin/pkg/rcode/rcode.go | 15 - .../coredns/plugin/pkg/replacer/replacer.go | 284 - .../coredns/plugin/pkg/response/classify.go | 61 - .../coredns/plugin/pkg/response/typify.go | 151 - .../pkg/reuseport/listen_no_reuseport.go | 13 - .../plugin/pkg/reuseport/listen_reuseport.go | 36 - .../plugin/pkg/singleflight/singleflight.go | 64 - .../coredns/coredns/plugin/pkg/tls/tls.go | 149 - .../coredns/coredns/plugin/pkg/trace/trace.go | 13 - .../coredns/plugin/pkg/transport/transport.go | 25 - .../coredns/coredns/plugin/pkg/uniq/uniq.go | 46 - .../coredns/coredns/plugin/pkg/up/up.go | 83 - .../coredns/plugin/pkg/upstream/upstream.go | 35 - .../coredns/coredns/plugin/plugin.go | 116 - .../coredns/coredns/plugin/pprof/README.md | 74 - .../coredns/coredns/plugin/pprof/pprof.go | 60 - .../coredns/coredns/plugin/pprof/setup.go | 65 - .../coredns/coredns/plugin/ready/README.md | 58 - .../coredns/coredns/plugin/ready/list.go | 56 - .../coredns/coredns/plugin/ready/readiness.go | 7 - .../coredns/coredns/plugin/ready/ready.go | 81 - .../coredns/coredns/plugin/ready/setup.go | 73 - .../coredns/coredns/plugin/register.go | 11 - .../coredns/coredns/plugin/reload/README.md | 108 - .../coredns/coredns/plugin/reload/metrics.go | 26 - .../coredns/coredns/plugin/reload/reload.go | 128 - .../coredns/coredns/plugin/reload/setup.go | 87 - .../coredns/coredns/plugin/rewrite/README.md | 532 - .../coredns/coredns/plugin/rewrite/class.go | 44 - .../coredns/plugin/rewrite/cname_target.go | 152 - .../coredns/coredns/plugin/rewrite/edns0.go | 447 - .../coredns/coredns/plugin/rewrite/fuzz.go | 20 - .../coredns/coredns/plugin/rewrite/name.go | 449 - .../coredns/coredns/plugin/rewrite/rcode.go | 178 - .../coredns/plugin/rewrite/reverter.go | 147 - .../coredns/coredns/plugin/rewrite/rewrite.go | 149 - .../coredns/coredns/plugin/rewrite/setup.go | 42 - .../coredns/coredns/plugin/rewrite/ttl.go | 205 - .../coredns/coredns/plugin/rewrite/type.go | 45 - .../coredns/coredns/plugin/rewrite/wire.go | 35 - .../coredns/coredns/plugin/root/README.md | 56 - .../coredns/coredns/plugin/root/root.go | 39 - .../coredns/coredns/plugin/route53/README.md | 131 - .../coredns/coredns/plugin/route53/route53.go | 294 - .../coredns/coredns/plugin/route53/setup.go | 144 - .../coredns/plugin/secondary/README.md | 73 - .../coredns/plugin/secondary/secondary.go | 13 - .../coredns/coredns/plugin/secondary/setup.go | 99 - .../coredns/coredns/plugin/sign/README.md | 168 - .../coredns/coredns/plugin/sign/dnssec.go | 20 - .../coredns/coredns/plugin/sign/file.go | 92 - .../coredns/coredns/plugin/sign/keys.go | 119 - .../coredns/coredns/plugin/sign/nsec.go | 36 - .../coredns/coredns/plugin/sign/setup.go | 100 - .../coredns/coredns/plugin/sign/sign.go | 38 - .../coredns/coredns/plugin/sign/signer.go | 206 - .../coredns/coredns/plugin/template/README.md | 298 - .../coredns/plugin/template/metrics.go | 32 - .../coredns/coredns/plugin/template/setup.go | 162 - .../coredns/plugin/template/template.go | 227 - .../coredns/coredns/plugin/test/doc.go | 2 - .../coredns/coredns/plugin/test/file.go | 103 - .../coredns/coredns/plugin/test/helpers.go | 333 - .../coredns/plugin/test/responsewriter.go | 80 - .../coredns/coredns/plugin/test/scrape.go | 262 - .../coredns/coredns/plugin/timeouts/README.md | 89 - .../coredns/plugin/timeouts/timeouts.go | 69 - .../coredns/coredns/plugin/tls/README.md | 73 - .../coredns/coredns/plugin/tls/test_ca.pem | 20 - .../coredns/coredns/plugin/tls/test_cert.pem | 20 - .../coredns/coredns/plugin/tls/test_key.pem | 28 - .../coredns/coredns/plugin/tls/tls.go | 77 - .../coredns/coredns/plugin/trace/README.md | 113 - .../coredns/coredns/plugin/trace/logger.go | 20 - .../coredns/coredns/plugin/trace/setup.go | 163 - .../coredns/coredns/plugin/trace/trace.go | 204 - .../coredns/coredns/plugin/transfer/README.md | 59 - .../coredns/coredns/plugin/transfer/notify.go | 58 - .../coredns/coredns/plugin/transfer/setup.go | 81 - .../coredns/plugin/transfer/transfer.go | 221 - .../coredns/coredns/plugin/tsig/README.md | 118 - .../coredns/coredns/plugin/tsig/setup.go | 168 - .../coredns/coredns/plugin/tsig/tsig.go | 140 - .../coredns/coredns/plugin/view/README.md | 135 - .../coredns/coredns/plugin/view/metadata.go | 16 - .../coredns/coredns/plugin/view/setup.go | 65 - .../coredns/coredns/plugin/view/view.go | 48 - .../coredns/coredns/plugin/whoami/README.md | 58 - .../coredns/coredns/plugin/whoami/fuzz.go | 13 - .../coredns/coredns/plugin/whoami/setup.go | 22 - .../coredns/coredns/plugin/whoami/whoami.go | 60 - .../coredns/coredns/request/edns0.go | 31 - .../coredns/coredns/request/request.go | 363 - .../coredns/coredns/request/writer.go | 21 - vendor/github.com/coreos/go-semver/LICENSE | 202 - vendor/github.com/coreos/go-semver/NOTICE | 5 - .../coreos/go-semver/semver/semver.go | 296 - .../coreos/go-semver/semver/sort.go | 38 - .../github.com/coreos/go-systemd/v22/LICENSE | 191 - .../github.com/coreos/go-systemd/v22/NOTICE | 5 - .../coreos/go-systemd/v22/journal/journal.go | 46 - .../go-systemd/v22/journal/journal_unix.go | 267 - .../go-systemd/v22/journal/journal_windows.go | 43 - .../github.com/dimchansky/utfbom/.gitignore | 37 - .../github.com/dimchansky/utfbom/.travis.yml | 29 - vendor/github.com/dimchansky/utfbom/LICENSE | 201 - vendor/github.com/dimchansky/utfbom/README.md | 66 - vendor/github.com/dimchansky/utfbom/utfbom.go | 192 - .../dnstap/golang-dnstap/.gitignore | 1 - .../github.com/dnstap/golang-dnstap/COPYRIGHT | 14 - .../dnstap/golang-dnstap/Decoder.go | 57 - .../dnstap/golang-dnstap/Encoder.go | 44 - .../dnstap/golang-dnstap/FrameStreamInput.go | 115 - .../dnstap/golang-dnstap/FrameStreamOutput.go | 100 - .../golang-dnstap/FrameStreamSockInput.go | 117 - .../golang-dnstap/FrameStreamSockOutput.go | 124 - .../dnstap/golang-dnstap/JsonFormat.go | 140 - .../github.com/dnstap/golang-dnstap/LICENSE | 202 - .../dnstap/golang-dnstap/QuietTextFormat.go | 181 - vendor/github.com/dnstap/golang-dnstap/README | 15 - .../github.com/dnstap/golang-dnstap/Reader.go | 54 - .../dnstap/golang-dnstap/SocketWriter.go | 217 - .../dnstap/golang-dnstap/TextOutput.go | 116 - .../github.com/dnstap/golang-dnstap/Writer.go | 55 - .../dnstap/golang-dnstap/YamlFormat.go | 118 - .../github.com/dnstap/golang-dnstap/dnstap.go | 56 - .../dnstap/golang-dnstap/dnstap.pb.go | 794 - .../dnstap/golang-dnstap/genproto.sh | 25 - .../github.com/dustin/go-humanize/.travis.yml | 21 - vendor/github.com/dustin/go-humanize/LICENSE | 21 - .../dustin/go-humanize/README.markdown | 124 - vendor/github.com/dustin/go-humanize/big.go | 31 - .../github.com/dustin/go-humanize/bigbytes.go | 189 - vendor/github.com/dustin/go-humanize/bytes.go | 143 - vendor/github.com/dustin/go-humanize/comma.go | 116 - .../github.com/dustin/go-humanize/commaf.go | 41 - vendor/github.com/dustin/go-humanize/ftoa.go | 49 - .../github.com/dustin/go-humanize/humanize.go | 8 - .../github.com/dustin/go-humanize/number.go | 192 - .../github.com/dustin/go-humanize/ordinals.go | 25 - vendor/github.com/dustin/go-humanize/si.go | 127 - vendor/github.com/dustin/go-humanize/times.go | 117 - vendor/github.com/eapache/queue/v2/LICENSE | 21 - vendor/github.com/eapache/queue/v2/queue.go | 102 - .../github.com/expr-lang/expr/.gitattributes | 1 - vendor/github.com/expr-lang/expr/.gitignore | 11 - vendor/github.com/expr-lang/expr/LICENSE | 21 - vendor/github.com/expr-lang/expr/README.md | 181 - vendor/github.com/expr-lang/expr/SECURITY.md | 22 - vendor/github.com/expr-lang/expr/ast/dump.go | 59 - vendor/github.com/expr-lang/expr/ast/find.go | 18 - vendor/github.com/expr-lang/expr/ast/node.go | 243 - vendor/github.com/expr-lang/expr/ast/print.go | 253 - .../github.com/expr-lang/expr/ast/visitor.go | 78 - .../expr-lang/expr/builtin/builtin.go | 1069 - .../expr-lang/expr/builtin/function.go | 23 - .../github.com/expr-lang/expr/builtin/lib.go | 433 - .../expr-lang/expr/builtin/utils.go | 90 - .../expr-lang/expr/builtin/validation.go | 38 - .../expr-lang/expr/checker/checker.go | 1285 - .../github.com/expr-lang/expr/checker/info.go | 129 - .../expr-lang/expr/checker/nature/nature.go | 261 - .../expr-lang/expr/checker/nature/utils.go | 76 - .../expr-lang/expr/checker/types.go | 190 - .../expr-lang/expr/compiler/compiler.go | 1280 - .../github.com/expr-lang/expr/conf/config.go | 101 - vendor/github.com/expr-lang/expr/conf/env.go | 68 - vendor/github.com/expr-lang/expr/expr.go | 260 - .../github.com/expr-lang/expr/file/error.go | 81 - .../expr-lang/expr/file/location.go | 6 - .../github.com/expr-lang/expr/file/source.go | 48 - .../expr-lang/expr/internal/deref/deref.go | 47 - .../expr-lang/expr/optimizer/const_expr.go | 81 - .../expr-lang/expr/optimizer/filter_first.go | 38 - .../expr-lang/expr/optimizer/filter_last.go | 38 - .../expr-lang/expr/optimizer/filter_len.go | 22 - .../expr-lang/expr/optimizer/filter_map.go | 33 - .../expr-lang/expr/optimizer/fold.go | 341 - .../expr-lang/expr/optimizer/in_array.go | 68 - .../expr-lang/expr/optimizer/in_range.go | 43 - .../expr-lang/expr/optimizer/optimizer.go | 79 - .../expr/optimizer/predicate_combination.go | 61 - .../expr-lang/expr/optimizer/sum_array.go | 37 - .../expr-lang/expr/optimizer/sum_map.go | 25 - .../expr-lang/expr/parser/lexer/lexer.go | 230 - .../expr-lang/expr/parser/lexer/state.go | 226 - .../expr-lang/expr/parser/lexer/token.go | 47 - .../expr-lang/expr/parser/lexer/utils.go | 186 - .../expr/parser/operator/operator.go | 69 - .../expr-lang/expr/parser/parser.go | 891 - .../expr-lang/expr/parser/utils/utils.go | 34 - .../expr/patcher/operator_override.go | 147 - .../expr-lang/expr/patcher/with_context.go | 45 - .../expr-lang/expr/patcher/with_timezone.go | 25 - .../github.com/expr-lang/expr/types/types.go | 181 - vendor/github.com/expr-lang/expr/vm/debug.go | 6 - .../github.com/expr-lang/expr/vm/debug_off.go | 6 - .../expr/vm/func_types[generated].go | 370 - .../github.com/expr-lang/expr/vm/opcodes.go | 88 - .../github.com/expr-lang/expr/vm/program.go | 382 - .../expr/vm/runtime/helpers[generated].go | 3718 -- .../expr-lang/expr/vm/runtime/runtime.go | 394 - .../expr-lang/expr/vm/runtime/sort.go | 45 - vendor/github.com/expr-lang/expr/vm/utils.go | 37 - vendor/github.com/expr-lang/expr/vm/vm.go | 617 - .../farsightsec/golang-framestream/.gitignore | 1 - .../farsightsec/golang-framestream/COPYRIGHT | 13 - .../farsightsec/golang-framestream/Control.go | 194 - .../farsightsec/golang-framestream/Decoder.go | 90 - .../farsightsec/golang-framestream/Encoder.go | 70 - .../farsightsec/golang-framestream/LICENSE | 202 - .../farsightsec/golang-framestream/README.md | 13 - .../farsightsec/golang-framestream/Reader.go | 176 - .../farsightsec/golang-framestream/Writer.go | 134 - .../golang-framestream/framestream.go | 32 - .../farsightsec/golang-framestream/timeout.go | 67 - vendor/github.com/flynn/go-shlex/COPYING | 202 - vendor/github.com/flynn/go-shlex/Makefile | 21 - vendor/github.com/flynn/go-shlex/README.md | 2 - vendor/github.com/flynn/go-shlex/shlex.go | 457 - .../gogo/protobuf/gogoproto/Makefile | 37 - .../github.com/gogo/protobuf/gogoproto/doc.go | 169 - .../gogo/protobuf/gogoproto/gogo.pb.go | 874 - .../gogo/protobuf/gogoproto/gogo.pb.golden | 45 - .../gogo/protobuf/gogoproto/gogo.proto | 144 - .../gogo/protobuf/gogoproto/helper.go | 415 - .../github.com/gogo/protobuf/jsonpb/jsonpb.go | 1435 - .../protoc-gen-gogo/descriptor/Makefile | 36 - .../protoc-gen-gogo/descriptor/descriptor.go | 118 - .../descriptor/descriptor.pb.go | 2865 - .../descriptor/descriptor_gostring.gen.go | 752 - .../protoc-gen-gogo/descriptor/helper.go | 390 - vendor/github.com/gogo/protobuf/types/any.go | 140 - .../github.com/gogo/protobuf/types/any.pb.go | 694 - .../github.com/gogo/protobuf/types/api.pb.go | 2134 - vendor/github.com/gogo/protobuf/types/doc.go | 35 - .../gogo/protobuf/types/duration.go | 100 - .../gogo/protobuf/types/duration.pb.go | 517 - .../gogo/protobuf/types/duration_gogo.go | 100 - .../gogo/protobuf/types/empty.pb.go | 462 - .../gogo/protobuf/types/field_mask.pb.go | 738 - .../gogo/protobuf/types/protosize.go | 34 - .../gogo/protobuf/types/source_context.pb.go | 524 - .../gogo/protobuf/types/struct.pb.go | 2271 - .../gogo/protobuf/types/timestamp.go | 130 - .../gogo/protobuf/types/timestamp.pb.go | 539 - .../gogo/protobuf/types/timestamp_gogo.go | 94 - .../github.com/gogo/protobuf/types/type.pb.go | 3355 -- .../gogo/protobuf/types/wrappers.pb.go | 2703 - .../gogo/protobuf/types/wrappers_gogo.go | 300 - .../github.com/golang-jwt/jwt/v4/.gitignore | 4 - vendor/github.com/golang-jwt/jwt/v4/LICENSE | 9 - .../golang-jwt/jwt/v4/MIGRATION_GUIDE.md | 22 - vendor/github.com/golang-jwt/jwt/v4/README.md | 138 - .../github.com/golang-jwt/jwt/v4/SECURITY.md | 19 - .../golang-jwt/jwt/v4/VERSION_HISTORY.md | 135 - vendor/github.com/golang-jwt/jwt/v4/claims.go | 269 - vendor/github.com/golang-jwt/jwt/v4/doc.go | 4 - vendor/github.com/golang-jwt/jwt/v4/ecdsa.go | 142 - .../golang-jwt/jwt/v4/ecdsa_utils.go | 69 - .../github.com/golang-jwt/jwt/v4/ed25519.go | 85 - .../golang-jwt/jwt/v4/ed25519_utils.go | 64 - vendor/github.com/golang-jwt/jwt/v4/errors.go | 112 - vendor/github.com/golang-jwt/jwt/v4/hmac.go | 95 - .../golang-jwt/jwt/v4/map_claims.go | 151 - vendor/github.com/golang-jwt/jwt/v4/none.go | 52 - vendor/github.com/golang-jwt/jwt/v4/parser.go | 206 - .../golang-jwt/jwt/v4/parser_option.go | 29 - vendor/github.com/golang-jwt/jwt/v4/rsa.go | 101 - .../github.com/golang-jwt/jwt/v4/rsa_pss.go | 143 - .../github.com/golang-jwt/jwt/v4/rsa_utils.go | 105 - .../golang-jwt/jwt/v4/signing_method.go | 46 - .../golang-jwt/jwt/v4/staticcheck.conf | 1 - vendor/github.com/golang-jwt/jwt/v4/token.go | 143 - vendor/github.com/golang-jwt/jwt/v4/types.go | 145 - vendor/github.com/google/s2a-go/.gitignore | 6 - .../google/s2a-go/CODE_OF_CONDUCT.md | 93 - .../github.com/google/s2a-go/CONTRIBUTING.md | 29 - vendor/github.com/google/s2a-go/LICENSE.md | 202 - vendor/github.com/google/s2a-go/README.md | 14 - .../google/s2a-go/fallback/s2a_fallback.go | 167 - .../s2a-go/internal/authinfo/authinfo.go | 119 - .../s2a-go/internal/handshaker/handshaker.go | 438 - .../internal/handshaker/service/service.go | 66 - .../proto/common_go_proto/common.pb.go | 388 - .../s2a_context_go_proto/s2a_context.pb.go | 267 - .../internal/proto/s2a_go_proto/s2a.pb.go | 1377 - .../proto/s2a_go_proto/s2a_grpc.pb.go | 174 - .../proto/v2/common_go_proto/common.pb.go | 549 - .../v2/s2a_context_go_proto/s2a_context.pb.go | 249 - .../internal/proto/v2/s2a_go_proto/s2a.pb.go | 2518 - .../proto/v2/s2a_go_proto/s2a_grpc.pb.go | 160 - .../internal/aeadcrypter/aeadcrypter.go | 34 - .../record/internal/aeadcrypter/aesgcm.go | 70 - .../record/internal/aeadcrypter/chachapoly.go | 67 - .../record/internal/aeadcrypter/common.go | 92 - .../record/internal/halfconn/ciphersuite.go | 98 - .../record/internal/halfconn/counter.go | 60 - .../record/internal/halfconn/expander.go | 59 - .../record/internal/halfconn/halfconn.go | 193 - .../google/s2a-go/internal/record/record.go | 729 - .../s2a-go/internal/record/ticketsender.go | 178 - .../internal/tokenmanager/tokenmanager.go | 79 - .../google/s2a-go/internal/v2/README.md | 1 - .../internal/v2/certverifier/certverifier.go | 122 - .../internal/v2/remotesigner/remotesigner.go | 186 - .../google/s2a-go/internal/v2/s2av2.go | 380 - .../v2/tlsconfigstore/tlsconfigstore.go | 403 - .../github.com/google/s2a-go/retry/retry.go | 144 - vendor/github.com/google/s2a-go/s2a.go | 448 - .../github.com/google/s2a-go/s2a_options.go | 272 - vendor/github.com/google/s2a-go/s2a_utils.go | 79 - .../google/s2a-go/stream/s2a_stream.go | 39 - .../enterprise-certificate-proxy/LICENSE | 202 - .../client/client.go | 219 - .../client/util/util.go | 100 - .../gax-go/v2/.release-please-manifest.json | 3 - .../googleapis/gax-go/v2/CHANGES.md | 168 - .../github.com/googleapis/gax-go/v2/LICENSE | 27 - .../googleapis/gax-go/v2/apierror/apierror.go | 363 - .../v2/apierror/internal/proto/README.md | 30 - .../internal/proto/custom_error.pb.go | 256 - .../internal/proto/custom_error.proto | 50 - .../v2/apierror/internal/proto/error.pb.go | 280 - .../v2/apierror/internal/proto/error.proto | 46 - .../googleapis/gax-go/v2/call_option.go | 265 - .../googleapis/gax-go/v2/callctx/callctx.go | 100 - .../googleapis/gax-go/v2/content_type.go | 112 - vendor/github.com/googleapis/gax-go/v2/gax.go | 41 - .../github.com/googleapis/gax-go/v2/header.go | 200 - .../googleapis/gax-go/v2/internal/version.go | 33 - .../v2/internallog/internal/internal.go | 134 - .../gax-go/v2/internallog/internallog.go | 154 - .../github.com/googleapis/gax-go/v2/invoke.go | 114 - .../googleapis/gax-go/v2/proto_json_stream.go | 127 - .../gax-go/v2/release-please-config.json | 10 - .../grpc-ecosystem/grpc-opentracing/LICENSE | 27 - .../grpc-ecosystem/grpc-opentracing/PATENTS | 23 - .../grpc-opentracing/go/otgrpc/README.md | 57 - .../grpc-opentracing/go/otgrpc/client.go | 239 - .../grpc-opentracing/go/otgrpc/errors.go | 69 - .../grpc-opentracing/go/otgrpc/options.go | 76 - .../grpc-opentracing/go/otgrpc/package.go | 5 - .../grpc-opentracing/go/otgrpc/server.go | 141 - .../grpc-opentracing/go/otgrpc/shared.go | 42 - .../go-secure-stdlib/parseutil/LICENSE | 363 - .../go-secure-stdlib/parseutil/parsepath.go | 65 - .../go-secure-stdlib/parseutil/parseutil.go | 502 - .../go-secure-stdlib/strutil/LICENSE | 363 - .../go-secure-stdlib/strutil/strutil.go | 510 - .../hashicorp/go-sockaddr/.gitignore | 26 - .../hashicorp/go-sockaddr/GNUmakefile | 65 - .../github.com/hashicorp/go-sockaddr/LICENSE | 373 - .../hashicorp/go-sockaddr/README.md | 118 - .../github.com/hashicorp/go-sockaddr/doc.go | 5 - .../hashicorp/go-sockaddr/ifaddr.go | 254 - .../hashicorp/go-sockaddr/ifaddrs.go | 1304 - .../hashicorp/go-sockaddr/ifattr.go | 65 - .../hashicorp/go-sockaddr/ipaddr.go | 169 - .../hashicorp/go-sockaddr/ipaddrs.go | 98 - .../hashicorp/go-sockaddr/ipv4addr.go | 516 - .../hashicorp/go-sockaddr/ipv6addr.go | 591 - .../github.com/hashicorp/go-sockaddr/rfc.go | 948 - .../hashicorp/go-sockaddr/route_info.go | 19 - .../go-sockaddr/route_info_android.go | 34 - .../hashicorp/go-sockaddr/route_info_bsd.go | 36 - .../go-sockaddr/route_info_default.go | 10 - .../hashicorp/go-sockaddr/route_info_linux.go | 42 - .../go-sockaddr/route_info_solaris.go | 37 - .../go-sockaddr/route_info_windows.go | 41 - .../hashicorp/go-sockaddr/sockaddr.go | 206 - .../hashicorp/go-sockaddr/sockaddrs.go | 193 - .../hashicorp/go-sockaddr/unixsock.go | 135 - .../github.com/infobloxopen/go-trees/LICENSE | 201 - .../infobloxopen/go-trees/iptree/iptree.go | 432 - .../infobloxopen/go-trees/numtree/node32.go | 452 - .../infobloxopen/go-trees/numtree/node64.go | 392 - .../jmespath/go-jmespath/.gitignore | 4 - .../jmespath/go-jmespath/.travis.yml | 28 - .../github.com/jmespath/go-jmespath/LICENSE | 13 - .../github.com/jmespath/go-jmespath/Makefile | 51 - .../github.com/jmespath/go-jmespath/README.md | 87 - vendor/github.com/jmespath/go-jmespath/api.go | 49 - .../go-jmespath/astnodetype_string.go | 16 - .../jmespath/go-jmespath/functions.go | 842 - .../jmespath/go-jmespath/interpreter.go | 418 - .../github.com/jmespath/go-jmespath/lexer.go | 420 - .../github.com/jmespath/go-jmespath/parser.go | 603 - .../jmespath/go-jmespath/toktype_string.go | 16 - .../github.com/jmespath/go-jmespath/util.go | 185 - .../golang_protobuf_extensions/LICENSE | 201 - .../golang_protobuf_extensions/NOTICE | 1 - .../pbutil/.gitignore | 1 - .../pbutil/Makefile | 7 - .../pbutil/decode.go | 75 - .../golang_protobuf_extensions/pbutil/doc.go | 16 - .../pbutil/encode.go | 46 - .../github.com/mitchellh/go-homedir/LICENSE | 21 - .../github.com/mitchellh/go-homedir/README.md | 14 - .../mitchellh/go-homedir/homedir.go | 167 - .../mitchellh/mapstructure/CHANGELOG.md | 101 - .../github.com/mitchellh/mapstructure/LICENSE | 21 - .../mitchellh/mapstructure/README.md | 46 - .../mitchellh/mapstructure/decode_hooks.go | 283 - .../mitchellh/mapstructure/error.go | 50 - .../mitchellh/mapstructure/mapstructure.go | 1542 - .../go-observer/.gitignore | 14 - .../opentracing-contrib/go-observer/LICENSE | 201 - .../opentracing-contrib/go-observer/README.md | 64 - .../go-observer/observer.go | 39 - .../opentracing/opentracing-go/.gitignore | 1 - .../opentracing/opentracing-go/.travis.yml | 20 - .../opentracing/opentracing-go/CHANGELOG.md | 63 - .../opentracing/opentracing-go/LICENSE | 201 - .../opentracing/opentracing-go/Makefile | 20 - .../opentracing/opentracing-go/README.md | 171 - .../opentracing/opentracing-go/ext.go | 24 - .../opentracing/opentracing-go/ext/field.go | 17 - .../opentracing/opentracing-go/ext/tags.go | 215 - .../opentracing-go/globaltracer.go | 42 - .../opentracing/opentracing-go/gocontext.go | 65 - .../opentracing/opentracing-go/log/field.go | 282 - .../opentracing/opentracing-go/log/util.go | 61 - .../opentracing/opentracing-go/noop.go | 64 - .../opentracing/opentracing-go/propagation.go | 176 - .../opentracing/opentracing-go/span.go | 189 - .../opentracing/opentracing-go/tracer.go | 304 - .../zipkin-go-opentracing/.golangci.yml | 30 - .../zipkin-go-opentracing/.travis.yml | 23 - .../zipkin-go-opentracing/LICENSE | 201 - .../zipkin-go-opentracing/Makefile | 23 - .../zipkin-go-opentracing/README.md | 68 - .../zipkin-go-opentracing/appveyor.yml | 20 - .../zipkin-go-opentracing/circle.yml | 11 - .../zipkin-go-opentracing/context.go | 25 - .../zipkin-go-opentracing/propagation.go | 157 - .../zipkin-go-opentracing/span.go | 159 - .../zipkin-go-opentracing/tracer.go | 194 - .../zipkin-go-opentracing/tracer_options.go | 54 - .../openzipkin/zipkin-go/.gitattributes | 1 - .../openzipkin/zipkin-go/.gitignore | 26 - .../openzipkin/zipkin-go/.golangci.yml | 33 - .../github.com/openzipkin/zipkin-go/LICENSE | 201 - .../github.com/openzipkin/zipkin-go/Makefile | 44 - .../github.com/openzipkin/zipkin-go/README.md | 128 - .../openzipkin/zipkin-go/SECURITY.md | 13 - .../openzipkin/zipkin-go/context.go | 63 - vendor/github.com/openzipkin/zipkin-go/doc.go | 20 - .../openzipkin/zipkin-go/endpoint.go | 81 - .../zipkin-go/idgenerator/idgenerator.go | 130 - .../openzipkin/zipkin-go/model/annotation.go | 60 - .../openzipkin/zipkin-go/model/doc.go | 23 - .../openzipkin/zipkin-go/model/endpoint.go | 50 - .../openzipkin/zipkin-go/model/kind.go | 27 - .../openzipkin/zipkin-go/model/span.go | 161 - .../openzipkin/zipkin-go/model/span_id.go | 44 - .../openzipkin/zipkin-go/model/traceid.go | 75 - .../github.com/openzipkin/zipkin-go/noop.go | 48 - .../zipkin-go/propagation/b3/doc.go | 19 - .../zipkin-go/propagation/b3/grpc.go | 87 - .../zipkin-go/propagation/b3/http.go | 129 - .../zipkin-go/propagation/b3/map.go | 101 - .../zipkin-go/propagation/b3/shared.go | 44 - .../zipkin-go/propagation/b3/spancontext.go | 203 - .../zipkin-go/propagation/propagation.go | 30 - .../zipkin-go/reporter/http/http.go | 275 - .../openzipkin/zipkin-go/reporter/reporter.go | 41 - .../zipkin-go/reporter/serializer.go | 42 - .../github.com/openzipkin/zipkin-go/sample.go | 127 - .../github.com/openzipkin/zipkin-go/span.go | 58 - .../zipkin-go/span_implementation.go | 107 - .../openzipkin/zipkin-go/span_options.go | 88 - .../github.com/openzipkin/zipkin-go/tags.go | 37 - .../github.com/openzipkin/zipkin-go/tracer.go | 200 - .../openzipkin/zipkin-go/tracer_options.go | 138 - .../oschwald/geoip2-golang/.gitignore | 3 - .../oschwald/geoip2-golang/.gitmodules | 3 - .../oschwald/geoip2-golang/.golangci.toml | 192 - .../github.com/oschwald/geoip2-golang/LICENSE | 15 - .../oschwald/geoip2-golang/README.md | 93 - .../oschwald/geoip2-golang/reader.go | 420 - .../oschwald/maxminddb-golang/.gitignore | 4 - .../oschwald/maxminddb-golang/.gitmodules | 3 - .../oschwald/maxminddb-golang/.golangci.toml | 192 - .../oschwald/maxminddb-golang/LICENSE | 15 - .../oschwald/maxminddb-golang/README.md | 36 - .../oschwald/maxminddb-golang/decoder.go | 900 - .../oschwald/maxminddb-golang/deserializer.go | 31 - .../oschwald/maxminddb-golang/errors.go | 46 - .../oschwald/maxminddb-golang/mmap_unix.go | 16 - .../oschwald/maxminddb-golang/mmap_windows.go | 86 - .../oschwald/maxminddb-golang/node.go | 58 - .../oschwald/maxminddb-golang/reader.go | 310 - .../maxminddb-golang/reader_memory.go | 26 - .../oschwald/maxminddb-golang/reader_mmap.go | 64 - .../oschwald/maxminddb-golang/set_zero_120.go | 10 - .../maxminddb-golang/set_zero_pre120.go | 10 - .../oschwald/maxminddb-golang/traverse.go | 211 - .../oschwald/maxminddb-golang/verifier.go | 201 - .../outcaste-io/ristretto/.deepsource.toml | 17 - .../github.com/outcaste-io/ristretto/.mailmap | 1 - .../outcaste-io/ristretto/CHANGELOG.md | 172 - .../github.com/outcaste-io/ristretto/LICENSE | 176 - .../outcaste-io/ristretto/README.md | 237 - .../github.com/outcaste-io/ristretto/cache.go | 520 - .../outcaste-io/ristretto/metrics.go | 249 - .../outcaste-io/ristretto/policy.go | 388 - .../github.com/outcaste-io/ristretto/ring.go | 91 - .../outcaste-io/ristretto/sketch.go | 155 - .../github.com/outcaste-io/ristretto/store.go | 225 - .../github.com/outcaste-io/ristretto/test.sh | 20 - .../github.com/outcaste-io/ristretto/ttl.go | 155 - .../outcaste-io/ristretto/z/LICENSE | 64 - .../outcaste-io/ristretto/z/README.md | 129 - .../outcaste-io/ristretto/z/allocator.go | 403 - .../outcaste-io/ristretto/z/bbloom.go | 209 - .../outcaste-io/ristretto/z/btree.go | 710 - .../outcaste-io/ristretto/z/buffer.go | 543 - .../outcaste-io/ristretto/z/calloc.go | 42 - .../outcaste-io/ristretto/z/calloc_32bit.go | 14 - .../outcaste-io/ristretto/z/calloc_64bit.go | 14 - .../ristretto/z/calloc_jemalloc.go | 173 - .../ristretto/z/calloc_nojemalloc.go | 37 - .../outcaste-io/ristretto/z/file.go | 217 - .../outcaste-io/ristretto/z/file_default.go | 39 - .../outcaste-io/ristretto/z/file_linux.go | 37 - .../outcaste-io/ristretto/z/flags.go | 324 - .../outcaste-io/ristretto/z/histogram.go | 205 - .../outcaste-io/ristretto/z/mmap.go | 44 - .../outcaste-io/ristretto/z/mmap_darwin.go | 59 - .../outcaste-io/ristretto/z/mmap_linux.go | 97 - .../outcaste-io/ristretto/z/mmap_plan9.go | 44 - .../outcaste-io/ristretto/z/mmap_unix.go | 56 - .../outcaste-io/ristretto/z/mmap_wasip1.go | 40 - .../outcaste-io/ristretto/z/mmap_windows.go | 95 - .../outcaste-io/ristretto/z/rtutil.go | 75 - .../outcaste-io/ristretto/z/rtutil.s | 0 .../outcaste-io/ristretto/z/simd/baseline.go | 127 - .../outcaste-io/ristretto/z/simd/search.go | 51 - .../ristretto/z/simd/search_amd64.s | 60 - .../ristretto/z/simd/stub_search_amd64.go | 6 - .../github.com/outcaste-io/ristretto/z/z.go | 163 - vendor/github.com/philhofer/fwd/LICENSE.md | 7 - vendor/github.com/philhofer/fwd/README.md | 368 - vendor/github.com/philhofer/fwd/reader.go | 383 - vendor/github.com/philhofer/fwd/writer.go | 236 - .../philhofer/fwd/writer_appengine.go | 6 - .../github.com/philhofer/fwd/writer_tinygo.go | 13 - .../github.com/philhofer/fwd/writer_unsafe.go | 20 - .../github.com/ryanuber/go-glob/.travis.yml | 5 - vendor/github.com/ryanuber/go-glob/LICENSE | 21 - vendor/github.com/ryanuber/go-glob/README.md | 29 - vendor/github.com/ryanuber/go-glob/glob.go | 56 - .../go-securesystemslib/LICENSE | 21 - .../cjson/canonicaljson.go | 151 - vendor/github.com/shirou/gopsutil/v3/LICENSE | 61 - .../shirou/gopsutil/v3/common/env.go | 23 - .../github.com/shirou/gopsutil/v3/cpu/cpu.go | 200 - .../shirou/gopsutil/v3/cpu/cpu_aix.go | 16 - .../shirou/gopsutil/v3/cpu/cpu_aix_cgo.go | 66 - .../shirou/gopsutil/v3/cpu/cpu_aix_nocgo.go | 92 - .../shirou/gopsutil/v3/cpu/cpu_darwin.go | 117 - .../shirou/gopsutil/v3/cpu/cpu_darwin_cgo.go | 111 - .../gopsutil/v3/cpu/cpu_darwin_nocgo.go | 14 - .../shirou/gopsutil/v3/cpu/cpu_dragonfly.go | 156 - .../gopsutil/v3/cpu/cpu_dragonfly_amd64.go | 9 - .../shirou/gopsutil/v3/cpu/cpu_fallback.go | 31 - .../shirou/gopsutil/v3/cpu/cpu_freebsd.go | 168 - .../shirou/gopsutil/v3/cpu/cpu_freebsd_386.go | 9 - .../gopsutil/v3/cpu/cpu_freebsd_amd64.go | 9 - .../shirou/gopsutil/v3/cpu/cpu_freebsd_arm.go | 9 - .../gopsutil/v3/cpu/cpu_freebsd_arm64.go | 9 - .../shirou/gopsutil/v3/cpu/cpu_linux.go | 479 - .../shirou/gopsutil/v3/cpu/cpu_netbsd.go | 119 - .../gopsutil/v3/cpu/cpu_netbsd_amd64.go | 9 - .../gopsutil/v3/cpu/cpu_netbsd_arm64.go | 9 - .../shirou/gopsutil/v3/cpu/cpu_openbsd.go | 137 - .../shirou/gopsutil/v3/cpu/cpu_openbsd_386.go | 10 - .../gopsutil/v3/cpu/cpu_openbsd_amd64.go | 10 - .../shirou/gopsutil/v3/cpu/cpu_openbsd_arm.go | 10 - .../gopsutil/v3/cpu/cpu_openbsd_arm64.go | 10 - .../gopsutil/v3/cpu/cpu_openbsd_riscv64.go | 10 - .../shirou/gopsutil/v3/cpu/cpu_plan9.go | 50 - .../shirou/gopsutil/v3/cpu/cpu_solaris.go | 269 - .../shirou/gopsutil/v3/cpu/cpu_windows.go | 229 - .../gopsutil/v3/internal/common/binary.go | 637 - .../gopsutil/v3/internal/common/common.go | 464 - .../v3/internal/common/common_darwin.go | 66 - .../v3/internal/common/common_freebsd.go | 82 - .../v3/internal/common/common_linux.go | 353 - .../v3/internal/common/common_netbsd.go | 66 - .../v3/internal/common/common_openbsd.go | 66 - .../v3/internal/common/common_unix.go | 62 - .../v3/internal/common/common_windows.go | 304 - .../gopsutil/v3/internal/common/endian.go | 10 - .../gopsutil/v3/internal/common/sleep.go | 21 - .../gopsutil/v3/internal/common/warnings.go | 30 - .../github.com/shirou/gopsutil/v3/mem/mem.go | 120 - .../shirou/gopsutil/v3/mem/mem_aix.go | 16 - .../shirou/gopsutil/v3/mem/mem_aix_cgo.go | 51 - .../shirou/gopsutil/v3/mem/mem_aix_nocgo.go | 78 - .../shirou/gopsutil/v3/mem/mem_bsd.go | 87 - .../shirou/gopsutil/v3/mem/mem_darwin.go | 72 - .../shirou/gopsutil/v3/mem/mem_darwin_cgo.go | 58 - .../gopsutil/v3/mem/mem_darwin_nocgo.go | 89 - .../shirou/gopsutil/v3/mem/mem_fallback.go | 34 - .../shirou/gopsutil/v3/mem/mem_freebsd.go | 167 - .../shirou/gopsutil/v3/mem/mem_linux.go | 532 - .../shirou/gopsutil/v3/mem/mem_netbsd.go | 87 - .../shirou/gopsutil/v3/mem/mem_openbsd.go | 100 - .../shirou/gopsutil/v3/mem/mem_openbsd_386.go | 38 - .../gopsutil/v3/mem/mem_openbsd_amd64.go | 32 - .../shirou/gopsutil/v3/mem/mem_openbsd_arm.go | 38 - .../gopsutil/v3/mem/mem_openbsd_arm64.go | 38 - .../gopsutil/v3/mem/mem_openbsd_riscv64.go | 38 - .../shirou/gopsutil/v3/mem/mem_plan9.go | 68 - .../shirou/gopsutil/v3/mem/mem_solaris.go | 213 - .../shirou/gopsutil/v3/mem/mem_windows.go | 166 - .../github.com/shirou/gopsutil/v3/net/net.go | 273 - .../shirou/gopsutil/v3/net/net_aix.go | 330 - .../shirou/gopsutil/v3/net/net_aix_cgo.go | 36 - .../shirou/gopsutil/v3/net/net_aix_nocgo.go | 95 - .../shirou/gopsutil/v3/net/net_darwin.go | 291 - .../shirou/gopsutil/v3/net/net_fallback.go | 93 - .../shirou/gopsutil/v3/net/net_freebsd.go | 128 - .../shirou/gopsutil/v3/net/net_linux.go | 910 - .../shirou/gopsutil/v3/net/net_linux_111.go | 12 - .../shirou/gopsutil/v3/net/net_linux_116.go | 12 - .../shirou/gopsutil/v3/net/net_openbsd.go | 335 - .../shirou/gopsutil/v3/net/net_solaris.go | 144 - .../shirou/gopsutil/v3/net/net_unix.go | 224 - .../shirou/gopsutil/v3/net/net_windows.go | 779 - .../shirou/gopsutil/v3/process/process.go | 627 - .../shirou/gopsutil/v3/process/process_bsd.go | 76 - .../gopsutil/v3/process/process_darwin.go | 325 - .../v3/process/process_darwin_amd64.go | 236 - .../v3/process/process_darwin_arm64.go | 213 - .../gopsutil/v3/process/process_darwin_cgo.go | 222 - .../v3/process/process_darwin_nocgo.go | 127 - .../gopsutil/v3/process/process_fallback.go | 203 - .../gopsutil/v3/process/process_freebsd.go | 342 - .../v3/process/process_freebsd_386.go | 192 - .../v3/process/process_freebsd_amd64.go | 192 - .../v3/process/process_freebsd_arm.go | 192 - .../v3/process/process_freebsd_arm64.go | 202 - .../gopsutil/v3/process/process_linux.go | 1187 - .../gopsutil/v3/process/process_openbsd.go | 387 - .../v3/process/process_openbsd_386.go | 202 - .../v3/process/process_openbsd_amd64.go | 200 - .../v3/process/process_openbsd_arm.go | 202 - .../v3/process/process_openbsd_arm64.go | 203 - .../v3/process/process_openbsd_riscv64.go | 204 - .../gopsutil/v3/process/process_plan9.go | 203 - .../gopsutil/v3/process/process_posix.go | 185 - .../gopsutil/v3/process/process_solaris.go | 303 - .../gopsutil/v3/process/process_windows.go | 1165 - .../v3/process/process_windows_32bit.go | 108 - .../v3/process/process_windows_64bit.go | 79 - .../shoenig/go-m1cpu/.golangci.yaml | 12 - vendor/github.com/shoenig/go-m1cpu/LICENSE | 363 - vendor/github.com/shoenig/go-m1cpu/Makefile | 12 - vendor/github.com/shoenig/go-m1cpu/README.md | 66 - vendor/github.com/shoenig/go-m1cpu/cpu.go | 213 - .../shoenig/go-m1cpu/incompatible.go | 53 - vendor/github.com/tinylib/msgp/LICENSE | 8 - .../tinylib/msgp/msgp/advise_linux.go | 25 - .../tinylib/msgp/msgp/advise_other.go | 18 - .../github.com/tinylib/msgp/msgp/circular.go | 39 - vendor/github.com/tinylib/msgp/msgp/defs.go | 151 - vendor/github.com/tinylib/msgp/msgp/edit.go | 242 - vendor/github.com/tinylib/msgp/msgp/elsize.go | 128 - .../tinylib/msgp/msgp/elsize_default.go | 21 - .../tinylib/msgp/msgp/elsize_tinygo.go | 13 - vendor/github.com/tinylib/msgp/msgp/errors.go | 368 - .../tinylib/msgp/msgp/errors_default.go | 25 - .../tinylib/msgp/msgp/errors_tinygo.go | 42 - .../github.com/tinylib/msgp/msgp/extension.go | 547 - vendor/github.com/tinylib/msgp/msgp/file.go | 93 - .../github.com/tinylib/msgp/msgp/file_port.go | 48 - .../github.com/tinylib/msgp/msgp/integers.go | 199 - vendor/github.com/tinylib/msgp/msgp/json.go | 582 - .../tinylib/msgp/msgp/json_bytes.go | 347 - vendor/github.com/tinylib/msgp/msgp/number.go | 266 - vendor/github.com/tinylib/msgp/msgp/purego.go | 16 - vendor/github.com/tinylib/msgp/msgp/read.go | 1411 - .../tinylib/msgp/msgp/read_bytes.go | 1328 - vendor/github.com/tinylib/msgp/msgp/size.go | 39 - vendor/github.com/tinylib/msgp/msgp/unsafe.go | 37 - vendor/github.com/tinylib/msgp/msgp/write.go | 813 - .../tinylib/msgp/msgp/write_bytes.go | 454 - vendor/go.etcd.io/etcd/api/v3/LICENSE | 202 - .../go.etcd.io/etcd/api/v3/authpb/auth.pb.go | 1158 - .../go.etcd.io/etcd/api/v3/authpb/auth.proto | 42 - .../etcd/api/v3/etcdserverpb/etcdserver.pb.go | 1002 - .../etcd/api/v3/etcdserverpb/etcdserver.proto | 34 - .../api/v3/etcdserverpb/raft_internal.pb.go | 2673 - .../api/v3/etcdserverpb/raft_internal.proto | 81 - .../v3/etcdserverpb/raft_internal_stringer.go | 183 - .../etcd/api/v3/etcdserverpb/rpc.pb.go | 25862 -------- .../etcd/api/v3/etcdserverpb/rpc.proto | 1199 - .../etcd/api/v3/membershippb/membership.pb.go | 1454 - .../etcd/api/v3/membershippb/membership.proto | 43 - vendor/go.etcd.io/etcd/api/v3/mvccpb/kv.pb.go | 798 - vendor/go.etcd.io/etcd/api/v3/mvccpb/kv.proto | 49 - .../etcd/api/v3/v3rpc/rpctypes/doc.go | 16 - .../etcd/api/v3/v3rpc/rpctypes/error.go | 267 - .../etcd/api/v3/v3rpc/rpctypes/md.go | 22 - .../api/v3/v3rpc/rpctypes/metadatafields.go | 20 - .../go.etcd.io/etcd/api/v3/version/version.go | 56 - vendor/go.etcd.io/etcd/client/pkg/v3/LICENSE | 202 - .../etcd/client/pkg/v3/logutil/doc.go | 16 - .../etcd/client/pkg/v3/logutil/log_level.go | 30 - .../etcd/client/pkg/v3/logutil/zap.go | 108 - .../etcd/client/pkg/v3/logutil/zap_journal.go | 93 - .../etcd/client/pkg/v3/systemd/doc.go | 16 - .../etcd/client/pkg/v3/systemd/journal.go | 29 - .../etcd/client/pkg/v3/types/doc.go | 17 - .../go.etcd.io/etcd/client/pkg/v3/types/id.go | 39 - .../etcd/client/pkg/v3/types/set.go | 195 - .../etcd/client/pkg/v3/types/slice.go | 22 - .../etcd/client/pkg/v3/types/urls.go | 87 - .../etcd/client/pkg/v3/types/urlsmap.go | 107 - vendor/go.etcd.io/etcd/client/v3/LICENSE | 202 - vendor/go.etcd.io/etcd/client/v3/README.md | 85 - vendor/go.etcd.io/etcd/client/v3/auth.go | 236 - vendor/go.etcd.io/etcd/client/v3/client.go | 629 - vendor/go.etcd.io/etcd/client/v3/cluster.go | 141 - .../go.etcd.io/etcd/client/v3/compact_op.go | 51 - vendor/go.etcd.io/etcd/client/v3/compare.go | 140 - vendor/go.etcd.io/etcd/client/v3/config.go | 101 - .../etcd/client/v3/credentials/credentials.go | 131 - vendor/go.etcd.io/etcd/client/v3/ctx.go | 50 - vendor/go.etcd.io/etcd/client/v3/doc.go | 106 - .../client/v3/internal/endpoint/endpoint.go | 134 - .../client/v3/internal/resolver/resolver.go | 74 - vendor/go.etcd.io/etcd/client/v3/kv.go | 177 - vendor/go.etcd.io/etcd/client/v3/lease.go | 617 - vendor/go.etcd.io/etcd/client/v3/logger.go | 59 - .../go.etcd.io/etcd/client/v3/maintenance.go | 255 - vendor/go.etcd.io/etcd/client/v3/op.go | 583 - vendor/go.etcd.io/etcd/client/v3/options.go | 69 - vendor/go.etcd.io/etcd/client/v3/retry.go | 306 - .../etcd/client/v3/retry_interceptor.go | 445 - vendor/go.etcd.io/etcd/client/v3/sort.go | 37 - vendor/go.etcd.io/etcd/client/v3/txn.go | 150 - vendor/go.etcd.io/etcd/client/v3/utils.go | 31 - vendor/go.etcd.io/etcd/client/v3/watch.go | 1042 - .../collector/component/LICENSE | 202 - .../collector/component/Makefile | 1 - .../collector/component/build_info.go | 26 - .../collector/component/component.go | 198 - .../collector/component/config.go | 166 - .../collector/component/doc.go | 8 - .../collector/component/host.go | 30 - .../collector/component/identifiable.go | 103 - .../collector/component/status.go | 190 - .../collector/component/telemetry.go | 43 - .../collector/config/configtelemetry/LICENSE | 202 - .../collector/config/configtelemetry/Makefile | 1 - .../config/configtelemetry/configtelemetry.go | 73 - .../collector/config/configtelemetry/doc.go | 7 - .../collector/pdata/LICENSE | 202 - .../collector/pdata/internal/.gitignore | 2 - .../collector/pdata/internal/data/bytesid.go | 45 - .../collector/logs/v1/logs_service.pb.go | 844 - .../metrics/v1/metrics_service.pb.go | 844 - .../v1experimental/profiles_service.pb.go | 845 - .../collector/trace/v1/trace_service.pb.go | 843 - .../data/protogen/common/v1/common.pb.go | 1721 - .../internal/data/protogen/logs/v1/logs.pb.go | 1770 - .../data/protogen/metrics/v1/metrics.pb.go | 6625 --- .../v1experimental/pprofextended.pb.go | 4919 -- .../profiles/v1experimental/profiles.pb.go | 1482 - .../data/protogen/resource/v1/resource.pb.go | 381 - .../data/protogen/trace/v1/trace.pb.go | 3043 - .../collector/pdata/internal/data/spanid.go | 79 - .../collector/pdata/internal/data/traceid.go | 79 - .../internal/generated_wrapper_byteslice.go | 34 - .../generated_wrapper_float64slice.go | 34 - .../generated_wrapper_instrumentationscope.go | 43 - .../internal/generated_wrapper_int64slice.go | 34 - .../internal/generated_wrapper_resource.go | 41 - .../internal/generated_wrapper_stringslice.go | 34 - .../internal/generated_wrapper_uint64slice.go | 34 - .../pdata/internal/json/attribute.go | 110 - .../collector/pdata/internal/json/enum.go | 29 - .../collector/pdata/internal/json/json.go | 22 - .../collector/pdata/internal/json/number.go | 103 - .../collector/pdata/internal/json/resource.go | 27 - .../collector/pdata/internal/json/scope.go | 31 - .../collector/pdata/internal/otlp/logs.go | 19 - .../collector/pdata/internal/otlp/metrics.go | 19 - .../collector/pdata/internal/otlp/traces.go | 19 - .../collector/pdata/internal/state.go | 22 - .../collector/pdata/internal/wrapper_logs.go | 46 - .../collector/pdata/internal/wrapper_map.go | 38 - .../pdata/internal/wrapper_metrics.go | 46 - .../pdata/internal/wrapper_profiles.go | 46 - .../collector/pdata/internal/wrapper_slice.go | 41 - .../pdata/internal/wrapper_traces.go | 46 - .../pdata/internal/wrapper_tracestate.go | 33 - .../collector/pdata/internal/wrapper_value.go | 37 - .../pdata/pcommon/generated_byteslice.go | 108 - .../pdata/pcommon/generated_float64slice.go | 108 - .../pcommon/generated_instrumentationscope.go | 98 - .../pdata/pcommon/generated_int64slice.go | 108 - .../pdata/pcommon/generated_resource.go | 74 - .../pdata/pcommon/generated_stringslice.go | 108 - .../pdata/pcommon/generated_uint64slice.go | 108 - .../collector/pdata/pcommon/map.go | 283 - .../collector/pdata/pcommon/slice.go | 166 - .../collector/pdata/pcommon/spanid.go | 36 - .../collector/pdata/pcommon/timestamp.go | 27 - .../collector/pdata/pcommon/trace_state.go | 53 - .../collector/pdata/pcommon/traceid.go | 37 - .../collector/pdata/pcommon/value.go | 483 - .../collector/pdata/pprofile/LICENSE | 202 - .../collector/pdata/pprofile/Makefile | 1 - .../pdata/pprofile/generated_attributeunit.go | 75 - .../pprofile/generated_attributeunitslice.go | 136 - .../pdata/pprofile/generated_function.go | 111 - .../pdata/pprofile/generated_functionslice.go | 136 - .../pdata/pprofile/generated_label.go | 99 - .../pdata/pprofile/generated_labelslice.go | 136 - .../pdata/pprofile/generated_line.go | 87 - .../pdata/pprofile/generated_lineslice.go | 136 - .../pdata/pprofile/generated_link.go | 77 - .../pdata/pprofile/generated_linkslice.go | 136 - .../pdata/pprofile/generated_location.go | 124 - .../pdata/pprofile/generated_locationslice.go | 136 - .../pdata/pprofile/generated_mapping.go | 190 - .../pdata/pprofile/generated_mappingslice.go | 136 - .../pdata/pprofile/generated_profile.go | 196 - .../pprofile/generated_profilecontainer.go | 106 - .../generated_profilescontainersslice.go | 152 - .../pprofile/generated_resourceprofiles.go | 76 - .../generated_resourceprofilesslice.go | 152 - .../pdata/pprofile/generated_sample.go | 130 - .../pdata/pprofile/generated_sampleslice.go | 136 - .../pdata/pprofile/generated_scopeprofiles.go | 76 - .../pprofile/generated_scopeprofilesslice.go | 152 - .../pdata/pprofile/generated_valuetype.go | 87 - .../pprofile/generated_valuetypeslice.go | 136 - .../collector/pdata/pprofile/profiles.go | 51 - .../collector/pdata/ptrace/encoding.go | 31 - .../pdata/ptrace/generated_resourcespans.go | 76 - .../ptrace/generated_resourcespansslice.go | 152 - .../pdata/ptrace/generated_scopespans.go | 76 - .../pdata/ptrace/generated_scopespansslice.go | 152 - .../collector/pdata/ptrace/generated_span.go | 216 - .../pdata/ptrace/generated_spanevent.go | 95 - .../pdata/ptrace/generated_spaneventslice.go | 152 - .../pdata/ptrace/generated_spanlink.go | 115 - .../pdata/ptrace/generated_spanlinkslice.go | 152 - .../pdata/ptrace/generated_spanslice.go | 152 - .../pdata/ptrace/generated_status.go | 76 - .../collector/pdata/ptrace/json.go | 213 - .../collector/pdata/ptrace/pb.go | 31 - .../collector/pdata/ptrace/span_kind.go | 54 - .../collector/pdata/ptrace/status_code.go | 31 - .../collector/pdata/ptrace/traces.go | 65 - .../collector/semconv/LICENSE | 202 - .../semconv/v1.17.0/generated_event.go | 118 - .../semconv/v1.17.0/generated_resource.go | 1168 - .../semconv/v1.17.0/generated_trace.go | 2011 - .../collector/semconv/v1.17.0/schema.go | 9 - .../semconv/v1.6.1/generated_resource.go | 991 - .../semconv/v1.6.1/generated_trace.go | 1587 - .../collector/semconv/v1.6.1/nonstandard.go | 11 - .../collector/semconv/v1.6.1/schema.go | 9 - vendor/go.uber.org/atomic/.codecov.yml | 19 - vendor/go.uber.org/atomic/.gitignore | 15 - vendor/go.uber.org/atomic/CHANGELOG.md | 127 - vendor/go.uber.org/atomic/LICENSE.txt | 19 - vendor/go.uber.org/atomic/Makefile | 79 - vendor/go.uber.org/atomic/README.md | 63 - vendor/go.uber.org/atomic/bool.go | 88 - vendor/go.uber.org/atomic/bool_ext.go | 53 - vendor/go.uber.org/atomic/doc.go | 23 - vendor/go.uber.org/atomic/duration.go | 89 - vendor/go.uber.org/atomic/duration_ext.go | 40 - vendor/go.uber.org/atomic/error.go | 72 - vendor/go.uber.org/atomic/error_ext.go | 39 - vendor/go.uber.org/atomic/float32.go | 77 - vendor/go.uber.org/atomic/float32_ext.go | 76 - vendor/go.uber.org/atomic/float64.go | 77 - vendor/go.uber.org/atomic/float64_ext.go | 76 - vendor/go.uber.org/atomic/gen.go | 27 - vendor/go.uber.org/atomic/int32.go | 109 - vendor/go.uber.org/atomic/int64.go | 109 - vendor/go.uber.org/atomic/nocmp.go | 35 - vendor/go.uber.org/atomic/pointer_go118.go | 31 - .../atomic/pointer_go118_pre119.go | 60 - vendor/go.uber.org/atomic/pointer_go119.go | 61 - vendor/go.uber.org/atomic/string.go | 72 - vendor/go.uber.org/atomic/string_ext.go | 54 - vendor/go.uber.org/atomic/time.go | 55 - vendor/go.uber.org/atomic/time_ext.go | 36 - vendor/go.uber.org/atomic/uint32.go | 109 - vendor/go.uber.org/atomic/uint64.go | 109 - vendor/go.uber.org/atomic/uintptr.go | 109 - vendor/go.uber.org/atomic/unsafe_pointer.go | 65 - vendor/go.uber.org/atomic/value.go | 31 - vendor/go.uber.org/multierr/.codecov.yml | 15 - vendor/go.uber.org/multierr/.gitignore | 4 - vendor/go.uber.org/multierr/CHANGELOG.md | 95 - vendor/go.uber.org/multierr/LICENSE.txt | 19 - vendor/go.uber.org/multierr/Makefile | 38 - vendor/go.uber.org/multierr/README.md | 43 - vendor/go.uber.org/multierr/error.go | 646 - .../go.uber.org/multierr/error_post_go120.go | 48 - .../go.uber.org/multierr/error_pre_go120.go | 79 - vendor/go.uber.org/zap/.codecov.yml | 17 - vendor/go.uber.org/zap/.gitignore | 32 - vendor/go.uber.org/zap/.golangci.yml | 77 - vendor/go.uber.org/zap/.readme.tmpl | 117 - vendor/go.uber.org/zap/CHANGELOG.md | 687 - vendor/go.uber.org/zap/CODE_OF_CONDUCT.md | 75 - vendor/go.uber.org/zap/CONTRIBUTING.md | 70 - vendor/go.uber.org/zap/FAQ.md | 164 - vendor/go.uber.org/zap/LICENSE | 19 - vendor/go.uber.org/zap/Makefile | 76 - vendor/go.uber.org/zap/README.md | 149 - vendor/go.uber.org/zap/array.go | 447 - vendor/go.uber.org/zap/buffer/buffer.go | 146 - vendor/go.uber.org/zap/buffer/pool.go | 53 - vendor/go.uber.org/zap/checklicense.sh | 17 - vendor/go.uber.org/zap/config.go | 330 - vendor/go.uber.org/zap/doc.go | 117 - vendor/go.uber.org/zap/encoder.go | 79 - vendor/go.uber.org/zap/error.go | 82 - vendor/go.uber.org/zap/field.go | 615 - vendor/go.uber.org/zap/flag.go | 39 - vendor/go.uber.org/zap/glide.yaml | 34 - vendor/go.uber.org/zap/global.go | 169 - vendor/go.uber.org/zap/http_handler.go | 140 - .../zap/internal/bufferpool/bufferpool.go | 31 - .../go.uber.org/zap/internal/color/color.go | 44 - vendor/go.uber.org/zap/internal/exit/exit.go | 66 - .../go.uber.org/zap/internal/level_enabler.go | 37 - vendor/go.uber.org/zap/internal/pool/pool.go | 58 - .../zap/internal/stacktrace/stack.go | 181 - vendor/go.uber.org/zap/level.go | 153 - vendor/go.uber.org/zap/logger.go | 435 - vendor/go.uber.org/zap/options.go | 182 - vendor/go.uber.org/zap/sink.go | 180 - vendor/go.uber.org/zap/sugar.go | 476 - vendor/go.uber.org/zap/time.go | 27 - vendor/go.uber.org/zap/writer.go | 98 - .../zap/zapcore/buffered_write_syncer.go | 219 - vendor/go.uber.org/zap/zapcore/clock.go | 48 - .../zap/zapcore/console_encoder.go | 157 - vendor/go.uber.org/zap/zapcore/core.go | 122 - vendor/go.uber.org/zap/zapcore/doc.go | 24 - vendor/go.uber.org/zap/zapcore/encoder.go | 466 - vendor/go.uber.org/zap/zapcore/entry.go | 298 - vendor/go.uber.org/zap/zapcore/error.go | 136 - vendor/go.uber.org/zap/zapcore/field.go | 233 - vendor/go.uber.org/zap/zapcore/hook.go | 77 - .../go.uber.org/zap/zapcore/increase_level.go | 75 - .../go.uber.org/zap/zapcore/json_encoder.go | 583 - vendor/go.uber.org/zap/zapcore/lazy_with.go | 54 - vendor/go.uber.org/zap/zapcore/level.go | 229 - .../go.uber.org/zap/zapcore/level_strings.go | 46 - vendor/go.uber.org/zap/zapcore/marshaler.go | 61 - .../go.uber.org/zap/zapcore/memory_encoder.go | 179 - .../zap/zapcore/reflected_encoder.go | 41 - vendor/go.uber.org/zap/zapcore/sampler.go | 229 - vendor/go.uber.org/zap/zapcore/tee.go | 96 - .../go.uber.org/zap/zapcore/write_syncer.go | 122 - vendor/go.uber.org/zap/zapgrpc/zapgrpc.go | 243 - vendor/golang.org/x/crypto/cryptobyte/asn1.go | 825 - .../x/crypto/cryptobyte/asn1/asn1.go | 46 - .../golang.org/x/crypto/cryptobyte/builder.go | 350 - .../golang.org/x/crypto/cryptobyte/string.go | 183 - .../golang.org/x/crypto/pkcs12/bmp-string.go | 50 - vendor/golang.org/x/crypto/pkcs12/crypto.go | 131 - vendor/golang.org/x/crypto/pkcs12/errors.go | 23 - .../x/crypto/pkcs12/internal/rc2/rc2.go | 268 - vendor/golang.org/x/crypto/pkcs12/mac.go | 45 - vendor/golang.org/x/crypto/pkcs12/pbkdf.go | 170 - vendor/golang.org/x/crypto/pkcs12/pkcs12.go | 360 - vendor/golang.org/x/crypto/pkcs12/safebags.go | 57 - .../x/oauth2/authhandler/authhandler.go | 94 - .../golang.org/x/oauth2/google/appengine.go | 40 - vendor/golang.org/x/oauth2/google/default.go | 329 - vendor/golang.org/x/oauth2/google/doc.go | 53 - vendor/golang.org/x/oauth2/google/error.go | 64 - .../x/oauth2/google/externalaccount/aws.go | 577 - .../google/externalaccount/basecredentials.go | 517 - .../externalaccount/executablecredsource.go | 313 - .../google/externalaccount/filecredsource.go | 61 - .../x/oauth2/google/externalaccount/header.go | 64 - .../programmaticrefreshcredsource.go | 21 - .../google/externalaccount/urlcredsource.go | 79 - vendor/golang.org/x/oauth2/google/google.go | 312 - .../externalaccountauthorizeduser.go | 114 - .../internal/impersonate/impersonate.go | 105 - .../google/internal/stsexchange/clientauth.go | 45 - .../internal/stsexchange/sts_exchange.go | 125 - vendor/golang.org/x/oauth2/google/jwt.go | 102 - vendor/golang.org/x/oauth2/google/sdk.go | 201 - vendor/golang.org/x/oauth2/jws/jws.go | 182 - vendor/golang.org/x/oauth2/jwt/jwt.go | 185 - .../x/text/encoding/simplifiedchinese/all.go | 12 - .../x/text/encoding/simplifiedchinese/gbk.go | 273 - .../encoding/simplifiedchinese/hzgb2312.go | 245 - .../text/encoding/simplifiedchinese/tables.go | 43999 -------------- vendor/golang.org/x/xerrors/LICENSE | 27 - vendor/golang.org/x/xerrors/PATENTS | 22 - vendor/golang.org/x/xerrors/README | 2 - vendor/golang.org/x/xerrors/adaptor.go | 193 - vendor/golang.org/x/xerrors/codereview.cfg | 1 - vendor/golang.org/x/xerrors/doc.go | 23 - vendor/golang.org/x/xerrors/errors.go | 33 - vendor/golang.org/x/xerrors/fmt.go | 190 - vendor/golang.org/x/xerrors/format.go | 34 - vendor/golang.org/x/xerrors/frame.go | 56 - .../golang.org/x/xerrors/internal/internal.go | 8 - vendor/golang.org/x/xerrors/wrap.go | 112 - vendor/google.golang.org/api/AUTHORS | 11 - vendor/google.golang.org/api/CONTRIBUTORS | 56 - vendor/google.golang.org/api/LICENSE | 27 - .../google.golang.org/api/dns/v1/dns-api.json | 3540 -- .../google.golang.org/api/dns/v1/dns-gen.go | 7625 --- .../api/googleapi/googleapi.go | 523 - .../api/googleapi/transport/apikey.go | 44 - .../google.golang.org/api/googleapi/types.go | 202 - vendor/google.golang.org/api/internal/cba.go | 318 - .../api/internal/cert/default_cert.go | 58 - .../api/internal/cert/enterprise_cert.go | 54 - .../api/internal/cert/secureconnect_cert.go | 122 - .../api/internal/conn_pool.go | 30 - .../google.golang.org/api/internal/creds.go | 327 - .../api/internal/gensupport/buffer.go | 79 - .../api/internal/gensupport/doc.go | 10 - .../api/internal/gensupport/error.go | 24 - .../api/internal/gensupport/json.go | 236 - .../api/internal/gensupport/jsonfloat.go | 47 - .../api/internal/gensupport/media.go | 317 - .../api/internal/gensupport/params.go | 78 - .../api/internal/gensupport/resumable.go | 309 - .../api/internal/gensupport/retry.go | 123 - .../api/internal/gensupport/send.go | 241 - .../api/internal/gensupport/version.go | 53 - .../api/internal/impersonate/impersonate.go | 127 - vendor/google.golang.org/api/internal/s2a.go | 136 - .../api/internal/settings.go | 248 - .../internal/third_party/uritemplates/LICENSE | 27 - .../third_party/uritemplates/METADATA | 14 - .../third_party/uritemplates/uritemplates.go | 248 - .../third_party/uritemplates/utils.go | 17 - .../google.golang.org/api/internal/version.go | 8 - .../option/internaloption/internaloption.go | 316 - vendor/google.golang.org/api/option/option.go | 416 - .../api/transport/http/dial.go | 321 - .../genproto/googleapis/rpc/code/code.pb.go | 336 - .../grpc/resolver/manual/manual.go | 128 - .../gopkg.in/DataDog/dd-trace-go.v1/LICENSE | 234 - .../dd-trace-go.v1/LICENSE-3rdparty.csv | 4 - .../DataDog/dd-trace-go.v1/LICENSE-APACHE | 200 - .../DataDog/dd-trace-go.v1/LICENSE-BSD3 | 24 - vendor/gopkg.in/DataDog/dd-trace-go.v1/NOTICE | 4 - .../dd-trace-go.v1/appsec/events/block.go | 32 - .../datastreams/options/options.go | 10 - .../DataDog/dd-trace-go.v1/ddtrace/ddtrace.go | 189 - .../dd-trace-go.v1/ddtrace/ext/app_types.go | 84 - .../DataDog/dd-trace-go.v1/ddtrace/ext/db.go | 112 - .../dd-trace-go.v1/ddtrace/ext/log_key.go | 13 - .../dd-trace-go.v1/ddtrace/ext/messaging.go | 25 - .../dd-trace-go.v1/ddtrace/ext/peer.go | 20 - .../dd-trace-go.v1/ddtrace/ext/priority.go | 27 - .../DataDog/dd-trace-go.v1/ddtrace/ext/rpc.go | 34 - .../dd-trace-go.v1/ddtrace/ext/span_kind.go | 32 - .../dd-trace-go.v1/ddtrace/ext/system.go | 12 - .../dd-trace-go.v1/ddtrace/ext/tags.go | 121 - .../ddtrace/internal/globaltracer.go | 104 - .../ddtrace/opentracer/option.go | 34 - .../dd-trace-go.v1/ddtrace/opentracer/span.go | 87 - .../ddtrace/opentracer/tracer.go | 126 - .../dd-trace-go.v1/ddtrace/span_link_msgp.go | 221 - .../ddtrace/tracer/abandonedspans.go | 314 - .../ddtrace/tracer/civisibility_payload.go | 152 - .../ddtrace/tracer/civisibility_transport.go | 207 - .../ddtrace/tracer/civisibility_tslv.go | 445 - .../ddtrace/tracer/civisibility_tslv_msgp.go | 924 - .../ddtrace/tracer/civisibility_writer.go | 130 - .../dd-trace-go.v1/ddtrace/tracer/context.go | 66 - .../ddtrace/tracer/data_streams.go | 74 - .../dd-trace-go.v1/ddtrace/tracer/doc.go | 110 - .../ddtrace/tracer/dynamic_config.go | 118 - .../dd-trace-go.v1/ddtrace/tracer/log.go | 173 - .../ddtrace/tracer/meta_struct.go | 88 - .../dd-trace-go.v1/ddtrace/tracer/metrics.go | 103 - .../dd-trace-go.v1/ddtrace/tracer/option.go | 1506 - .../ddtrace/tracer/orchestrion.yml | 123 - .../ddtrace/tracer/otel_dd_mappings.go | 202 - .../dd-trace-go.v1/ddtrace/tracer/payload.go | 154 - .../ddtrace/tracer/propagating_tags.go | 68 - .../ddtrace/tracer/propagator.go | 57 - .../dd-trace-go.v1/ddtrace/tracer/rand.go | 19 - .../ddtrace/tracer/remote_config.go | 360 - .../ddtrace/tracer/rules_sampler.go | 885 - .../dd-trace-go.v1/ddtrace/tracer/sampler.go | 150 - .../dd-trace-go.v1/ddtrace/tracer/slog.go | 68 - .../dd-trace-go.v1/ddtrace/tracer/span.go | 781 - .../ddtrace/tracer/span_msgp.go | 667 - .../ddtrace/tracer/spancontext.go | 642 - .../ddtrace/tracer/sqlcomment.go | 323 - .../dd-trace-go.v1/ddtrace/tracer/stats.go | 223 - .../ddtrace/tracer/telemetry.go | 118 - .../dd-trace-go.v1/ddtrace/tracer/textmap.go | 1278 - .../dd-trace-go.v1/ddtrace/tracer/time.go | 17 - .../ddtrace/tracer/time_windows.go | 48 - .../dd-trace-go.v1/ddtrace/tracer/tracer.go | 866 - .../ddtrace/tracer/transport.go | 216 - .../dd-trace-go.v1/ddtrace/tracer/util.go | 177 - .../dd-trace-go.v1/ddtrace/tracer/writer.go | 362 - .../internal/active_span_key.go | 11 - .../internal/agent-otel-workaround.go | 18 - .../DataDog/dd-trace-go.v1/internal/agent.go | 75 - .../dd-trace-go.v1/internal/appsec/README.md | 212 - .../dd-trace-go.v1/internal/appsec/appsec.go | 229 - .../internal/appsec/config/config.go | 223 - .../internal/appsec/config/rules_manager.go | 147 - .../internal/appsec/dyngo/operation.go | 383 - .../appsec/emitter/graphqlsec/README.md | 25 - .../appsec/emitter/graphqlsec/execution.go | 66 - .../appsec/emitter/graphqlsec/request.go | 74 - .../appsec/emitter/graphqlsec/resolve.go | 63 - .../internal/appsec/emitter/grpcsec/grpc.go | 125 - .../internal/appsec/emitter/httpsec/config.go | 24 - .../internal/appsec/emitter/httpsec/http.go | 200 - .../appsec/emitter/httpsec/roundtripper.go | 71 - .../internal/appsec/emitter/ossec/lfi.go | 41 - .../internal/appsec/emitter/sqlsec/sql.go | 71 - .../emitter/trace/service_entry_span.go | 156 - .../internal/appsec/emitter/trace/span.go | 67 - .../appsec/emitter/trace/tag_setter.go | 29 - .../internal/appsec/emitter/usersec/user.go | 73 - .../appsec/emitter/waf/actions/actions.go | 56 - .../appsec/emitter/waf/actions/block.go | 161 - .../emitter/waf/actions/blocked-template.html | 1 - .../emitter/waf/actions/blocked-template.json | 1 - .../emitter/waf/actions/http_redirect.go | 54 - .../appsec/emitter/waf/actions/stacktrace.go | 44 - .../appsec/emitter/waf/addresses/addresses.go | 40 - .../appsec/emitter/waf/addresses/builder.go | 243 - .../internal/appsec/emitter/waf/context.go | 163 - .../internal/appsec/emitter/waf/run.go | 78 - .../internal/appsec/features.go | 81 - .../internal/appsec/listener/feature.go | 24 - .../appsec/listener/graphqlsec/graphql.go | 43 - .../internal/appsec/listener/grpcsec/grpc.go | 75 - .../internal/appsec/listener/httpsec/http.go | 96 - .../appsec/listener/httpsec/request.go | 167 - .../appsec/listener/httpsec/roundtripper.go | 40 - .../internal/appsec/listener/ossec/lfi.go | 53 - .../internal/appsec/listener/sqlsec/sql.go | 43 - .../internal/appsec/listener/trace/trace.go | 53 - .../internal/appsec/listener/usersec/usec.go | 59 - .../internal/appsec/listener/waf/tags.go | 77 - .../internal/appsec/listener/waf/waf.go | 145 - .../internal/appsec/remoteconfig.go | 458 - .../internal/appsec/telemetry.go | 91 - .../internal/appsec/telemetry_cgo.go | 14 - .../internal/civisibility/constants/ci.go | 44 - .../internal/civisibility/constants/env.go | 40 - .../internal/civisibility/constants/git.go | 61 - .../internal/civisibility/constants/os.go | 21 - .../civisibility/constants/runtime.go | 16 - .../civisibility/constants/span_types.go | 28 - .../internal/civisibility/constants/tags.go | 50 - .../civisibility/constants/test_tags.go | 139 - .../civisibility/utils/ci_providers.go | 610 - .../internal/civisibility/utils/codeowners.go | 307 - .../civisibility/utils/environmentTags.go | 325 - .../internal/civisibility/utils/git.go | 490 - .../internal/civisibility/utils/home.go | 126 - .../internal/civisibility/utils/names.go | 93 - .../civisibility/utils/telemetry/telemetry.go | 144 - .../utils/telemetry/telemetry_count.go | 212 - .../utils/telemetry/telemetry_distribution.go | 104 - .../internal/container_linux.go | 182 - .../dd-trace-go.v1/internal/container_stub.go | 19 - .../internal/datastreams/fast_queue.go | 67 - .../internal/datastreams/hash_cache.go | 70 - .../internal/datastreams/pathway.go | 94 - .../internal/datastreams/payload.go | 84 - .../internal/datastreams/payload_msgp.go | 907 - .../internal/datastreams/processor.go | 510 - .../internal/datastreams/propagator.go | 87 - .../internal/datastreams/transport.go | 90 - .../DataDog/dd-trace-go.v1/internal/env.go | 140 - .../dd-trace-go.v1/internal/gitmetadata.go | 164 - .../internal/globalconfig/globalconfig.go | 132 - .../internal/hostname/azure/azure.go | 63 - .../internal/hostname/cachedfetch/fetcher.go | 86 - .../internal/hostname/ec2/ec2.go | 72 - .../internal/hostname/ecs/aws.go | 54 - .../internal/hostname/fqdn_nix.go | 28 - .../internal/hostname/fqdn_windows.go | 14 - .../internal/hostname/gce/gce.go | 120 - .../internal/hostname/httputils/helpers.go | 74 - .../internal/hostname/providers.go | 245 - .../internal/hostname/validate/validate.go | 57 - .../dd-trace-go.v1/internal/log/log.go | 318 - .../internal/meta_internal_types.go | 18 - .../internal/namingschema/namingschema.go | 77 - .../internal/namingschema/op.go | 191 - .../internal/namingschema/service_name.go | 40 - .../internal/normalizer/normalizer.go | 52 - .../internal/orchestrion/context.go | 70 - .../internal/orchestrion/context_stack.go | 62 - .../internal/orchestrion/gls.go | 41 - .../internal/orchestrion/gls.orchestrion.yml | 48 - .../internal/orchestrion/orchestrion.go | 18 - .../dd-trace-go.v1/internal/osinfo/osinfo.go | 54 - .../internal/osinfo/osinfo_unix.go | 70 - .../internal/osinfo/osinfo_windows.go | 52 - .../internal/remoteconfig/config.go | 68 - .../internal/remoteconfig/remoteconfig.go | 667 - .../internal/remoteconfig/types.go | 83 - .../internal/samplernames/samplernames.go | 45 - .../internal/stacktrace/event.go | 115 - .../internal/stacktrace/event_msgp.go | 333 - .../internal/stacktrace/stacktrace.go | 253 - .../internal/stacktrace/stacktrace_msgp.go | 475 - .../DataDog/dd-trace-go.v1/internal/statsd.go | 38 - .../internal/telemetry/client.go | 618 - .../internal/telemetry/message.go | 305 - .../internal/telemetry/option.go | 150 - .../internal/telemetry/telemetry.go | 126 - .../internal/telemetry/utils.go | 101 - .../dd-trace-go.v1/internal/trace_context.go | 49 - .../internal/traceprof/endpoint_counter.go | 105 - .../internal/traceprof/profiler.go | 35 - .../internal/traceprof/traceprof.go | 21 - .../DataDog/dd-trace-go.v1/internal/utils.go | 70 - .../internal/version/version.go | 43 - vendor/gopkg.in/ini.v1/.editorconfig | 12 - vendor/gopkg.in/ini.v1/.gitignore | 7 - vendor/gopkg.in/ini.v1/.golangci.yml | 27 - vendor/gopkg.in/ini.v1/LICENSE | 191 - vendor/gopkg.in/ini.v1/Makefile | 15 - vendor/gopkg.in/ini.v1/README.md | 43 - vendor/gopkg.in/ini.v1/codecov.yml | 16 - vendor/gopkg.in/ini.v1/data_source.go | 76 - vendor/gopkg.in/ini.v1/deprecated.go | 22 - vendor/gopkg.in/ini.v1/error.go | 49 - vendor/gopkg.in/ini.v1/file.go | 541 - vendor/gopkg.in/ini.v1/helper.go | 24 - vendor/gopkg.in/ini.v1/ini.go | 176 - vendor/gopkg.in/ini.v1/key.go | 837 - vendor/gopkg.in/ini.v1/parser.go | 520 - vendor/gopkg.in/ini.v1/section.go | 256 - vendor/gopkg.in/ini.v1/struct.go | 747 - vendor/modules.txt | 718 +- 2573 files changed, 39 insertions(+), 632239 deletions(-) delete mode 100644 pkg/dns/coredns.go rename pkg/dns/{forwardserver.go => forward_server.go} (100%) rename pkg/dns/{forwardserver_test.go => forward_server_test.go} (100%) delete mode 100644 vendor/cloud.google.com/go/auth/CHANGES.md delete mode 100644 vendor/cloud.google.com/go/auth/LICENSE delete mode 100644 vendor/cloud.google.com/go/auth/README.md delete mode 100644 vendor/cloud.google.com/go/auth/auth.go delete mode 100644 vendor/cloud.google.com/go/auth/credentials/compute.go delete mode 100644 vendor/cloud.google.com/go/auth/credentials/detect.go delete mode 100644 vendor/cloud.google.com/go/auth/credentials/doc.go delete mode 100644 vendor/cloud.google.com/go/auth/credentials/filetypes.go delete mode 100644 vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/aws_provider.go delete mode 100644 vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/executable_provider.go delete mode 100644 vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/externalaccount.go delete mode 100644 vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/file_provider.go delete mode 100644 vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/info.go delete mode 100644 vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/programmatic_provider.go delete mode 100644 vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/url_provider.go delete mode 100644 vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/x509_provider.go delete mode 100644 vendor/cloud.google.com/go/auth/credentials/internal/externalaccountuser/externalaccountuser.go delete mode 100644 vendor/cloud.google.com/go/auth/credentials/internal/gdch/gdch.go delete mode 100644 vendor/cloud.google.com/go/auth/credentials/internal/impersonate/idtoken.go delete mode 100644 vendor/cloud.google.com/go/auth/credentials/internal/impersonate/impersonate.go delete mode 100644 vendor/cloud.google.com/go/auth/credentials/internal/stsexchange/sts_exchange.go delete mode 100644 vendor/cloud.google.com/go/auth/credentials/selfsignedjwt.go delete mode 100644 vendor/cloud.google.com/go/auth/httptransport/httptransport.go delete mode 100644 vendor/cloud.google.com/go/auth/httptransport/transport.go delete mode 100644 vendor/cloud.google.com/go/auth/internal/credsfile/credsfile.go delete mode 100644 vendor/cloud.google.com/go/auth/internal/credsfile/filetype.go delete mode 100644 vendor/cloud.google.com/go/auth/internal/credsfile/parse.go delete mode 100644 vendor/cloud.google.com/go/auth/internal/internal.go delete mode 100644 vendor/cloud.google.com/go/auth/internal/jwt/jwt.go delete mode 100644 vendor/cloud.google.com/go/auth/internal/transport/cba.go delete mode 100644 vendor/cloud.google.com/go/auth/internal/transport/cert/default_cert.go delete mode 100644 vendor/cloud.google.com/go/auth/internal/transport/cert/enterprise_cert.go delete mode 100644 vendor/cloud.google.com/go/auth/internal/transport/cert/secureconnect_cert.go delete mode 100644 vendor/cloud.google.com/go/auth/internal/transport/cert/workload_cert.go delete mode 100644 vendor/cloud.google.com/go/auth/internal/transport/s2a.go delete mode 100644 vendor/cloud.google.com/go/auth/internal/transport/transport.go delete mode 100644 vendor/cloud.google.com/go/auth/oauth2adapt/CHANGES.md delete mode 100644 vendor/cloud.google.com/go/auth/oauth2adapt/LICENSE delete mode 100644 vendor/cloud.google.com/go/auth/oauth2adapt/oauth2adapt.go delete mode 100644 vendor/cloud.google.com/go/auth/threelegged.go delete mode 100644 vendor/cloud.google.com/go/compute/metadata/CHANGES.md delete mode 100644 vendor/cloud.google.com/go/compute/metadata/LICENSE delete mode 100644 vendor/cloud.google.com/go/compute/metadata/README.md delete mode 100644 vendor/cloud.google.com/go/compute/metadata/log.go delete mode 100644 vendor/cloud.google.com/go/compute/metadata/metadata.go delete mode 100644 vendor/cloud.google.com/go/compute/metadata/retry.go delete mode 100644 vendor/cloud.google.com/go/compute/metadata/retry_linux.go delete mode 100644 vendor/cloud.google.com/go/compute/metadata/syscheck.go delete mode 100644 vendor/cloud.google.com/go/compute/metadata/syscheck_linux.go delete mode 100644 vendor/cloud.google.com/go/compute/metadata/syscheck_windows.go delete mode 100644 vendor/github.com/Azure/azure-sdk-for-go/LICENSE.txt delete mode 100644 vendor/github.com/Azure/azure-sdk-for-go/NOTICE.txt delete mode 100644 vendor/github.com/Azure/azure-sdk-for-go/profiles/latest/dns/mgmt/dns/models.go delete mode 100644 vendor/github.com/Azure/azure-sdk-for-go/profiles/latest/privatedns/mgmt/privatedns/models.go delete mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns/CHANGELOG.md delete mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns/_meta.json delete mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns/client.go delete mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns/enums.go delete mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns/models.go delete mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns/recordsets.go delete mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns/resourcereference.go delete mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns/version.go delete mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns/zones.go delete mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2020-06-01/privatedns/CHANGELOG.md delete mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2020-06-01/privatedns/_meta.json delete mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2020-06-01/privatedns/client.go delete mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2020-06-01/privatedns/enums.go delete mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2020-06-01/privatedns/models.go delete mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2020-06-01/privatedns/privatezones.go delete mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2020-06-01/privatedns/recordsets.go delete mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2020-06-01/privatedns/version.go delete mode 100644 vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2020-06-01/privatedns/virtualnetworklinks.go delete mode 100644 vendor/github.com/Azure/azure-sdk-for-go/version/version.go delete mode 100644 vendor/github.com/Azure/go-autorest/.gitignore delete mode 100644 vendor/github.com/Azure/go-autorest/CHANGELOG.md delete mode 100644 vendor/github.com/Azure/go-autorest/GNUmakefile delete mode 100644 vendor/github.com/Azure/go-autorest/Gopkg.lock delete mode 100644 vendor/github.com/Azure/go-autorest/Gopkg.toml delete mode 100644 vendor/github.com/Azure/go-autorest/LICENSE delete mode 100644 vendor/github.com/Azure/go-autorest/README.md delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/LICENSE delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/adal/LICENSE delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/adal/README.md delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/adal/config.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/adal/devicetoken.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/adal/go_mod_tidy_hack.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/adal/persist.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/adal/sender.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/adal/token.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/adal/token_1.13.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/adal/token_legacy.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/adal/version.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/authorization.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/authorization_sas.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/authorization_storage.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/autorest.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/azure/async.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/azure/auth/LICENSE delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/azure/auth/README.md delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/azure/auth/auth.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/azure/auth/go_mod_tidy_hack.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/azure/azure.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/azure/cli/LICENSE delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/azure/cli/go_mod_tidy_hack.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/azure/cli/profile.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/azure/cli/token.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/azure/environments.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/azure/metadata_environment.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/azure/rp.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/client.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/date/LICENSE delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/date/date.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/date/go_mod_tidy_hack.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/date/time.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/date/timerfc1123.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/date/unixtime.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/date/utility.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/error.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/go_mod_tidy_hack.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/preparer.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/responder.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/retriablerequest.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.7.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.8.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/sender.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/to/LICENSE delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/to/convert.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/to/go_mod_tidy_hack.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/utility.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/utility_1.13.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/utility_legacy.go delete mode 100644 vendor/github.com/Azure/go-autorest/autorest/version.go delete mode 100644 vendor/github.com/Azure/go-autorest/azure-pipelines.yml delete mode 100644 vendor/github.com/Azure/go-autorest/doc.go delete mode 100644 vendor/github.com/Azure/go-autorest/logger/LICENSE delete mode 100644 vendor/github.com/Azure/go-autorest/logger/go_mod_tidy_hack.go delete mode 100644 vendor/github.com/Azure/go-autorest/logger/logger.go delete mode 100644 vendor/github.com/Azure/go-autorest/tracing/LICENSE delete mode 100644 vendor/github.com/Azure/go-autorest/tracing/go_mod_tidy_hack.go delete mode 100644 vendor/github.com/Azure/go-autorest/tracing/tracing.go delete mode 100644 vendor/github.com/DataDog/appsec-internal-go/LICENSE delete mode 100644 vendor/github.com/DataDog/appsec-internal-go/appsec/config.go delete mode 100644 vendor/github.com/DataDog/appsec-internal-go/appsec/embed.go delete mode 100644 vendor/github.com/DataDog/appsec-internal-go/appsec/rules.go delete mode 100644 vendor/github.com/DataDog/appsec-internal-go/appsec/rules.json delete mode 100644 vendor/github.com/DataDog/appsec-internal-go/httpsec/client_ip.go delete mode 100644 vendor/github.com/DataDog/appsec-internal-go/limiter/limiter.go delete mode 100644 vendor/github.com/DataDog/appsec-internal-go/log/backend.go delete mode 100644 vendor/github.com/DataDog/appsec-internal-go/log/log.go delete mode 100644 vendor/github.com/DataDog/appsec-internal-go/netip/ip.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/LICENSE delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/cache.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/credit_cards.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/http.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/ip_address.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/json.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/json_scanner.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/memcached.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/obfuscate.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/redis.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/redis_tokenizer.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/sql.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/sql_tokenizer.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/proto/LICENSE delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/agent_payload.pb.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/agent_payload_gen.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/agent_payload_vtproto.pb.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/decoder_bytes.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/decoder_v05.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/span.pb.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/span_gen.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/span_utils.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/span_vtproto.pb.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/stats.pb.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/stats_gen.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/stats_vtproto.pb.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/trace.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/trace_gen.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/tracer_payload.pb.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/tracer_payload_gen.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/tracer_payload_utils.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/tracer_payload_vtproto.pb.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/LICENSE delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/README.md delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/agent_config.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/configs.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/configs_agent_task.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/configs_asm.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/path.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/products.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/repository.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/tuf.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/trace/LICENSE delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/trace/config/client.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/trace/config/config.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/trace/config/peer_tags.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/trace/config/peer_tags.ini delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/trace/log/buflogger.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/trace/log/logger.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/trace/log/throttled.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/trace/stats/aggregation.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/trace/stats/client_stats_aggregator.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/trace/stats/concentrator.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/trace/stats/otel_util.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/trace/stats/span_concentrator.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/trace/stats/statsraw.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/trace/stats/weight.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/trace/traceutil/azure.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/trace/traceutil/doc.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/trace/traceutil/normalize.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/trace/traceutil/otel_util.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/trace/traceutil/processed_trace.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/trace/traceutil/span.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/trace/traceutil/trace.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/trace/traceutil/truncate.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/trace/version/version.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/trace/watchdog/cpu.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/trace/watchdog/cpu_aix.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/trace/watchdog/cpu_windows.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/trace/watchdog/info.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/trace/watchdog/logonpanic.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/util/log/LICENSE delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/util/log/klog_redirect.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/util/log/log.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/util/log/log_limit.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/util/log/log_not_serverless.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/util/log/log_serverless.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/util/log/log_test_init.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/util/log/wrapper.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/util/scrubber/LICENSE delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/util/scrubber/default.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/util/scrubber/json_scrubber.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/util/scrubber/scrubber.go delete mode 100644 vendor/github.com/DataDog/datadog-agent/pkg/util/scrubber/yaml_scrubber.go delete mode 100644 vendor/github.com/DataDog/datadog-go/v5/LICENSE.txt delete mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/README.md delete mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/aggregator.go delete mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/buffer.go delete mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/buffer_pool.go delete mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/buffered_metric_context.go delete mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/container.go delete mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/container_linux.go delete mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/container_stub.go delete mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/error_handler.go delete mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/event.go delete mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/fnv1a.go delete mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/format.go delete mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/metrics.go delete mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/noop.go delete mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/options.go delete mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/pipe.go delete mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/pipe_windows.go delete mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/sender.go delete mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/service_check.go delete mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/statsd.go delete mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/statsd_direct.go delete mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/telemetry.go delete mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/udp.go delete mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/uds.go delete mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/uds_windows.go delete mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/utils.go delete mode 100644 vendor/github.com/DataDog/datadog-go/v5/statsd/worker.go delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/.gitattributes delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/.gitignore delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/CODEOWNERS delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/LICENSE delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/README.md delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/cgo_ref_pool.go delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/context.go delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/decoder.go delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/encoder.go delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/errors/support.go delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/errors/waf.go delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/handle.go delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/internal/bindings/ctypes.go delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/internal/bindings/safe.go delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/internal/bindings/waf_dl.go delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/internal/bindings/waf_dl_unsupported.go delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/.version delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/README.md delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/doc.go delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/dump_waf_darwin.go delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/dump_waf_linux.go delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/lib_darwin_amd64.go delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/lib_darwin_arm64.go delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/lib_linux_amd64.go delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/lib_linux_arm64.go delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/libddwaf-darwin-amd64.dylib.gz delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/libddwaf-darwin-arm64.dylib.gz delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/libddwaf-linux-amd64.so.gz delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/libddwaf-linux-arm64.so.gz delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/version.go delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/internal/log/ddwaf.h delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/internal/log/log.go delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/internal/log/log_cgo.go delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/internal/log/log_purego.go delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/internal/log/log_unsupported.go delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/internal/support/waf_cgo_disabled.go delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/internal/support/waf_manually_disabled.go delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/internal/support/waf_support.go delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/internal/support/waf_unsupported_go.go delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/internal/support/waf_unsupported_target.go delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/internal/unsafe/utils.go delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/metrics.go delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/timer/base_timer.go delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/timer/clock.go delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/timer/component.go delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/timer/config.go delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/timer/node_timer.go delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/timer/timer.go delete mode 100644 vendor/github.com/DataDog/go-libddwaf/v3/waf.go delete mode 100644 vendor/github.com/DataDog/go-runtime-metrics-internal/LICENSE delete mode 100644 vendor/github.com/DataDog/go-runtime-metrics-internal/LICENSE-3rdparty.csv delete mode 100644 vendor/github.com/DataDog/go-runtime-metrics-internal/NOTICE delete mode 100644 vendor/github.com/DataDog/go-runtime-metrics-internal/pkg/runtimemetrics/histogram.go delete mode 100644 vendor/github.com/DataDog/go-runtime-metrics-internal/pkg/runtimemetrics/runtime_metrics.go delete mode 100644 vendor/github.com/DataDog/go-runtime-metrics-internal/pkg/runtimemetrics/tags.go delete mode 100644 vendor/github.com/DataDog/go-sqllexer/.gitignore delete mode 100644 vendor/github.com/DataDog/go-sqllexer/LICENSE delete mode 100644 vendor/github.com/DataDog/go-sqllexer/README.md delete mode 100644 vendor/github.com/DataDog/go-sqllexer/normalizer.go delete mode 100644 vendor/github.com/DataDog/go-sqllexer/obfuscate_and_normalize.go delete mode 100644 vendor/github.com/DataDog/go-sqllexer/obfuscator.go delete mode 100644 vendor/github.com/DataDog/go-sqllexer/sqllexer.go delete mode 100644 vendor/github.com/DataDog/go-sqllexer/sqllexer_utils.go delete mode 100644 vendor/github.com/DataDog/go-tuf/LICENSE delete mode 100644 vendor/github.com/DataDog/go-tuf/client/client.go delete mode 100644 vendor/github.com/DataDog/go-tuf/client/delegations.go delete mode 100644 vendor/github.com/DataDog/go-tuf/client/errors.go delete mode 100644 vendor/github.com/DataDog/go-tuf/client/file_store.go delete mode 100644 vendor/github.com/DataDog/go-tuf/client/local_store.go delete mode 100644 vendor/github.com/DataDog/go-tuf/client/remote_store.go delete mode 100644 vendor/github.com/DataDog/go-tuf/data/hex_bytes.go delete mode 100644 vendor/github.com/DataDog/go-tuf/data/types.go delete mode 100644 vendor/github.com/DataDog/go-tuf/internal/roles/roles.go delete mode 100644 vendor/github.com/DataDog/go-tuf/internal/sets/strings.go delete mode 100644 vendor/github.com/DataDog/go-tuf/pkg/keys/deprecated_ecdsa.go delete mode 100644 vendor/github.com/DataDog/go-tuf/pkg/keys/ecdsa.go delete mode 100644 vendor/github.com/DataDog/go-tuf/pkg/keys/ed25519.go delete mode 100644 vendor/github.com/DataDog/go-tuf/pkg/keys/keys.go delete mode 100644 vendor/github.com/DataDog/go-tuf/pkg/keys/pkix.go delete mode 100644 vendor/github.com/DataDog/go-tuf/pkg/keys/rsa.go delete mode 100644 vendor/github.com/DataDog/go-tuf/pkg/targets/delegation.go delete mode 100644 vendor/github.com/DataDog/go-tuf/pkg/targets/hash_bins.go delete mode 100644 vendor/github.com/DataDog/go-tuf/util/util.go delete mode 100644 vendor/github.com/DataDog/go-tuf/verify/db.go delete mode 100644 vendor/github.com/DataDog/go-tuf/verify/errors.go delete mode 100644 vendor/github.com/DataDog/go-tuf/verify/verify.go delete mode 100644 vendor/github.com/DataDog/opentelemetry-mapping-go/pkg/otlp/attributes/LICENSE delete mode 100644 vendor/github.com/DataDog/opentelemetry-mapping-go/pkg/otlp/attributes/attributes.go delete mode 100644 vendor/github.com/DataDog/opentelemetry-mapping-go/pkg/otlp/attributes/azure/azure.go delete mode 100644 vendor/github.com/DataDog/opentelemetry-mapping-go/pkg/otlp/attributes/ec2/ec2.go delete mode 100644 vendor/github.com/DataDog/opentelemetry-mapping-go/pkg/otlp/attributes/gcp/gcp.go delete mode 100644 vendor/github.com/DataDog/opentelemetry-mapping-go/pkg/otlp/attributes/process.go delete mode 100644 vendor/github.com/DataDog/opentelemetry-mapping-go/pkg/otlp/attributes/source.go delete mode 100644 vendor/github.com/DataDog/opentelemetry-mapping-go/pkg/otlp/attributes/source/source_provider.go delete mode 100644 vendor/github.com/DataDog/opentelemetry-mapping-go/pkg/otlp/attributes/system.go delete mode 100644 vendor/github.com/DataDog/opentelemetry-mapping-go/pkg/otlp/attributes/translator.go delete mode 100644 vendor/github.com/DataDog/sketches-go/LICENSE delete mode 100644 vendor/github.com/DataDog/sketches-go/LICENSE-3rdparty.csv delete mode 100644 vendor/github.com/DataDog/sketches-go/NOTICE delete mode 100644 vendor/github.com/DataDog/sketches-go/ddsketch/ddsketch.go delete mode 100644 vendor/github.com/DataDog/sketches-go/ddsketch/encoding/encoding.go delete mode 100644 vendor/github.com/DataDog/sketches-go/ddsketch/encoding/flag.go delete mode 100644 vendor/github.com/DataDog/sketches-go/ddsketch/mapping/bit_operation_helper.go delete mode 100644 vendor/github.com/DataDog/sketches-go/ddsketch/mapping/cubically_interpolated_mapping.go delete mode 100644 vendor/github.com/DataDog/sketches-go/ddsketch/mapping/index_mapping.go delete mode 100644 vendor/github.com/DataDog/sketches-go/ddsketch/mapping/linearly_interpolated_mapping.go delete mode 100644 vendor/github.com/DataDog/sketches-go/ddsketch/mapping/logarithmic_mapping.go delete mode 100644 vendor/github.com/DataDog/sketches-go/ddsketch/pb/sketchpb/ddsketch.pb.go delete mode 100644 vendor/github.com/DataDog/sketches-go/ddsketch/stat/summary.go delete mode 100644 vendor/github.com/DataDog/sketches-go/ddsketch/store/bin.go delete mode 100644 vendor/github.com/DataDog/sketches-go/ddsketch/store/buffered_paginated.go delete mode 100644 vendor/github.com/DataDog/sketches-go/ddsketch/store/collapsing_highest_dense_store.go delete mode 100644 vendor/github.com/DataDog/sketches-go/ddsketch/store/collapsing_lowest_dense_store.go delete mode 100644 vendor/github.com/DataDog/sketches-go/ddsketch/store/dense_store.go delete mode 100644 vendor/github.com/DataDog/sketches-go/ddsketch/store/sparse.go delete mode 100644 vendor/github.com/DataDog/sketches-go/ddsketch/store/store.go delete mode 100644 vendor/github.com/apparentlymart/go-cidr/LICENSE delete mode 100644 vendor/github.com/apparentlymart/go-cidr/cidr/cidr.go delete mode 100644 vendor/github.com/apparentlymart/go-cidr/cidr/wrangling.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/LICENSE.txt delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/NOTICE.txt delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/accountid_endpoint_mode.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/checksum.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/config.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/context.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/credential_cache.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/credentials.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/defaults/auto.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/defaults/configuration.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/defaults/defaults.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/defaults/doc.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/defaultsmode.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/doc.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/endpoints.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/errors.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/from_ptr.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/go_module_metadata.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/logging.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/logging_generate.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/metadata.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/middleware.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/osname.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/osname_go115.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/recursion_detection.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/request_id.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/request_id_retriever.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/middleware/user_agent.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/query/array.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/query/encoder.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/query/map.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/query/middleware.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/query/object.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/query/value.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/restjson/decoder_util.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/protocol/xml/error_utils.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/ratelimit/none.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/ratelimit/token_bucket.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/ratelimit/token_rate_limit.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/request.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/retry/adaptive.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/retry/adaptive_ratelimit.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/retry/adaptive_token_bucket.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/retry/attempt_metrics.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/retry/doc.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/retry/errors.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/retry/jitter_backoff.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/retry/metadata.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/retry/middleware.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/retry/retry.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/retry/retryable_error.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/retry/standard.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/retry/throttle_error.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/retry/timeout_error.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/retryer.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/runtime.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4/cache.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4/const.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4/header_rules.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4/headers.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4/hmac.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4/host.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4/scope.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4/time.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/signer/internal/v4/util.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/signer/v4/middleware.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/signer/v4/presign_middleware.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/signer/v4/stream.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/signer/v4/v4.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/to_ptr.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/transport/http/client.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/transport/http/content_type.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/transport/http/response_error.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/transport/http/response_error_middleware.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/transport/http/timeout_read_closer.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/types.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/aws/version.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/config/CHANGELOG.md delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/config/LICENSE.txt delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/config/config.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/config/defaultsmode.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/config/doc.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/config/env_config.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/config/generate.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/config/go_module_metadata.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/config/load_options.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/config/local.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/config/provider.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/config/resolve.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/config/resolve_bearer_token.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/config/resolve_credentials.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/config/shared_config.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/credentials/CHANGELOG.md delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/credentials/LICENSE.txt delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/credentials/doc.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/credentials/ec2rolecreds/doc.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/credentials/ec2rolecreds/provider.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client/auth.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client/client.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client/endpoints.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client/middleware.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/provider.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/credentials/go_module_metadata.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/credentials/processcreds/doc.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/credentials/processcreds/provider.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/credentials/ssocreds/doc.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/credentials/ssocreds/sso_cached_token.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/credentials/ssocreds/sso_credentials_provider.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/credentials/ssocreds/sso_token_provider.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/credentials/static_provider.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/credentials/stscreds/assume_role_provider.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/credentials/stscreds/web_identity_provider.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/CHANGELOG.md delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/LICENSE.txt delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/api_client.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/api_op_GetDynamicData.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/api_op_GetIAMInfo.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/api_op_GetInstanceIdentityDocument.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/api_op_GetMetadata.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/api_op_GetRegion.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/api_op_GetToken.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/api_op_GetUserData.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/auth.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/doc.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/endpoints.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/go_module_metadata.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/internal/config/resolvers.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/request_middleware.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/feature/ec2/imds/token_provider.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/auth/auth.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/auth/scheme.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/auth/smithy/bearer_token_adapter.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/auth/smithy/bearer_token_signer_adapter.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/auth/smithy/credentials_adapter.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/auth/smithy/smithy.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/auth/smithy/v4signer_adapter.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/CHANGELOG.md delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/LICENSE.txt delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/config.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/endpoints.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/configsources/go_module_metadata.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/context/context.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/arn.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/doc.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/generate.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/host.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/partition.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/partitions.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn/partitions.json delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/endpoints.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/CHANGELOG.md delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/LICENSE.txt delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/endpoints.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/endpoints/v2/go_module_metadata.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/ini/CHANGELOG.md delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/ini/LICENSE.txt delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/ini/errors.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/ini/go_module_metadata.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/ini/ini.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/ini/parse.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/ini/sections.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/ini/strings.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/ini/token.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/ini/tokenize.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/ini/value.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/middleware/middleware.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/rand/rand.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/sdk/interfaces.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/sdk/time.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/sdkio/byte.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/shareddefaults/shared_config.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/strings/strings.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/sync/singleflight/LICENSE delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/sync/singleflight/docs.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/sync/singleflight/singleflight.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/internal/timeconv/duration.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/CHANGELOG.md delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/LICENSE.txt delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/accept_encoding_gzip.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/doc.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding/go_module_metadata.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/CHANGELOG.md delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/LICENSE.txt delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/context.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/doc.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/go_module_metadata.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/internal/presigned-url/middleware.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/secretsmanager/CHANGELOG.md delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/secretsmanager/LICENSE.txt delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/secretsmanager/api_client.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/secretsmanager/api_op_BatchGetSecretValue.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/secretsmanager/api_op_CancelRotateSecret.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/secretsmanager/api_op_CreateSecret.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/secretsmanager/api_op_DeleteResourcePolicy.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/secretsmanager/api_op_DeleteSecret.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/secretsmanager/api_op_DescribeSecret.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/secretsmanager/api_op_GetRandomPassword.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/secretsmanager/api_op_GetResourcePolicy.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/secretsmanager/api_op_GetSecretValue.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/secretsmanager/api_op_ListSecretVersionIds.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/secretsmanager/api_op_ListSecrets.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/secretsmanager/api_op_PutResourcePolicy.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/secretsmanager/api_op_PutSecretValue.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/secretsmanager/api_op_RemoveRegionsFromReplication.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/secretsmanager/api_op_ReplicateSecretToRegions.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/secretsmanager/api_op_RestoreSecret.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/secretsmanager/api_op_RotateSecret.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/secretsmanager/api_op_StopReplicationToReplica.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/secretsmanager/api_op_TagResource.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/secretsmanager/api_op_UntagResource.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/secretsmanager/api_op_UpdateSecret.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/secretsmanager/api_op_UpdateSecretVersionStage.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/secretsmanager/api_op_ValidateResourcePolicy.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/secretsmanager/auth.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/secretsmanager/deserializers.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/secretsmanager/doc.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/secretsmanager/endpoints.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/secretsmanager/generated.json delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/secretsmanager/go_module_metadata.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/secretsmanager/internal/endpoints/endpoints.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/secretsmanager/options.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/secretsmanager/serializers.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/secretsmanager/types/enums.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/secretsmanager/types/errors.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/secretsmanager/types/types.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/secretsmanager/validators.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sso/CHANGELOG.md delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sso/LICENSE.txt delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_client.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_GetRoleCredentials.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_ListAccountRoles.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_ListAccounts.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sso/api_op_Logout.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sso/auth.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sso/deserializers.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sso/doc.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sso/endpoints.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sso/generated.json delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sso/go_module_metadata.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sso/internal/endpoints/endpoints.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sso/options.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sso/serializers.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sso/types/errors.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sso/types/types.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sso/validators.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/CHANGELOG.md delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/LICENSE.txt delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_client.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_CreateToken.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_CreateTokenWithIAM.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_RegisterClient.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/api_op_StartDeviceAuthorization.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/auth.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/deserializers.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/doc.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/endpoints.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/generated.json delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/go_module_metadata.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/internal/endpoints/endpoints.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/options.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/serializers.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/types/errors.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/types/types.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/ssooidc/validators.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sts/CHANGELOG.md delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sts/LICENSE.txt delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_client.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRole.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoleWithSAML.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoleWithWebIdentity.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_AssumeRoot.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_DecodeAuthorizationMessage.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetAccessKeyInfo.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetCallerIdentity.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetFederationToken.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sts/api_op_GetSessionToken.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sts/auth.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sts/deserializers.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sts/doc.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sts/endpoints.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sts/generated.json delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sts/go_module_metadata.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sts/internal/endpoints/endpoints.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sts/options.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sts/serializers.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sts/types/errors.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sts/types/types.go delete mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/sts/validators.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/LICENSE.txt delete mode 100644 vendor/github.com/aws/aws-sdk-go/NOTICE.txt delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/auth/bearer/token.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/awserr/error.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/awserr/types.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/awsutil/copy.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/awsutil/equal.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/awsutil/path_value.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/awsutil/prettify.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/awsutil/string_value.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/client/client.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/client/logger.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/client/metadata/client_info.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/client/no_op_retryer.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/config.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/context_1_5.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/context_1_9.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/context_background_1_5.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/context_background_1_7.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/context_sleep.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/convert_types.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/corehandlers/awsinternal.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/corehandlers/handlers.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/corehandlers/param_validator.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/corehandlers/user_agent.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/chain_provider.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/context_background_go1.5.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/context_background_go1.7.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/context_go1.5.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/context_go1.9.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/credentials.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds/ec2_role_provider.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/endpointcreds/provider.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/env_provider.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/example.ini delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/processcreds/provider.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/ssocreds/doc.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/ssocreds/os.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/ssocreds/os_windows.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/ssocreds/provider.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/ssocreds/sso_cached_token.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/ssocreds/token_provider.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/static_provider.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/web_identity_provider.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/csm/doc.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/csm/enable.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/csm/metric.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/csm/metric_chan.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/csm/metric_exception.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/csm/reporter.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/defaults/defaults.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/defaults/shared_config.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/doc.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/api.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/service.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/token_provider.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/endpoints/decode.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/endpoints/dep_service_ids.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/endpoints/doc.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/endpoints/endpoints.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/endpoints/legacy_regions.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model_codegen.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/errors.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/jsonvalue.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/logger.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/handlers.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/http_request.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/offset_reader.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/request.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/request_1_7.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/request_1_8.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/request_context.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/request_context_1_6.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/request_pagination.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/retryer.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/timeout_read_closer.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/validation.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/waiter.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/session/credentials.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/session/custom_transport.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/session/custom_transport_go1.12.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/session/custom_transport_go1.5.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/session/custom_transport_go1.6.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/session/doc.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/session/env_config.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/session/session.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/session/shared_config.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/signer/v4/header_rules.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/signer/v4/options.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/signer/v4/request_context_go1.5.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/signer/v4/request_context_go1.7.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/signer/v4/stream.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/signer/v4/uri_path.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/types.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/url.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/url_1_7.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/aws/version.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/internal/context/background_go1.5.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/ast.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/comma_token.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/comment_token.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/doc.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/empty_token.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/expression.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/fuzz.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/ini.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/ini_lexer.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/ini_parser.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/literal_tokens.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/newline_token.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/number_helper.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/op_tokens.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/parse_error.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/parse_stack.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/sep_tokens.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/skipper.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/statement.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/value_util.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/visitor.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/walker.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/internal/ini/ws_token.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/internal/sdkio/byte.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/internal/sdkio/io_go1.6.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/internal/sdkio/io_go1.7.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/internal/sdkmath/floor.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/internal/sdkmath/floor_go1.9.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/internal/sdkrand/locked_source.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/internal/sdkrand/read.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/internal/sdkrand/read_1_5.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/internal/sdkuri/path.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/internal/shareddefaults/ecs_container.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/internal/shareddefaults/shared_config.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/internal/shareddefaults/shared_config_resolve_home.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/internal/shareddefaults/shared_config_resolve_home_go1.12.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/internal/strings/strings.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/internal/sync/singleflight/LICENSE delete mode 100644 vendor/github.com/aws/aws-sdk-go/internal/sync/singleflight/singleflight.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/host.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/host_prefix.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/idempotency.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil/build.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil/unmarshal.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/jsonrpc/jsonrpc.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/jsonrpc/unmarshal_error.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/jsonvalue.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/payload.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/protocol.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/query/build.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/query/queryutil/queryutil.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/query/unmarshal.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/query/unmarshal_error.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/rest/build.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/rest/payload.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/rest/unmarshal.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/restjson/restjson.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/restjson/unmarshal_error.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/restxml/restxml.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/timestamp.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/unmarshal.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/unmarshal_error.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/build.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/sort.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/unmarshal.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/xml_to_struct.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/service/route53/api.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/service/route53/customizations.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/service/route53/doc.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/service/route53/errors.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/service/route53/route53iface/interface.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/service/route53/service.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/service/route53/unmarshal_error.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/service/route53/waiters.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/service/sso/api.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/service/sso/doc.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/service/sso/errors.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/service/sso/service.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/service/sso/ssoiface/interface.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/service/ssooidc/api.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/service/ssooidc/doc.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/service/ssooidc/errors.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/service/ssooidc/service.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/service/sts/api.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/service/sts/customizations.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/service/sts/doc.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/service/sts/errors.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/service/sts/service.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/service/sts/stsiface/interface.go delete mode 100644 vendor/github.com/aws/smithy-go/.gitignore delete mode 100644 vendor/github.com/aws/smithy-go/.travis.yml delete mode 100644 vendor/github.com/aws/smithy-go/CHANGELOG.md delete mode 100644 vendor/github.com/aws/smithy-go/CODE_OF_CONDUCT.md delete mode 100644 vendor/github.com/aws/smithy-go/CONTRIBUTING.md delete mode 100644 vendor/github.com/aws/smithy-go/LICENSE delete mode 100644 vendor/github.com/aws/smithy-go/Makefile delete mode 100644 vendor/github.com/aws/smithy-go/NOTICE delete mode 100644 vendor/github.com/aws/smithy-go/README.md delete mode 100644 vendor/github.com/aws/smithy-go/auth/auth.go delete mode 100644 vendor/github.com/aws/smithy-go/auth/bearer/docs.go delete mode 100644 vendor/github.com/aws/smithy-go/auth/bearer/middleware.go delete mode 100644 vendor/github.com/aws/smithy-go/auth/bearer/token.go delete mode 100644 vendor/github.com/aws/smithy-go/auth/bearer/token_cache.go delete mode 100644 vendor/github.com/aws/smithy-go/auth/identity.go delete mode 100644 vendor/github.com/aws/smithy-go/auth/option.go delete mode 100644 vendor/github.com/aws/smithy-go/auth/scheme_id.go delete mode 100644 vendor/github.com/aws/smithy-go/changelog-template.json delete mode 100644 vendor/github.com/aws/smithy-go/context/suppress_expired.go delete mode 100644 vendor/github.com/aws/smithy-go/doc.go delete mode 100644 vendor/github.com/aws/smithy-go/document.go delete mode 100644 vendor/github.com/aws/smithy-go/document/doc.go delete mode 100644 vendor/github.com/aws/smithy-go/document/document.go delete mode 100644 vendor/github.com/aws/smithy-go/document/errors.go delete mode 100644 vendor/github.com/aws/smithy-go/encoding/doc.go delete mode 100644 vendor/github.com/aws/smithy-go/encoding/encoding.go delete mode 100644 vendor/github.com/aws/smithy-go/encoding/httpbinding/encode.go delete mode 100644 vendor/github.com/aws/smithy-go/encoding/httpbinding/header.go delete mode 100644 vendor/github.com/aws/smithy-go/encoding/httpbinding/path_replace.go delete mode 100644 vendor/github.com/aws/smithy-go/encoding/httpbinding/query.go delete mode 100644 vendor/github.com/aws/smithy-go/encoding/httpbinding/uri.go delete mode 100644 vendor/github.com/aws/smithy-go/encoding/json/array.go delete mode 100644 vendor/github.com/aws/smithy-go/encoding/json/constants.go delete mode 100644 vendor/github.com/aws/smithy-go/encoding/json/decoder_util.go delete mode 100644 vendor/github.com/aws/smithy-go/encoding/json/encoder.go delete mode 100644 vendor/github.com/aws/smithy-go/encoding/json/escape.go delete mode 100644 vendor/github.com/aws/smithy-go/encoding/json/object.go delete mode 100644 vendor/github.com/aws/smithy-go/encoding/json/value.go delete mode 100644 vendor/github.com/aws/smithy-go/encoding/xml/array.go delete mode 100644 vendor/github.com/aws/smithy-go/encoding/xml/constants.go delete mode 100644 vendor/github.com/aws/smithy-go/encoding/xml/doc.go delete mode 100644 vendor/github.com/aws/smithy-go/encoding/xml/element.go delete mode 100644 vendor/github.com/aws/smithy-go/encoding/xml/encoder.go delete mode 100644 vendor/github.com/aws/smithy-go/encoding/xml/error_utils.go delete mode 100644 vendor/github.com/aws/smithy-go/encoding/xml/escape.go delete mode 100644 vendor/github.com/aws/smithy-go/encoding/xml/map.go delete mode 100644 vendor/github.com/aws/smithy-go/encoding/xml/value.go delete mode 100644 vendor/github.com/aws/smithy-go/encoding/xml/xml_decoder.go delete mode 100644 vendor/github.com/aws/smithy-go/endpoints/endpoint.go delete mode 100644 vendor/github.com/aws/smithy-go/errors.go delete mode 100644 vendor/github.com/aws/smithy-go/go_module_metadata.go delete mode 100644 vendor/github.com/aws/smithy-go/internal/sync/singleflight/LICENSE delete mode 100644 vendor/github.com/aws/smithy-go/internal/sync/singleflight/docs.go delete mode 100644 vendor/github.com/aws/smithy-go/internal/sync/singleflight/singleflight.go delete mode 100644 vendor/github.com/aws/smithy-go/io/byte.go delete mode 100644 vendor/github.com/aws/smithy-go/io/doc.go delete mode 100644 vendor/github.com/aws/smithy-go/io/reader.go delete mode 100644 vendor/github.com/aws/smithy-go/io/ringbuffer.go delete mode 100644 vendor/github.com/aws/smithy-go/local-mod-replace.sh delete mode 100644 vendor/github.com/aws/smithy-go/logging/logger.go delete mode 100644 vendor/github.com/aws/smithy-go/metrics/metrics.go delete mode 100644 vendor/github.com/aws/smithy-go/metrics/nop.go delete mode 100644 vendor/github.com/aws/smithy-go/middleware/context.go delete mode 100644 vendor/github.com/aws/smithy-go/middleware/doc.go delete mode 100644 vendor/github.com/aws/smithy-go/middleware/logging.go delete mode 100644 vendor/github.com/aws/smithy-go/middleware/metadata.go delete mode 100644 vendor/github.com/aws/smithy-go/middleware/middleware.go delete mode 100644 vendor/github.com/aws/smithy-go/middleware/ordered_group.go delete mode 100644 vendor/github.com/aws/smithy-go/middleware/stack.go delete mode 100644 vendor/github.com/aws/smithy-go/middleware/stack_values.go delete mode 100644 vendor/github.com/aws/smithy-go/middleware/step_build.go delete mode 100644 vendor/github.com/aws/smithy-go/middleware/step_deserialize.go delete mode 100644 vendor/github.com/aws/smithy-go/middleware/step_finalize.go delete mode 100644 vendor/github.com/aws/smithy-go/middleware/step_initialize.go delete mode 100644 vendor/github.com/aws/smithy-go/middleware/step_serialize.go delete mode 100644 vendor/github.com/aws/smithy-go/modman.toml delete mode 100644 vendor/github.com/aws/smithy-go/private/requestcompression/gzip.go delete mode 100644 vendor/github.com/aws/smithy-go/private/requestcompression/middleware_capture_request_compression.go delete mode 100644 vendor/github.com/aws/smithy-go/private/requestcompression/request_compression.go delete mode 100644 vendor/github.com/aws/smithy-go/properties.go delete mode 100644 vendor/github.com/aws/smithy-go/ptr/doc.go delete mode 100644 vendor/github.com/aws/smithy-go/ptr/from_ptr.go delete mode 100644 vendor/github.com/aws/smithy-go/ptr/gen_scalars.go delete mode 100644 vendor/github.com/aws/smithy-go/ptr/to_ptr.go delete mode 100644 vendor/github.com/aws/smithy-go/rand/doc.go delete mode 100644 vendor/github.com/aws/smithy-go/rand/rand.go delete mode 100644 vendor/github.com/aws/smithy-go/rand/uuid.go delete mode 100644 vendor/github.com/aws/smithy-go/time/time.go delete mode 100644 vendor/github.com/aws/smithy-go/tracing/context.go delete mode 100644 vendor/github.com/aws/smithy-go/tracing/nop.go delete mode 100644 vendor/github.com/aws/smithy-go/tracing/tracing.go delete mode 100644 vendor/github.com/aws/smithy-go/transport/http/auth.go delete mode 100644 vendor/github.com/aws/smithy-go/transport/http/auth_schemes.go delete mode 100644 vendor/github.com/aws/smithy-go/transport/http/checksum_middleware.go delete mode 100644 vendor/github.com/aws/smithy-go/transport/http/client.go delete mode 100644 vendor/github.com/aws/smithy-go/transport/http/doc.go delete mode 100644 vendor/github.com/aws/smithy-go/transport/http/headerlist.go delete mode 100644 vendor/github.com/aws/smithy-go/transport/http/host.go delete mode 100644 vendor/github.com/aws/smithy-go/transport/http/internal/io/safe.go delete mode 100644 vendor/github.com/aws/smithy-go/transport/http/md5_checksum.go delete mode 100644 vendor/github.com/aws/smithy-go/transport/http/metrics.go delete mode 100644 vendor/github.com/aws/smithy-go/transport/http/middleware_close_response_body.go delete mode 100644 vendor/github.com/aws/smithy-go/transport/http/middleware_content_length.go delete mode 100644 vendor/github.com/aws/smithy-go/transport/http/middleware_header_comment.go delete mode 100644 vendor/github.com/aws/smithy-go/transport/http/middleware_headers.go delete mode 100644 vendor/github.com/aws/smithy-go/transport/http/middleware_http_logging.go delete mode 100644 vendor/github.com/aws/smithy-go/transport/http/middleware_metadata.go delete mode 100644 vendor/github.com/aws/smithy-go/transport/http/middleware_min_proto.go delete mode 100644 vendor/github.com/aws/smithy-go/transport/http/properties.go delete mode 100644 vendor/github.com/aws/smithy-go/transport/http/request.go delete mode 100644 vendor/github.com/aws/smithy-go/transport/http/response.go delete mode 100644 vendor/github.com/aws/smithy-go/transport/http/time.go delete mode 100644 vendor/github.com/aws/smithy-go/transport/http/url.go delete mode 100644 vendor/github.com/aws/smithy-go/transport/http/user_agent.go delete mode 100644 vendor/github.com/aws/smithy-go/validation.go delete mode 100644 vendor/github.com/cihub/seelog/LICENSE.txt delete mode 100644 vendor/github.com/cihub/seelog/README.markdown delete mode 100644 vendor/github.com/cihub/seelog/archive/archive.go delete mode 100644 vendor/github.com/cihub/seelog/archive/gzip/gzip.go delete mode 100644 vendor/github.com/cihub/seelog/archive/tar/tar.go delete mode 100644 vendor/github.com/cihub/seelog/archive/zip/zip.go delete mode 100644 vendor/github.com/cihub/seelog/behavior_adaptivelogger.go delete mode 100644 vendor/github.com/cihub/seelog/behavior_asynclogger.go delete mode 100644 vendor/github.com/cihub/seelog/behavior_asynclooplogger.go delete mode 100644 vendor/github.com/cihub/seelog/behavior_asynctimerlogger.go delete mode 100644 vendor/github.com/cihub/seelog/behavior_synclogger.go delete mode 100644 vendor/github.com/cihub/seelog/cfg_config.go delete mode 100644 vendor/github.com/cihub/seelog/cfg_errors.go delete mode 100644 vendor/github.com/cihub/seelog/cfg_logconfig.go delete mode 100644 vendor/github.com/cihub/seelog/cfg_parser.go delete mode 100644 vendor/github.com/cihub/seelog/common_closer.go delete mode 100644 vendor/github.com/cihub/seelog/common_constraints.go delete mode 100644 vendor/github.com/cihub/seelog/common_context.go delete mode 100644 vendor/github.com/cihub/seelog/common_exception.go delete mode 100644 vendor/github.com/cihub/seelog/common_flusher.go delete mode 100644 vendor/github.com/cihub/seelog/common_loglevel.go delete mode 100644 vendor/github.com/cihub/seelog/dispatch_custom.go delete mode 100644 vendor/github.com/cihub/seelog/dispatch_dispatcher.go delete mode 100644 vendor/github.com/cihub/seelog/dispatch_filterdispatcher.go delete mode 100644 vendor/github.com/cihub/seelog/dispatch_splitdispatcher.go delete mode 100644 vendor/github.com/cihub/seelog/doc.go delete mode 100644 vendor/github.com/cihub/seelog/format.go delete mode 100644 vendor/github.com/cihub/seelog/internals_baseerror.go delete mode 100644 vendor/github.com/cihub/seelog/internals_fsutils.go delete mode 100644 vendor/github.com/cihub/seelog/internals_xmlnode.go delete mode 100644 vendor/github.com/cihub/seelog/log.go delete mode 100644 vendor/github.com/cihub/seelog/logger.go delete mode 100644 vendor/github.com/cihub/seelog/writers_bufferedwriter.go delete mode 100644 vendor/github.com/cihub/seelog/writers_connwriter.go delete mode 100644 vendor/github.com/cihub/seelog/writers_consolewriter.go delete mode 100644 vendor/github.com/cihub/seelog/writers_filewriter.go delete mode 100644 vendor/github.com/cihub/seelog/writers_formattedwriter.go delete mode 100644 vendor/github.com/cihub/seelog/writers_rollingfilewriter.go delete mode 100644 vendor/github.com/cihub/seelog/writers_smtpwriter.go delete mode 100644 vendor/github.com/coredns/caddy/.gitattributes delete mode 100644 vendor/github.com/coredns/caddy/.gitignore delete mode 100644 vendor/github.com/coredns/caddy/LICENSE.txt delete mode 100644 vendor/github.com/coredns/caddy/README.md delete mode 100644 vendor/github.com/coredns/caddy/assets.go delete mode 100644 vendor/github.com/coredns/caddy/caddy.go delete mode 100644 vendor/github.com/coredns/caddy/caddyfile/dispenser.go delete mode 100644 vendor/github.com/coredns/caddy/caddyfile/json.go delete mode 100644 vendor/github.com/coredns/caddy/caddyfile/lexer.go delete mode 100644 vendor/github.com/coredns/caddy/caddyfile/parse.go delete mode 100644 vendor/github.com/coredns/caddy/commands.go delete mode 100644 vendor/github.com/coredns/caddy/controller.go delete mode 100644 vendor/github.com/coredns/caddy/onevent/hook/config.go delete mode 100644 vendor/github.com/coredns/caddy/onevent/hook/hook.go delete mode 100644 vendor/github.com/coredns/caddy/onevent/on.go delete mode 100644 vendor/github.com/coredns/caddy/plugins.go delete mode 100644 vendor/github.com/coredns/caddy/rlimit_nonposix.go delete mode 100644 vendor/github.com/coredns/caddy/rlimit_posix.go delete mode 100644 vendor/github.com/coredns/caddy/sigtrap.go delete mode 100644 vendor/github.com/coredns/caddy/sigtrap_nonposix.go delete mode 100644 vendor/github.com/coredns/caddy/sigtrap_posix.go delete mode 100644 vendor/github.com/coredns/caddy/upgrade.go delete mode 100644 vendor/github.com/coredns/coredns/LICENSE delete mode 100644 vendor/github.com/coredns/coredns/core/dnsserver/address.go delete mode 100644 vendor/github.com/coredns/coredns/core/dnsserver/config.go delete mode 100644 vendor/github.com/coredns/coredns/core/dnsserver/https.go delete mode 100644 vendor/github.com/coredns/coredns/core/dnsserver/onstartup.go delete mode 100644 vendor/github.com/coredns/coredns/core/dnsserver/quic.go delete mode 100644 vendor/github.com/coredns/coredns/core/dnsserver/register.go delete mode 100644 vendor/github.com/coredns/coredns/core/dnsserver/server.go delete mode 100644 vendor/github.com/coredns/coredns/core/dnsserver/server_grpc.go delete mode 100644 vendor/github.com/coredns/coredns/core/dnsserver/server_https.go delete mode 100644 vendor/github.com/coredns/coredns/core/dnsserver/server_quic.go delete mode 100644 vendor/github.com/coredns/coredns/core/dnsserver/server_tls.go delete mode 100644 vendor/github.com/coredns/coredns/core/dnsserver/view.go delete mode 100644 vendor/github.com/coredns/coredns/core/dnsserver/zdirectives.go delete mode 100644 vendor/github.com/coredns/coredns/core/plugin/zplugin.go delete mode 100644 vendor/github.com/coredns/coredns/coremain/run.go delete mode 100644 vendor/github.com/coredns/coredns/coremain/version.go delete mode 100644 vendor/github.com/coredns/coredns/pb/Makefile delete mode 100644 vendor/github.com/coredns/coredns/pb/dns.pb.go delete mode 100644 vendor/github.com/coredns/coredns/pb/dns.proto delete mode 100644 vendor/github.com/coredns/coredns/pb/dns_grpc.pb.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/acl/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/acl/acl.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/acl/metrics.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/acl/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/any/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/any/any.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/any/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/auto/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/auto/auto.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/auto/regexp.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/auto/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/auto/walk.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/auto/xfr.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/auto/zone.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/autopath/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/autopath/autopath.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/autopath/cname.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/autopath/metrics.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/autopath/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/azure/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/azure/azure.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/azure/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/backend.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/backend_lookup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/bind/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/bind/bind.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/bind/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/bufsize/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/bufsize/bufsize.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/bufsize/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/cache/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/cache/cache.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/cache/dnssec.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/cache/freq/freq.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/cache/fuzz.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/cache/handler.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/cache/item.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/cache/metrics.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/cache/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/cancel/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/cancel/cancel.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/chaos/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/chaos/chaos.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/chaos/fuzz.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/chaos/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/chaos/zowners.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/clouddns/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/clouddns/clouddns.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/clouddns/gcp.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/clouddns/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/debug/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/debug/debug.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/debug/pcap.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/dns64/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/dns64/dns64.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/dns64/metrics.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/dns64/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/dnssec/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/dnssec/black_lies.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/dnssec/cache.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/dnssec/dnskey.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/dnssec/dnssec.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/dnssec/handler.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/dnssec/metrics.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/dnssec/responsewriter.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/dnssec/rrsig.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/dnssec/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/dnstap/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/dnstap/encoder.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/dnstap/handler.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/dnstap/io.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/dnstap/msg/msg.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/dnstap/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/dnstap/writer.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/done.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/erratic/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/erratic/autopath.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/erratic/erratic.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/erratic/ready.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/erratic/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/erratic/xfr.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/errors/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/errors/errors.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/errors/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/etcd/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/etcd/etcd.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/etcd/handler.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/etcd/msg/path.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/etcd/msg/service.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/etcd/msg/type.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/etcd/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/etcd/xfr.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/file/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/file/closest.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/file/dname.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/file/example_org.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/file/file.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/file/fuzz.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/file/lookup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/file/notify.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/file/reload.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/file/rrutil/util.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/file/secondary.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/file/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/file/shutdown.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/file/tree/all.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/file/tree/auth_walk.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/file/tree/elem.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/file/tree/glue.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/file/tree/less.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/file/tree/print.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/file/tree/tree.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/file/tree/walk.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/file/wildcard.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/file/xfr.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/file/zone.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/forward/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/forward/dnstap.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/forward/forward.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/forward/fuzz.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/forward/metrics.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/forward/policy.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/forward/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/geoip/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/geoip/city.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/geoip/geoip.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/geoip/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/grpc/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/grpc/grpc.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/grpc/metrics.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/grpc/policy.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/grpc/proxy.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/grpc/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/header/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/header/handler.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/header/header.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/header/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/health/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/health/health.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/health/overloaded.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/health/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/hosts/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/hosts/hosts.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/hosts/hostsfile.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/hosts/metrics.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/hosts/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/k8s_external/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/k8s_external/apex.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/k8s_external/external.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/k8s_external/msg_to_dns.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/k8s_external/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/k8s_external/transfer.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/kubernetes/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/kubernetes/autopath.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/kubernetes/controller.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/kubernetes/external.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/kubernetes/handler.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/kubernetes/kubernetes.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/kubernetes/local.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/kubernetes/logger.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/kubernetes/metadata.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/kubernetes/metrics.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/kubernetes/metrics_test.backup delete mode 100644 vendor/github.com/coredns/coredns/plugin/kubernetes/namespace.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/kubernetes/ns.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/kubernetes/object/endpoint.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/kubernetes/object/informer.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/kubernetes/object/metrics.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/kubernetes/object/namespace.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/kubernetes/object/object.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/kubernetes/object/pod.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/kubernetes/object/service.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/kubernetes/parse.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/kubernetes/ready.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/kubernetes/reverse.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/kubernetes/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/kubernetes/xfr.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/loadbalance/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/loadbalance/handler.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/loadbalance/loadbalance.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/loadbalance/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/loadbalance/weighted.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/local/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/local/local.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/local/metrics.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/local/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/log/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/log/log.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/log/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/loop/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/loop/loop.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/loop/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/metadata/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/metadata/metadata.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/metadata/provider.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/metadata/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/metrics/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/metrics/context.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/metrics/handler.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/metrics/metrics.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/metrics/recorder.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/metrics/registry.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/metrics/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/metrics/vars/monitor.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/metrics/vars/report.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/metrics/vars/vars.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/minimal/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/minimal/minimal.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/minimal/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/multisocket/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/multisocket/multisocket.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/normalize.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/nsid/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/nsid/nsid.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/nsid/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/cache/cache.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/cidr/cidr.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/dnstest/multirecorder.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/dnstest/recorder.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/dnstest/server.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/dnsutil/cname.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/dnsutil/doc.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/dnsutil/join.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/dnsutil/reverse.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/dnsutil/ttl.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/dnsutil/zone.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/doh/doh.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/durations/durations.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/edns/edns.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/expression/expression.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/fall/fall.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/fuzz/do.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/log/listener.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/log/log.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/log/plugin.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/nonwriter/nonwriter.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/parse/host.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/parse/parse.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/parse/transport.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/proxy/connect.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/proxy/errors.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/proxy/health.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/proxy/metrics.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/proxy/persistent.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/proxy/proxy.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/proxy/type.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/rand/rand.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/rcode/rcode.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/replacer/replacer.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/response/classify.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/response/typify.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/reuseport/listen_no_reuseport.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/reuseport/listen_reuseport.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/singleflight/singleflight.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/tls/tls.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/trace/trace.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/transport/transport.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/uniq/uniq.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/up/up.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pkg/upstream/upstream.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/plugin.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pprof/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/pprof/pprof.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/pprof/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/ready/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/ready/list.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/ready/readiness.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/ready/ready.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/ready/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/register.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/reload/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/reload/metrics.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/reload/reload.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/reload/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/rewrite/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/rewrite/class.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/rewrite/cname_target.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/rewrite/edns0.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/rewrite/fuzz.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/rewrite/name.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/rewrite/rcode.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/rewrite/reverter.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/rewrite/rewrite.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/rewrite/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/rewrite/ttl.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/rewrite/type.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/rewrite/wire.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/root/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/root/root.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/route53/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/route53/route53.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/route53/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/secondary/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/secondary/secondary.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/secondary/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/sign/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/sign/dnssec.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/sign/file.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/sign/keys.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/sign/nsec.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/sign/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/sign/sign.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/sign/signer.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/template/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/template/metrics.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/template/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/template/template.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/test/doc.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/test/file.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/test/helpers.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/test/responsewriter.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/test/scrape.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/timeouts/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/timeouts/timeouts.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/tls/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/tls/test_ca.pem delete mode 100644 vendor/github.com/coredns/coredns/plugin/tls/test_cert.pem delete mode 100644 vendor/github.com/coredns/coredns/plugin/tls/test_key.pem delete mode 100644 vendor/github.com/coredns/coredns/plugin/tls/tls.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/trace/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/trace/logger.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/trace/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/trace/trace.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/transfer/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/transfer/notify.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/transfer/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/transfer/transfer.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/tsig/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/tsig/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/tsig/tsig.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/view/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/view/metadata.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/view/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/view/view.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/whoami/README.md delete mode 100644 vendor/github.com/coredns/coredns/plugin/whoami/fuzz.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/whoami/setup.go delete mode 100644 vendor/github.com/coredns/coredns/plugin/whoami/whoami.go delete mode 100644 vendor/github.com/coredns/coredns/request/edns0.go delete mode 100644 vendor/github.com/coredns/coredns/request/request.go delete mode 100644 vendor/github.com/coredns/coredns/request/writer.go delete mode 100644 vendor/github.com/coreos/go-semver/LICENSE delete mode 100644 vendor/github.com/coreos/go-semver/NOTICE delete mode 100644 vendor/github.com/coreos/go-semver/semver/semver.go delete mode 100644 vendor/github.com/coreos/go-semver/semver/sort.go delete mode 100644 vendor/github.com/coreos/go-systemd/v22/LICENSE delete mode 100644 vendor/github.com/coreos/go-systemd/v22/NOTICE delete mode 100644 vendor/github.com/coreos/go-systemd/v22/journal/journal.go delete mode 100644 vendor/github.com/coreos/go-systemd/v22/journal/journal_unix.go delete mode 100644 vendor/github.com/coreos/go-systemd/v22/journal/journal_windows.go delete mode 100644 vendor/github.com/dimchansky/utfbom/.gitignore delete mode 100644 vendor/github.com/dimchansky/utfbom/.travis.yml delete mode 100644 vendor/github.com/dimchansky/utfbom/LICENSE delete mode 100644 vendor/github.com/dimchansky/utfbom/README.md delete mode 100644 vendor/github.com/dimchansky/utfbom/utfbom.go delete mode 100644 vendor/github.com/dnstap/golang-dnstap/.gitignore delete mode 100644 vendor/github.com/dnstap/golang-dnstap/COPYRIGHT delete mode 100644 vendor/github.com/dnstap/golang-dnstap/Decoder.go delete mode 100644 vendor/github.com/dnstap/golang-dnstap/Encoder.go delete mode 100644 vendor/github.com/dnstap/golang-dnstap/FrameStreamInput.go delete mode 100644 vendor/github.com/dnstap/golang-dnstap/FrameStreamOutput.go delete mode 100644 vendor/github.com/dnstap/golang-dnstap/FrameStreamSockInput.go delete mode 100644 vendor/github.com/dnstap/golang-dnstap/FrameStreamSockOutput.go delete mode 100644 vendor/github.com/dnstap/golang-dnstap/JsonFormat.go delete mode 100644 vendor/github.com/dnstap/golang-dnstap/LICENSE delete mode 100644 vendor/github.com/dnstap/golang-dnstap/QuietTextFormat.go delete mode 100644 vendor/github.com/dnstap/golang-dnstap/README delete mode 100644 vendor/github.com/dnstap/golang-dnstap/Reader.go delete mode 100644 vendor/github.com/dnstap/golang-dnstap/SocketWriter.go delete mode 100644 vendor/github.com/dnstap/golang-dnstap/TextOutput.go delete mode 100644 vendor/github.com/dnstap/golang-dnstap/Writer.go delete mode 100644 vendor/github.com/dnstap/golang-dnstap/YamlFormat.go delete mode 100644 vendor/github.com/dnstap/golang-dnstap/dnstap.go delete mode 100644 vendor/github.com/dnstap/golang-dnstap/dnstap.pb.go delete mode 100644 vendor/github.com/dnstap/golang-dnstap/genproto.sh delete mode 100644 vendor/github.com/dustin/go-humanize/.travis.yml delete mode 100644 vendor/github.com/dustin/go-humanize/LICENSE delete mode 100644 vendor/github.com/dustin/go-humanize/README.markdown delete mode 100644 vendor/github.com/dustin/go-humanize/big.go delete mode 100644 vendor/github.com/dustin/go-humanize/bigbytes.go delete mode 100644 vendor/github.com/dustin/go-humanize/bytes.go delete mode 100644 vendor/github.com/dustin/go-humanize/comma.go delete mode 100644 vendor/github.com/dustin/go-humanize/commaf.go delete mode 100644 vendor/github.com/dustin/go-humanize/ftoa.go delete mode 100644 vendor/github.com/dustin/go-humanize/humanize.go delete mode 100644 vendor/github.com/dustin/go-humanize/number.go delete mode 100644 vendor/github.com/dustin/go-humanize/ordinals.go delete mode 100644 vendor/github.com/dustin/go-humanize/si.go delete mode 100644 vendor/github.com/dustin/go-humanize/times.go delete mode 100644 vendor/github.com/eapache/queue/v2/LICENSE delete mode 100644 vendor/github.com/eapache/queue/v2/queue.go delete mode 100644 vendor/github.com/expr-lang/expr/.gitattributes delete mode 100644 vendor/github.com/expr-lang/expr/.gitignore delete mode 100644 vendor/github.com/expr-lang/expr/LICENSE delete mode 100644 vendor/github.com/expr-lang/expr/README.md delete mode 100644 vendor/github.com/expr-lang/expr/SECURITY.md delete mode 100644 vendor/github.com/expr-lang/expr/ast/dump.go delete mode 100644 vendor/github.com/expr-lang/expr/ast/find.go delete mode 100644 vendor/github.com/expr-lang/expr/ast/node.go delete mode 100644 vendor/github.com/expr-lang/expr/ast/print.go delete mode 100644 vendor/github.com/expr-lang/expr/ast/visitor.go delete mode 100644 vendor/github.com/expr-lang/expr/builtin/builtin.go delete mode 100644 vendor/github.com/expr-lang/expr/builtin/function.go delete mode 100644 vendor/github.com/expr-lang/expr/builtin/lib.go delete mode 100644 vendor/github.com/expr-lang/expr/builtin/utils.go delete mode 100644 vendor/github.com/expr-lang/expr/builtin/validation.go delete mode 100644 vendor/github.com/expr-lang/expr/checker/checker.go delete mode 100644 vendor/github.com/expr-lang/expr/checker/info.go delete mode 100644 vendor/github.com/expr-lang/expr/checker/nature/nature.go delete mode 100644 vendor/github.com/expr-lang/expr/checker/nature/utils.go delete mode 100644 vendor/github.com/expr-lang/expr/checker/types.go delete mode 100644 vendor/github.com/expr-lang/expr/compiler/compiler.go delete mode 100644 vendor/github.com/expr-lang/expr/conf/config.go delete mode 100644 vendor/github.com/expr-lang/expr/conf/env.go delete mode 100644 vendor/github.com/expr-lang/expr/expr.go delete mode 100644 vendor/github.com/expr-lang/expr/file/error.go delete mode 100644 vendor/github.com/expr-lang/expr/file/location.go delete mode 100644 vendor/github.com/expr-lang/expr/file/source.go delete mode 100644 vendor/github.com/expr-lang/expr/internal/deref/deref.go delete mode 100644 vendor/github.com/expr-lang/expr/optimizer/const_expr.go delete mode 100644 vendor/github.com/expr-lang/expr/optimizer/filter_first.go delete mode 100644 vendor/github.com/expr-lang/expr/optimizer/filter_last.go delete mode 100644 vendor/github.com/expr-lang/expr/optimizer/filter_len.go delete mode 100644 vendor/github.com/expr-lang/expr/optimizer/filter_map.go delete mode 100644 vendor/github.com/expr-lang/expr/optimizer/fold.go delete mode 100644 vendor/github.com/expr-lang/expr/optimizer/in_array.go delete mode 100644 vendor/github.com/expr-lang/expr/optimizer/in_range.go delete mode 100644 vendor/github.com/expr-lang/expr/optimizer/optimizer.go delete mode 100644 vendor/github.com/expr-lang/expr/optimizer/predicate_combination.go delete mode 100644 vendor/github.com/expr-lang/expr/optimizer/sum_array.go delete mode 100644 vendor/github.com/expr-lang/expr/optimizer/sum_map.go delete mode 100644 vendor/github.com/expr-lang/expr/parser/lexer/lexer.go delete mode 100644 vendor/github.com/expr-lang/expr/parser/lexer/state.go delete mode 100644 vendor/github.com/expr-lang/expr/parser/lexer/token.go delete mode 100644 vendor/github.com/expr-lang/expr/parser/lexer/utils.go delete mode 100644 vendor/github.com/expr-lang/expr/parser/operator/operator.go delete mode 100644 vendor/github.com/expr-lang/expr/parser/parser.go delete mode 100644 vendor/github.com/expr-lang/expr/parser/utils/utils.go delete mode 100644 vendor/github.com/expr-lang/expr/patcher/operator_override.go delete mode 100644 vendor/github.com/expr-lang/expr/patcher/with_context.go delete mode 100644 vendor/github.com/expr-lang/expr/patcher/with_timezone.go delete mode 100644 vendor/github.com/expr-lang/expr/types/types.go delete mode 100644 vendor/github.com/expr-lang/expr/vm/debug.go delete mode 100644 vendor/github.com/expr-lang/expr/vm/debug_off.go delete mode 100644 vendor/github.com/expr-lang/expr/vm/func_types[generated].go delete mode 100644 vendor/github.com/expr-lang/expr/vm/opcodes.go delete mode 100644 vendor/github.com/expr-lang/expr/vm/program.go delete mode 100644 vendor/github.com/expr-lang/expr/vm/runtime/helpers[generated].go delete mode 100644 vendor/github.com/expr-lang/expr/vm/runtime/runtime.go delete mode 100644 vendor/github.com/expr-lang/expr/vm/runtime/sort.go delete mode 100644 vendor/github.com/expr-lang/expr/vm/utils.go delete mode 100644 vendor/github.com/expr-lang/expr/vm/vm.go delete mode 100644 vendor/github.com/farsightsec/golang-framestream/.gitignore delete mode 100644 vendor/github.com/farsightsec/golang-framestream/COPYRIGHT delete mode 100644 vendor/github.com/farsightsec/golang-framestream/Control.go delete mode 100644 vendor/github.com/farsightsec/golang-framestream/Decoder.go delete mode 100644 vendor/github.com/farsightsec/golang-framestream/Encoder.go delete mode 100644 vendor/github.com/farsightsec/golang-framestream/LICENSE delete mode 100644 vendor/github.com/farsightsec/golang-framestream/README.md delete mode 100644 vendor/github.com/farsightsec/golang-framestream/Reader.go delete mode 100644 vendor/github.com/farsightsec/golang-framestream/Writer.go delete mode 100644 vendor/github.com/farsightsec/golang-framestream/framestream.go delete mode 100644 vendor/github.com/farsightsec/golang-framestream/timeout.go delete mode 100644 vendor/github.com/flynn/go-shlex/COPYING delete mode 100644 vendor/github.com/flynn/go-shlex/Makefile delete mode 100644 vendor/github.com/flynn/go-shlex/README.md delete mode 100644 vendor/github.com/flynn/go-shlex/shlex.go delete mode 100644 vendor/github.com/gogo/protobuf/gogoproto/Makefile delete mode 100644 vendor/github.com/gogo/protobuf/gogoproto/doc.go delete mode 100644 vendor/github.com/gogo/protobuf/gogoproto/gogo.pb.go delete mode 100644 vendor/github.com/gogo/protobuf/gogoproto/gogo.pb.golden delete mode 100644 vendor/github.com/gogo/protobuf/gogoproto/gogo.proto delete mode 100644 vendor/github.com/gogo/protobuf/gogoproto/helper.go delete mode 100644 vendor/github.com/gogo/protobuf/jsonpb/jsonpb.go delete mode 100644 vendor/github.com/gogo/protobuf/protoc-gen-gogo/descriptor/Makefile delete mode 100644 vendor/github.com/gogo/protobuf/protoc-gen-gogo/descriptor/descriptor.go delete mode 100644 vendor/github.com/gogo/protobuf/protoc-gen-gogo/descriptor/descriptor.pb.go delete mode 100644 vendor/github.com/gogo/protobuf/protoc-gen-gogo/descriptor/descriptor_gostring.gen.go delete mode 100644 vendor/github.com/gogo/protobuf/protoc-gen-gogo/descriptor/helper.go delete mode 100644 vendor/github.com/gogo/protobuf/types/any.go delete mode 100644 vendor/github.com/gogo/protobuf/types/any.pb.go delete mode 100644 vendor/github.com/gogo/protobuf/types/api.pb.go delete mode 100644 vendor/github.com/gogo/protobuf/types/doc.go delete mode 100644 vendor/github.com/gogo/protobuf/types/duration.go delete mode 100644 vendor/github.com/gogo/protobuf/types/duration.pb.go delete mode 100644 vendor/github.com/gogo/protobuf/types/duration_gogo.go delete mode 100644 vendor/github.com/gogo/protobuf/types/empty.pb.go delete mode 100644 vendor/github.com/gogo/protobuf/types/field_mask.pb.go delete mode 100644 vendor/github.com/gogo/protobuf/types/protosize.go delete mode 100644 vendor/github.com/gogo/protobuf/types/source_context.pb.go delete mode 100644 vendor/github.com/gogo/protobuf/types/struct.pb.go delete mode 100644 vendor/github.com/gogo/protobuf/types/timestamp.go delete mode 100644 vendor/github.com/gogo/protobuf/types/timestamp.pb.go delete mode 100644 vendor/github.com/gogo/protobuf/types/timestamp_gogo.go delete mode 100644 vendor/github.com/gogo/protobuf/types/type.pb.go delete mode 100644 vendor/github.com/gogo/protobuf/types/wrappers.pb.go delete mode 100644 vendor/github.com/gogo/protobuf/types/wrappers_gogo.go delete mode 100644 vendor/github.com/golang-jwt/jwt/v4/.gitignore delete mode 100644 vendor/github.com/golang-jwt/jwt/v4/LICENSE delete mode 100644 vendor/github.com/golang-jwt/jwt/v4/MIGRATION_GUIDE.md delete mode 100644 vendor/github.com/golang-jwt/jwt/v4/README.md delete mode 100644 vendor/github.com/golang-jwt/jwt/v4/SECURITY.md delete mode 100644 vendor/github.com/golang-jwt/jwt/v4/VERSION_HISTORY.md delete mode 100644 vendor/github.com/golang-jwt/jwt/v4/claims.go delete mode 100644 vendor/github.com/golang-jwt/jwt/v4/doc.go delete mode 100644 vendor/github.com/golang-jwt/jwt/v4/ecdsa.go delete mode 100644 vendor/github.com/golang-jwt/jwt/v4/ecdsa_utils.go delete mode 100644 vendor/github.com/golang-jwt/jwt/v4/ed25519.go delete mode 100644 vendor/github.com/golang-jwt/jwt/v4/ed25519_utils.go delete mode 100644 vendor/github.com/golang-jwt/jwt/v4/errors.go delete mode 100644 vendor/github.com/golang-jwt/jwt/v4/hmac.go delete mode 100644 vendor/github.com/golang-jwt/jwt/v4/map_claims.go delete mode 100644 vendor/github.com/golang-jwt/jwt/v4/none.go delete mode 100644 vendor/github.com/golang-jwt/jwt/v4/parser.go delete mode 100644 vendor/github.com/golang-jwt/jwt/v4/parser_option.go delete mode 100644 vendor/github.com/golang-jwt/jwt/v4/rsa.go delete mode 100644 vendor/github.com/golang-jwt/jwt/v4/rsa_pss.go delete mode 100644 vendor/github.com/golang-jwt/jwt/v4/rsa_utils.go delete mode 100644 vendor/github.com/golang-jwt/jwt/v4/signing_method.go delete mode 100644 vendor/github.com/golang-jwt/jwt/v4/staticcheck.conf delete mode 100644 vendor/github.com/golang-jwt/jwt/v4/token.go delete mode 100644 vendor/github.com/golang-jwt/jwt/v4/types.go delete mode 100644 vendor/github.com/google/s2a-go/.gitignore delete mode 100644 vendor/github.com/google/s2a-go/CODE_OF_CONDUCT.md delete mode 100644 vendor/github.com/google/s2a-go/CONTRIBUTING.md delete mode 100644 vendor/github.com/google/s2a-go/LICENSE.md delete mode 100644 vendor/github.com/google/s2a-go/README.md delete mode 100644 vendor/github.com/google/s2a-go/fallback/s2a_fallback.go delete mode 100644 vendor/github.com/google/s2a-go/internal/authinfo/authinfo.go delete mode 100644 vendor/github.com/google/s2a-go/internal/handshaker/handshaker.go delete mode 100644 vendor/github.com/google/s2a-go/internal/handshaker/service/service.go delete mode 100644 vendor/github.com/google/s2a-go/internal/proto/common_go_proto/common.pb.go delete mode 100644 vendor/github.com/google/s2a-go/internal/proto/s2a_context_go_proto/s2a_context.pb.go delete mode 100644 vendor/github.com/google/s2a-go/internal/proto/s2a_go_proto/s2a.pb.go delete mode 100644 vendor/github.com/google/s2a-go/internal/proto/s2a_go_proto/s2a_grpc.pb.go delete mode 100644 vendor/github.com/google/s2a-go/internal/proto/v2/common_go_proto/common.pb.go delete mode 100644 vendor/github.com/google/s2a-go/internal/proto/v2/s2a_context_go_proto/s2a_context.pb.go delete mode 100644 vendor/github.com/google/s2a-go/internal/proto/v2/s2a_go_proto/s2a.pb.go delete mode 100644 vendor/github.com/google/s2a-go/internal/proto/v2/s2a_go_proto/s2a_grpc.pb.go delete mode 100644 vendor/github.com/google/s2a-go/internal/record/internal/aeadcrypter/aeadcrypter.go delete mode 100644 vendor/github.com/google/s2a-go/internal/record/internal/aeadcrypter/aesgcm.go delete mode 100644 vendor/github.com/google/s2a-go/internal/record/internal/aeadcrypter/chachapoly.go delete mode 100644 vendor/github.com/google/s2a-go/internal/record/internal/aeadcrypter/common.go delete mode 100644 vendor/github.com/google/s2a-go/internal/record/internal/halfconn/ciphersuite.go delete mode 100644 vendor/github.com/google/s2a-go/internal/record/internal/halfconn/counter.go delete mode 100644 vendor/github.com/google/s2a-go/internal/record/internal/halfconn/expander.go delete mode 100644 vendor/github.com/google/s2a-go/internal/record/internal/halfconn/halfconn.go delete mode 100644 vendor/github.com/google/s2a-go/internal/record/record.go delete mode 100644 vendor/github.com/google/s2a-go/internal/record/ticketsender.go delete mode 100644 vendor/github.com/google/s2a-go/internal/tokenmanager/tokenmanager.go delete mode 100644 vendor/github.com/google/s2a-go/internal/v2/README.md delete mode 100644 vendor/github.com/google/s2a-go/internal/v2/certverifier/certverifier.go delete mode 100644 vendor/github.com/google/s2a-go/internal/v2/remotesigner/remotesigner.go delete mode 100644 vendor/github.com/google/s2a-go/internal/v2/s2av2.go delete mode 100644 vendor/github.com/google/s2a-go/internal/v2/tlsconfigstore/tlsconfigstore.go delete mode 100644 vendor/github.com/google/s2a-go/retry/retry.go delete mode 100644 vendor/github.com/google/s2a-go/s2a.go delete mode 100644 vendor/github.com/google/s2a-go/s2a_options.go delete mode 100644 vendor/github.com/google/s2a-go/s2a_utils.go delete mode 100644 vendor/github.com/google/s2a-go/stream/s2a_stream.go delete mode 100644 vendor/github.com/googleapis/enterprise-certificate-proxy/LICENSE delete mode 100644 vendor/github.com/googleapis/enterprise-certificate-proxy/client/client.go delete mode 100644 vendor/github.com/googleapis/enterprise-certificate-proxy/client/util/util.go delete mode 100644 vendor/github.com/googleapis/gax-go/v2/.release-please-manifest.json delete mode 100644 vendor/github.com/googleapis/gax-go/v2/CHANGES.md delete mode 100644 vendor/github.com/googleapis/gax-go/v2/LICENSE delete mode 100644 vendor/github.com/googleapis/gax-go/v2/apierror/apierror.go delete mode 100644 vendor/github.com/googleapis/gax-go/v2/apierror/internal/proto/README.md delete mode 100644 vendor/github.com/googleapis/gax-go/v2/apierror/internal/proto/custom_error.pb.go delete mode 100644 vendor/github.com/googleapis/gax-go/v2/apierror/internal/proto/custom_error.proto delete mode 100644 vendor/github.com/googleapis/gax-go/v2/apierror/internal/proto/error.pb.go delete mode 100644 vendor/github.com/googleapis/gax-go/v2/apierror/internal/proto/error.proto delete mode 100644 vendor/github.com/googleapis/gax-go/v2/call_option.go delete mode 100644 vendor/github.com/googleapis/gax-go/v2/callctx/callctx.go delete mode 100644 vendor/github.com/googleapis/gax-go/v2/content_type.go delete mode 100644 vendor/github.com/googleapis/gax-go/v2/gax.go delete mode 100644 vendor/github.com/googleapis/gax-go/v2/header.go delete mode 100644 vendor/github.com/googleapis/gax-go/v2/internal/version.go delete mode 100644 vendor/github.com/googleapis/gax-go/v2/internallog/internal/internal.go delete mode 100644 vendor/github.com/googleapis/gax-go/v2/internallog/internallog.go delete mode 100644 vendor/github.com/googleapis/gax-go/v2/invoke.go delete mode 100644 vendor/github.com/googleapis/gax-go/v2/proto_json_stream.go delete mode 100644 vendor/github.com/googleapis/gax-go/v2/release-please-config.json delete mode 100644 vendor/github.com/grpc-ecosystem/grpc-opentracing/LICENSE delete mode 100644 vendor/github.com/grpc-ecosystem/grpc-opentracing/PATENTS delete mode 100644 vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/README.md delete mode 100644 vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/client.go delete mode 100644 vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/errors.go delete mode 100644 vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/options.go delete mode 100644 vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/package.go delete mode 100644 vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/server.go delete mode 100644 vendor/github.com/grpc-ecosystem/grpc-opentracing/go/otgrpc/shared.go delete mode 100644 vendor/github.com/hashicorp/go-secure-stdlib/parseutil/LICENSE delete mode 100644 vendor/github.com/hashicorp/go-secure-stdlib/parseutil/parsepath.go delete mode 100644 vendor/github.com/hashicorp/go-secure-stdlib/parseutil/parseutil.go delete mode 100644 vendor/github.com/hashicorp/go-secure-stdlib/strutil/LICENSE delete mode 100644 vendor/github.com/hashicorp/go-secure-stdlib/strutil/strutil.go delete mode 100644 vendor/github.com/hashicorp/go-sockaddr/.gitignore delete mode 100644 vendor/github.com/hashicorp/go-sockaddr/GNUmakefile delete mode 100644 vendor/github.com/hashicorp/go-sockaddr/LICENSE delete mode 100644 vendor/github.com/hashicorp/go-sockaddr/README.md delete mode 100644 vendor/github.com/hashicorp/go-sockaddr/doc.go delete mode 100644 vendor/github.com/hashicorp/go-sockaddr/ifaddr.go delete mode 100644 vendor/github.com/hashicorp/go-sockaddr/ifaddrs.go delete mode 100644 vendor/github.com/hashicorp/go-sockaddr/ifattr.go delete mode 100644 vendor/github.com/hashicorp/go-sockaddr/ipaddr.go delete mode 100644 vendor/github.com/hashicorp/go-sockaddr/ipaddrs.go delete mode 100644 vendor/github.com/hashicorp/go-sockaddr/ipv4addr.go delete mode 100644 vendor/github.com/hashicorp/go-sockaddr/ipv6addr.go delete mode 100644 vendor/github.com/hashicorp/go-sockaddr/rfc.go delete mode 100644 vendor/github.com/hashicorp/go-sockaddr/route_info.go delete mode 100644 vendor/github.com/hashicorp/go-sockaddr/route_info_android.go delete mode 100644 vendor/github.com/hashicorp/go-sockaddr/route_info_bsd.go delete mode 100644 vendor/github.com/hashicorp/go-sockaddr/route_info_default.go delete mode 100644 vendor/github.com/hashicorp/go-sockaddr/route_info_linux.go delete mode 100644 vendor/github.com/hashicorp/go-sockaddr/route_info_solaris.go delete mode 100644 vendor/github.com/hashicorp/go-sockaddr/route_info_windows.go delete mode 100644 vendor/github.com/hashicorp/go-sockaddr/sockaddr.go delete mode 100644 vendor/github.com/hashicorp/go-sockaddr/sockaddrs.go delete mode 100644 vendor/github.com/hashicorp/go-sockaddr/unixsock.go delete mode 100644 vendor/github.com/infobloxopen/go-trees/LICENSE delete mode 100644 vendor/github.com/infobloxopen/go-trees/iptree/iptree.go delete mode 100644 vendor/github.com/infobloxopen/go-trees/numtree/node32.go delete mode 100644 vendor/github.com/infobloxopen/go-trees/numtree/node64.go delete mode 100644 vendor/github.com/jmespath/go-jmespath/.gitignore delete mode 100644 vendor/github.com/jmespath/go-jmespath/.travis.yml delete mode 100644 vendor/github.com/jmespath/go-jmespath/LICENSE delete mode 100644 vendor/github.com/jmespath/go-jmespath/Makefile delete mode 100644 vendor/github.com/jmespath/go-jmespath/README.md delete mode 100644 vendor/github.com/jmespath/go-jmespath/api.go delete mode 100644 vendor/github.com/jmespath/go-jmespath/astnodetype_string.go delete mode 100644 vendor/github.com/jmespath/go-jmespath/functions.go delete mode 100644 vendor/github.com/jmespath/go-jmespath/interpreter.go delete mode 100644 vendor/github.com/jmespath/go-jmespath/lexer.go delete mode 100644 vendor/github.com/jmespath/go-jmespath/parser.go delete mode 100644 vendor/github.com/jmespath/go-jmespath/toktype_string.go delete mode 100644 vendor/github.com/jmespath/go-jmespath/util.go delete mode 100644 vendor/github.com/matttproud/golang_protobuf_extensions/LICENSE delete mode 100644 vendor/github.com/matttproud/golang_protobuf_extensions/NOTICE delete mode 100644 vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/.gitignore delete mode 100644 vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/Makefile delete mode 100644 vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/decode.go delete mode 100644 vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/doc.go delete mode 100644 vendor/github.com/matttproud/golang_protobuf_extensions/pbutil/encode.go delete mode 100644 vendor/github.com/mitchellh/go-homedir/LICENSE delete mode 100644 vendor/github.com/mitchellh/go-homedir/README.md delete mode 100644 vendor/github.com/mitchellh/go-homedir/homedir.go delete mode 100644 vendor/github.com/mitchellh/mapstructure/CHANGELOG.md delete mode 100644 vendor/github.com/mitchellh/mapstructure/LICENSE delete mode 100644 vendor/github.com/mitchellh/mapstructure/README.md delete mode 100644 vendor/github.com/mitchellh/mapstructure/decode_hooks.go delete mode 100644 vendor/github.com/mitchellh/mapstructure/error.go delete mode 100644 vendor/github.com/mitchellh/mapstructure/mapstructure.go delete mode 100644 vendor/github.com/opentracing-contrib/go-observer/.gitignore delete mode 100644 vendor/github.com/opentracing-contrib/go-observer/LICENSE delete mode 100644 vendor/github.com/opentracing-contrib/go-observer/README.md delete mode 100644 vendor/github.com/opentracing-contrib/go-observer/observer.go delete mode 100644 vendor/github.com/opentracing/opentracing-go/.gitignore delete mode 100644 vendor/github.com/opentracing/opentracing-go/.travis.yml delete mode 100644 vendor/github.com/opentracing/opentracing-go/CHANGELOG.md delete mode 100644 vendor/github.com/opentracing/opentracing-go/LICENSE delete mode 100644 vendor/github.com/opentracing/opentracing-go/Makefile delete mode 100644 vendor/github.com/opentracing/opentracing-go/README.md delete mode 100644 vendor/github.com/opentracing/opentracing-go/ext.go delete mode 100644 vendor/github.com/opentracing/opentracing-go/ext/field.go delete mode 100644 vendor/github.com/opentracing/opentracing-go/ext/tags.go delete mode 100644 vendor/github.com/opentracing/opentracing-go/globaltracer.go delete mode 100644 vendor/github.com/opentracing/opentracing-go/gocontext.go delete mode 100644 vendor/github.com/opentracing/opentracing-go/log/field.go delete mode 100644 vendor/github.com/opentracing/opentracing-go/log/util.go delete mode 100644 vendor/github.com/opentracing/opentracing-go/noop.go delete mode 100644 vendor/github.com/opentracing/opentracing-go/propagation.go delete mode 100644 vendor/github.com/opentracing/opentracing-go/span.go delete mode 100644 vendor/github.com/opentracing/opentracing-go/tracer.go delete mode 100644 vendor/github.com/openzipkin-contrib/zipkin-go-opentracing/.golangci.yml delete mode 100644 vendor/github.com/openzipkin-contrib/zipkin-go-opentracing/.travis.yml delete mode 100644 vendor/github.com/openzipkin-contrib/zipkin-go-opentracing/LICENSE delete mode 100644 vendor/github.com/openzipkin-contrib/zipkin-go-opentracing/Makefile delete mode 100644 vendor/github.com/openzipkin-contrib/zipkin-go-opentracing/README.md delete mode 100644 vendor/github.com/openzipkin-contrib/zipkin-go-opentracing/appveyor.yml delete mode 100644 vendor/github.com/openzipkin-contrib/zipkin-go-opentracing/circle.yml delete mode 100644 vendor/github.com/openzipkin-contrib/zipkin-go-opentracing/context.go delete mode 100644 vendor/github.com/openzipkin-contrib/zipkin-go-opentracing/propagation.go delete mode 100644 vendor/github.com/openzipkin-contrib/zipkin-go-opentracing/span.go delete mode 100644 vendor/github.com/openzipkin-contrib/zipkin-go-opentracing/tracer.go delete mode 100644 vendor/github.com/openzipkin-contrib/zipkin-go-opentracing/tracer_options.go delete mode 100644 vendor/github.com/openzipkin/zipkin-go/.gitattributes delete mode 100644 vendor/github.com/openzipkin/zipkin-go/.gitignore delete mode 100644 vendor/github.com/openzipkin/zipkin-go/.golangci.yml delete mode 100644 vendor/github.com/openzipkin/zipkin-go/LICENSE delete mode 100644 vendor/github.com/openzipkin/zipkin-go/Makefile delete mode 100644 vendor/github.com/openzipkin/zipkin-go/README.md delete mode 100644 vendor/github.com/openzipkin/zipkin-go/SECURITY.md delete mode 100644 vendor/github.com/openzipkin/zipkin-go/context.go delete mode 100644 vendor/github.com/openzipkin/zipkin-go/doc.go delete mode 100644 vendor/github.com/openzipkin/zipkin-go/endpoint.go delete mode 100644 vendor/github.com/openzipkin/zipkin-go/idgenerator/idgenerator.go delete mode 100644 vendor/github.com/openzipkin/zipkin-go/model/annotation.go delete mode 100644 vendor/github.com/openzipkin/zipkin-go/model/doc.go delete mode 100644 vendor/github.com/openzipkin/zipkin-go/model/endpoint.go delete mode 100644 vendor/github.com/openzipkin/zipkin-go/model/kind.go delete mode 100644 vendor/github.com/openzipkin/zipkin-go/model/span.go delete mode 100644 vendor/github.com/openzipkin/zipkin-go/model/span_id.go delete mode 100644 vendor/github.com/openzipkin/zipkin-go/model/traceid.go delete mode 100644 vendor/github.com/openzipkin/zipkin-go/noop.go delete mode 100644 vendor/github.com/openzipkin/zipkin-go/propagation/b3/doc.go delete mode 100644 vendor/github.com/openzipkin/zipkin-go/propagation/b3/grpc.go delete mode 100644 vendor/github.com/openzipkin/zipkin-go/propagation/b3/http.go delete mode 100644 vendor/github.com/openzipkin/zipkin-go/propagation/b3/map.go delete mode 100644 vendor/github.com/openzipkin/zipkin-go/propagation/b3/shared.go delete mode 100644 vendor/github.com/openzipkin/zipkin-go/propagation/b3/spancontext.go delete mode 100644 vendor/github.com/openzipkin/zipkin-go/propagation/propagation.go delete mode 100644 vendor/github.com/openzipkin/zipkin-go/reporter/http/http.go delete mode 100644 vendor/github.com/openzipkin/zipkin-go/reporter/reporter.go delete mode 100644 vendor/github.com/openzipkin/zipkin-go/reporter/serializer.go delete mode 100644 vendor/github.com/openzipkin/zipkin-go/sample.go delete mode 100644 vendor/github.com/openzipkin/zipkin-go/span.go delete mode 100644 vendor/github.com/openzipkin/zipkin-go/span_implementation.go delete mode 100644 vendor/github.com/openzipkin/zipkin-go/span_options.go delete mode 100644 vendor/github.com/openzipkin/zipkin-go/tags.go delete mode 100644 vendor/github.com/openzipkin/zipkin-go/tracer.go delete mode 100644 vendor/github.com/openzipkin/zipkin-go/tracer_options.go delete mode 100644 vendor/github.com/oschwald/geoip2-golang/.gitignore delete mode 100644 vendor/github.com/oschwald/geoip2-golang/.gitmodules delete mode 100644 vendor/github.com/oschwald/geoip2-golang/.golangci.toml delete mode 100644 vendor/github.com/oschwald/geoip2-golang/LICENSE delete mode 100644 vendor/github.com/oschwald/geoip2-golang/README.md delete mode 100644 vendor/github.com/oschwald/geoip2-golang/reader.go delete mode 100644 vendor/github.com/oschwald/maxminddb-golang/.gitignore delete mode 100644 vendor/github.com/oschwald/maxminddb-golang/.gitmodules delete mode 100644 vendor/github.com/oschwald/maxminddb-golang/.golangci.toml delete mode 100644 vendor/github.com/oschwald/maxminddb-golang/LICENSE delete mode 100644 vendor/github.com/oschwald/maxminddb-golang/README.md delete mode 100644 vendor/github.com/oschwald/maxminddb-golang/decoder.go delete mode 100644 vendor/github.com/oschwald/maxminddb-golang/deserializer.go delete mode 100644 vendor/github.com/oschwald/maxminddb-golang/errors.go delete mode 100644 vendor/github.com/oschwald/maxminddb-golang/mmap_unix.go delete mode 100644 vendor/github.com/oschwald/maxminddb-golang/mmap_windows.go delete mode 100644 vendor/github.com/oschwald/maxminddb-golang/node.go delete mode 100644 vendor/github.com/oschwald/maxminddb-golang/reader.go delete mode 100644 vendor/github.com/oschwald/maxminddb-golang/reader_memory.go delete mode 100644 vendor/github.com/oschwald/maxminddb-golang/reader_mmap.go delete mode 100644 vendor/github.com/oschwald/maxminddb-golang/set_zero_120.go delete mode 100644 vendor/github.com/oschwald/maxminddb-golang/set_zero_pre120.go delete mode 100644 vendor/github.com/oschwald/maxminddb-golang/traverse.go delete mode 100644 vendor/github.com/oschwald/maxminddb-golang/verifier.go delete mode 100644 vendor/github.com/outcaste-io/ristretto/.deepsource.toml delete mode 100644 vendor/github.com/outcaste-io/ristretto/.mailmap delete mode 100644 vendor/github.com/outcaste-io/ristretto/CHANGELOG.md delete mode 100644 vendor/github.com/outcaste-io/ristretto/LICENSE delete mode 100644 vendor/github.com/outcaste-io/ristretto/README.md delete mode 100644 vendor/github.com/outcaste-io/ristretto/cache.go delete mode 100644 vendor/github.com/outcaste-io/ristretto/metrics.go delete mode 100644 vendor/github.com/outcaste-io/ristretto/policy.go delete mode 100644 vendor/github.com/outcaste-io/ristretto/ring.go delete mode 100644 vendor/github.com/outcaste-io/ristretto/sketch.go delete mode 100644 vendor/github.com/outcaste-io/ristretto/store.go delete mode 100644 vendor/github.com/outcaste-io/ristretto/test.sh delete mode 100644 vendor/github.com/outcaste-io/ristretto/ttl.go delete mode 100644 vendor/github.com/outcaste-io/ristretto/z/LICENSE delete mode 100644 vendor/github.com/outcaste-io/ristretto/z/README.md delete mode 100644 vendor/github.com/outcaste-io/ristretto/z/allocator.go delete mode 100644 vendor/github.com/outcaste-io/ristretto/z/bbloom.go delete mode 100644 vendor/github.com/outcaste-io/ristretto/z/btree.go delete mode 100644 vendor/github.com/outcaste-io/ristretto/z/buffer.go delete mode 100644 vendor/github.com/outcaste-io/ristretto/z/calloc.go delete mode 100644 vendor/github.com/outcaste-io/ristretto/z/calloc_32bit.go delete mode 100644 vendor/github.com/outcaste-io/ristretto/z/calloc_64bit.go delete mode 100644 vendor/github.com/outcaste-io/ristretto/z/calloc_jemalloc.go delete mode 100644 vendor/github.com/outcaste-io/ristretto/z/calloc_nojemalloc.go delete mode 100644 vendor/github.com/outcaste-io/ristretto/z/file.go delete mode 100644 vendor/github.com/outcaste-io/ristretto/z/file_default.go delete mode 100644 vendor/github.com/outcaste-io/ristretto/z/file_linux.go delete mode 100644 vendor/github.com/outcaste-io/ristretto/z/flags.go delete mode 100644 vendor/github.com/outcaste-io/ristretto/z/histogram.go delete mode 100644 vendor/github.com/outcaste-io/ristretto/z/mmap.go delete mode 100644 vendor/github.com/outcaste-io/ristretto/z/mmap_darwin.go delete mode 100644 vendor/github.com/outcaste-io/ristretto/z/mmap_linux.go delete mode 100644 vendor/github.com/outcaste-io/ristretto/z/mmap_plan9.go delete mode 100644 vendor/github.com/outcaste-io/ristretto/z/mmap_unix.go delete mode 100644 vendor/github.com/outcaste-io/ristretto/z/mmap_wasip1.go delete mode 100644 vendor/github.com/outcaste-io/ristretto/z/mmap_windows.go delete mode 100644 vendor/github.com/outcaste-io/ristretto/z/rtutil.go delete mode 100644 vendor/github.com/outcaste-io/ristretto/z/rtutil.s delete mode 100644 vendor/github.com/outcaste-io/ristretto/z/simd/baseline.go delete mode 100644 vendor/github.com/outcaste-io/ristretto/z/simd/search.go delete mode 100644 vendor/github.com/outcaste-io/ristretto/z/simd/search_amd64.s delete mode 100644 vendor/github.com/outcaste-io/ristretto/z/simd/stub_search_amd64.go delete mode 100644 vendor/github.com/outcaste-io/ristretto/z/z.go delete mode 100644 vendor/github.com/philhofer/fwd/LICENSE.md delete mode 100644 vendor/github.com/philhofer/fwd/README.md delete mode 100644 vendor/github.com/philhofer/fwd/reader.go delete mode 100644 vendor/github.com/philhofer/fwd/writer.go delete mode 100644 vendor/github.com/philhofer/fwd/writer_appengine.go delete mode 100644 vendor/github.com/philhofer/fwd/writer_tinygo.go delete mode 100644 vendor/github.com/philhofer/fwd/writer_unsafe.go delete mode 100644 vendor/github.com/ryanuber/go-glob/.travis.yml delete mode 100644 vendor/github.com/ryanuber/go-glob/LICENSE delete mode 100644 vendor/github.com/ryanuber/go-glob/README.md delete mode 100644 vendor/github.com/ryanuber/go-glob/glob.go delete mode 100644 vendor/github.com/secure-systems-lab/go-securesystemslib/LICENSE delete mode 100644 vendor/github.com/secure-systems-lab/go-securesystemslib/cjson/canonicaljson.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/LICENSE delete mode 100644 vendor/github.com/shirou/gopsutil/v3/common/env.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/cpu/cpu.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/cpu/cpu_aix.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/cpu/cpu_aix_cgo.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/cpu/cpu_aix_nocgo.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/cpu/cpu_darwin.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/cpu/cpu_darwin_cgo.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/cpu/cpu_darwin_nocgo.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/cpu/cpu_dragonfly.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/cpu/cpu_dragonfly_amd64.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/cpu/cpu_fallback.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/cpu/cpu_freebsd.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/cpu/cpu_freebsd_386.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/cpu/cpu_freebsd_amd64.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/cpu/cpu_freebsd_arm.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/cpu/cpu_freebsd_arm64.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/cpu/cpu_linux.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/cpu/cpu_netbsd.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/cpu/cpu_netbsd_amd64.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/cpu/cpu_netbsd_arm64.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/cpu/cpu_openbsd.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/cpu/cpu_openbsd_386.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/cpu/cpu_openbsd_amd64.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/cpu/cpu_openbsd_arm.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/cpu/cpu_openbsd_arm64.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/cpu/cpu_openbsd_riscv64.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/cpu/cpu_plan9.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/cpu/cpu_solaris.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/cpu/cpu_windows.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/internal/common/binary.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/internal/common/common.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/internal/common/common_darwin.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/internal/common/common_freebsd.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/internal/common/common_linux.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/internal/common/common_netbsd.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/internal/common/common_openbsd.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/internal/common/common_unix.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/internal/common/common_windows.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/internal/common/endian.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/internal/common/sleep.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/internal/common/warnings.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/mem/mem.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/mem/mem_aix.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/mem/mem_aix_cgo.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/mem/mem_aix_nocgo.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/mem/mem_bsd.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/mem/mem_darwin.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/mem/mem_darwin_cgo.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/mem/mem_darwin_nocgo.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/mem/mem_fallback.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/mem/mem_freebsd.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/mem/mem_linux.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/mem/mem_netbsd.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/mem/mem_openbsd.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/mem/mem_openbsd_386.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/mem/mem_openbsd_amd64.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/mem/mem_openbsd_arm.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/mem/mem_openbsd_arm64.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/mem/mem_openbsd_riscv64.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/mem/mem_plan9.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/mem/mem_solaris.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/mem/mem_windows.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/net/net.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/net/net_aix.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/net/net_aix_cgo.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/net/net_aix_nocgo.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/net/net_darwin.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/net/net_fallback.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/net/net_freebsd.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/net/net_linux.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/net/net_linux_111.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/net/net_linux_116.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/net/net_openbsd.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/net/net_solaris.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/net/net_unix.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/net/net_windows.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/process/process.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/process/process_bsd.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/process/process_darwin.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/process/process_darwin_amd64.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/process/process_darwin_arm64.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/process/process_darwin_cgo.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/process/process_darwin_nocgo.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/process/process_fallback.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/process/process_freebsd.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/process/process_freebsd_386.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/process/process_freebsd_amd64.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/process/process_freebsd_arm.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/process/process_freebsd_arm64.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/process/process_linux.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/process/process_openbsd.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/process/process_openbsd_386.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/process/process_openbsd_amd64.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/process/process_openbsd_arm.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/process/process_openbsd_arm64.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/process/process_openbsd_riscv64.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/process/process_plan9.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/process/process_posix.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/process/process_solaris.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/process/process_windows.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/process/process_windows_32bit.go delete mode 100644 vendor/github.com/shirou/gopsutil/v3/process/process_windows_64bit.go delete mode 100644 vendor/github.com/shoenig/go-m1cpu/.golangci.yaml delete mode 100644 vendor/github.com/shoenig/go-m1cpu/LICENSE delete mode 100644 vendor/github.com/shoenig/go-m1cpu/Makefile delete mode 100644 vendor/github.com/shoenig/go-m1cpu/README.md delete mode 100644 vendor/github.com/shoenig/go-m1cpu/cpu.go delete mode 100644 vendor/github.com/shoenig/go-m1cpu/incompatible.go delete mode 100644 vendor/github.com/tinylib/msgp/LICENSE delete mode 100644 vendor/github.com/tinylib/msgp/msgp/advise_linux.go delete mode 100644 vendor/github.com/tinylib/msgp/msgp/advise_other.go delete mode 100644 vendor/github.com/tinylib/msgp/msgp/circular.go delete mode 100644 vendor/github.com/tinylib/msgp/msgp/defs.go delete mode 100644 vendor/github.com/tinylib/msgp/msgp/edit.go delete mode 100644 vendor/github.com/tinylib/msgp/msgp/elsize.go delete mode 100644 vendor/github.com/tinylib/msgp/msgp/elsize_default.go delete mode 100644 vendor/github.com/tinylib/msgp/msgp/elsize_tinygo.go delete mode 100644 vendor/github.com/tinylib/msgp/msgp/errors.go delete mode 100644 vendor/github.com/tinylib/msgp/msgp/errors_default.go delete mode 100644 vendor/github.com/tinylib/msgp/msgp/errors_tinygo.go delete mode 100644 vendor/github.com/tinylib/msgp/msgp/extension.go delete mode 100644 vendor/github.com/tinylib/msgp/msgp/file.go delete mode 100644 vendor/github.com/tinylib/msgp/msgp/file_port.go delete mode 100644 vendor/github.com/tinylib/msgp/msgp/integers.go delete mode 100644 vendor/github.com/tinylib/msgp/msgp/json.go delete mode 100644 vendor/github.com/tinylib/msgp/msgp/json_bytes.go delete mode 100644 vendor/github.com/tinylib/msgp/msgp/number.go delete mode 100644 vendor/github.com/tinylib/msgp/msgp/purego.go delete mode 100644 vendor/github.com/tinylib/msgp/msgp/read.go delete mode 100644 vendor/github.com/tinylib/msgp/msgp/read_bytes.go delete mode 100644 vendor/github.com/tinylib/msgp/msgp/size.go delete mode 100644 vendor/github.com/tinylib/msgp/msgp/unsafe.go delete mode 100644 vendor/github.com/tinylib/msgp/msgp/write.go delete mode 100644 vendor/github.com/tinylib/msgp/msgp/write_bytes.go delete mode 100644 vendor/go.etcd.io/etcd/api/v3/LICENSE delete mode 100644 vendor/go.etcd.io/etcd/api/v3/authpb/auth.pb.go delete mode 100644 vendor/go.etcd.io/etcd/api/v3/authpb/auth.proto delete mode 100644 vendor/go.etcd.io/etcd/api/v3/etcdserverpb/etcdserver.pb.go delete mode 100644 vendor/go.etcd.io/etcd/api/v3/etcdserverpb/etcdserver.proto delete mode 100644 vendor/go.etcd.io/etcd/api/v3/etcdserverpb/raft_internal.pb.go delete mode 100644 vendor/go.etcd.io/etcd/api/v3/etcdserverpb/raft_internal.proto delete mode 100644 vendor/go.etcd.io/etcd/api/v3/etcdserverpb/raft_internal_stringer.go delete mode 100644 vendor/go.etcd.io/etcd/api/v3/etcdserverpb/rpc.pb.go delete mode 100644 vendor/go.etcd.io/etcd/api/v3/etcdserverpb/rpc.proto delete mode 100644 vendor/go.etcd.io/etcd/api/v3/membershippb/membership.pb.go delete mode 100644 vendor/go.etcd.io/etcd/api/v3/membershippb/membership.proto delete mode 100644 vendor/go.etcd.io/etcd/api/v3/mvccpb/kv.pb.go delete mode 100644 vendor/go.etcd.io/etcd/api/v3/mvccpb/kv.proto delete mode 100644 vendor/go.etcd.io/etcd/api/v3/v3rpc/rpctypes/doc.go delete mode 100644 vendor/go.etcd.io/etcd/api/v3/v3rpc/rpctypes/error.go delete mode 100644 vendor/go.etcd.io/etcd/api/v3/v3rpc/rpctypes/md.go delete mode 100644 vendor/go.etcd.io/etcd/api/v3/v3rpc/rpctypes/metadatafields.go delete mode 100644 vendor/go.etcd.io/etcd/api/v3/version/version.go delete mode 100644 vendor/go.etcd.io/etcd/client/pkg/v3/LICENSE delete mode 100644 vendor/go.etcd.io/etcd/client/pkg/v3/logutil/doc.go delete mode 100644 vendor/go.etcd.io/etcd/client/pkg/v3/logutil/log_level.go delete mode 100644 vendor/go.etcd.io/etcd/client/pkg/v3/logutil/zap.go delete mode 100644 vendor/go.etcd.io/etcd/client/pkg/v3/logutil/zap_journal.go delete mode 100644 vendor/go.etcd.io/etcd/client/pkg/v3/systemd/doc.go delete mode 100644 vendor/go.etcd.io/etcd/client/pkg/v3/systemd/journal.go delete mode 100644 vendor/go.etcd.io/etcd/client/pkg/v3/types/doc.go delete mode 100644 vendor/go.etcd.io/etcd/client/pkg/v3/types/id.go delete mode 100644 vendor/go.etcd.io/etcd/client/pkg/v3/types/set.go delete mode 100644 vendor/go.etcd.io/etcd/client/pkg/v3/types/slice.go delete mode 100644 vendor/go.etcd.io/etcd/client/pkg/v3/types/urls.go delete mode 100644 vendor/go.etcd.io/etcd/client/pkg/v3/types/urlsmap.go delete mode 100644 vendor/go.etcd.io/etcd/client/v3/LICENSE delete mode 100644 vendor/go.etcd.io/etcd/client/v3/README.md delete mode 100644 vendor/go.etcd.io/etcd/client/v3/auth.go delete mode 100644 vendor/go.etcd.io/etcd/client/v3/client.go delete mode 100644 vendor/go.etcd.io/etcd/client/v3/cluster.go delete mode 100644 vendor/go.etcd.io/etcd/client/v3/compact_op.go delete mode 100644 vendor/go.etcd.io/etcd/client/v3/compare.go delete mode 100644 vendor/go.etcd.io/etcd/client/v3/config.go delete mode 100644 vendor/go.etcd.io/etcd/client/v3/credentials/credentials.go delete mode 100644 vendor/go.etcd.io/etcd/client/v3/ctx.go delete mode 100644 vendor/go.etcd.io/etcd/client/v3/doc.go delete mode 100644 vendor/go.etcd.io/etcd/client/v3/internal/endpoint/endpoint.go delete mode 100644 vendor/go.etcd.io/etcd/client/v3/internal/resolver/resolver.go delete mode 100644 vendor/go.etcd.io/etcd/client/v3/kv.go delete mode 100644 vendor/go.etcd.io/etcd/client/v3/lease.go delete mode 100644 vendor/go.etcd.io/etcd/client/v3/logger.go delete mode 100644 vendor/go.etcd.io/etcd/client/v3/maintenance.go delete mode 100644 vendor/go.etcd.io/etcd/client/v3/op.go delete mode 100644 vendor/go.etcd.io/etcd/client/v3/options.go delete mode 100644 vendor/go.etcd.io/etcd/client/v3/retry.go delete mode 100644 vendor/go.etcd.io/etcd/client/v3/retry_interceptor.go delete mode 100644 vendor/go.etcd.io/etcd/client/v3/sort.go delete mode 100644 vendor/go.etcd.io/etcd/client/v3/txn.go delete mode 100644 vendor/go.etcd.io/etcd/client/v3/utils.go delete mode 100644 vendor/go.etcd.io/etcd/client/v3/watch.go delete mode 100644 vendor/go.opentelemetry.io/collector/component/LICENSE delete mode 100644 vendor/go.opentelemetry.io/collector/component/Makefile delete mode 100644 vendor/go.opentelemetry.io/collector/component/build_info.go delete mode 100644 vendor/go.opentelemetry.io/collector/component/component.go delete mode 100644 vendor/go.opentelemetry.io/collector/component/config.go delete mode 100644 vendor/go.opentelemetry.io/collector/component/doc.go delete mode 100644 vendor/go.opentelemetry.io/collector/component/host.go delete mode 100644 vendor/go.opentelemetry.io/collector/component/identifiable.go delete mode 100644 vendor/go.opentelemetry.io/collector/component/status.go delete mode 100644 vendor/go.opentelemetry.io/collector/component/telemetry.go delete mode 100644 vendor/go.opentelemetry.io/collector/config/configtelemetry/LICENSE delete mode 100644 vendor/go.opentelemetry.io/collector/config/configtelemetry/Makefile delete mode 100644 vendor/go.opentelemetry.io/collector/config/configtelemetry/configtelemetry.go delete mode 100644 vendor/go.opentelemetry.io/collector/config/configtelemetry/doc.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/LICENSE delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/internal/.gitignore delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/internal/data/bytesid.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/internal/data/protogen/collector/logs/v1/logs_service.pb.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/internal/data/protogen/collector/metrics/v1/metrics_service.pb.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/internal/data/protogen/collector/profiles/v1experimental/profiles_service.pb.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/internal/data/protogen/collector/trace/v1/trace_service.pb.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/internal/data/protogen/common/v1/common.pb.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/internal/data/protogen/logs/v1/logs.pb.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/internal/data/protogen/metrics/v1/metrics.pb.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/internal/data/protogen/profiles/v1experimental/pprofextended.pb.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/internal/data/protogen/profiles/v1experimental/profiles.pb.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/internal/data/protogen/resource/v1/resource.pb.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/internal/data/protogen/trace/v1/trace.pb.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/internal/data/spanid.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/internal/data/traceid.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/internal/generated_wrapper_byteslice.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/internal/generated_wrapper_float64slice.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/internal/generated_wrapper_instrumentationscope.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/internal/generated_wrapper_int64slice.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/internal/generated_wrapper_resource.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/internal/generated_wrapper_stringslice.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/internal/generated_wrapper_uint64slice.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/internal/json/attribute.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/internal/json/enum.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/internal/json/json.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/internal/json/number.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/internal/json/resource.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/internal/json/scope.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/internal/otlp/logs.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/internal/otlp/metrics.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/internal/otlp/traces.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/internal/state.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/internal/wrapper_logs.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/internal/wrapper_map.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/internal/wrapper_metrics.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/internal/wrapper_profiles.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/internal/wrapper_slice.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/internal/wrapper_traces.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/internal/wrapper_tracestate.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/internal/wrapper_value.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/pcommon/generated_byteslice.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/pcommon/generated_float64slice.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/pcommon/generated_instrumentationscope.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/pcommon/generated_int64slice.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/pcommon/generated_resource.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/pcommon/generated_stringslice.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/pcommon/generated_uint64slice.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/pcommon/map.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/pcommon/slice.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/pcommon/spanid.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/pcommon/timestamp.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/pcommon/trace_state.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/pcommon/traceid.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/pcommon/value.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/pprofile/LICENSE delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/pprofile/Makefile delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/pprofile/generated_attributeunit.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/pprofile/generated_attributeunitslice.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/pprofile/generated_function.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/pprofile/generated_functionslice.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/pprofile/generated_label.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/pprofile/generated_labelslice.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/pprofile/generated_line.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/pprofile/generated_lineslice.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/pprofile/generated_link.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/pprofile/generated_linkslice.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/pprofile/generated_location.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/pprofile/generated_locationslice.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/pprofile/generated_mapping.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/pprofile/generated_mappingslice.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/pprofile/generated_profile.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/pprofile/generated_profilecontainer.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/pprofile/generated_profilescontainersslice.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/pprofile/generated_resourceprofiles.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/pprofile/generated_resourceprofilesslice.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/pprofile/generated_sample.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/pprofile/generated_sampleslice.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/pprofile/generated_scopeprofiles.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/pprofile/generated_scopeprofilesslice.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/pprofile/generated_valuetype.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/pprofile/generated_valuetypeslice.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/pprofile/profiles.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/ptrace/encoding.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/ptrace/generated_resourcespans.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/ptrace/generated_resourcespansslice.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/ptrace/generated_scopespans.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/ptrace/generated_scopespansslice.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/ptrace/generated_span.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/ptrace/generated_spanevent.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/ptrace/generated_spaneventslice.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/ptrace/generated_spanlink.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/ptrace/generated_spanlinkslice.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/ptrace/generated_spanslice.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/ptrace/generated_status.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/ptrace/json.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/ptrace/pb.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/ptrace/span_kind.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/ptrace/status_code.go delete mode 100644 vendor/go.opentelemetry.io/collector/pdata/ptrace/traces.go delete mode 100644 vendor/go.opentelemetry.io/collector/semconv/LICENSE delete mode 100644 vendor/go.opentelemetry.io/collector/semconv/v1.17.0/generated_event.go delete mode 100644 vendor/go.opentelemetry.io/collector/semconv/v1.17.0/generated_resource.go delete mode 100644 vendor/go.opentelemetry.io/collector/semconv/v1.17.0/generated_trace.go delete mode 100644 vendor/go.opentelemetry.io/collector/semconv/v1.17.0/schema.go delete mode 100644 vendor/go.opentelemetry.io/collector/semconv/v1.6.1/generated_resource.go delete mode 100644 vendor/go.opentelemetry.io/collector/semconv/v1.6.1/generated_trace.go delete mode 100644 vendor/go.opentelemetry.io/collector/semconv/v1.6.1/nonstandard.go delete mode 100644 vendor/go.opentelemetry.io/collector/semconv/v1.6.1/schema.go delete mode 100644 vendor/go.uber.org/atomic/.codecov.yml delete mode 100644 vendor/go.uber.org/atomic/.gitignore delete mode 100644 vendor/go.uber.org/atomic/CHANGELOG.md delete mode 100644 vendor/go.uber.org/atomic/LICENSE.txt delete mode 100644 vendor/go.uber.org/atomic/Makefile delete mode 100644 vendor/go.uber.org/atomic/README.md delete mode 100644 vendor/go.uber.org/atomic/bool.go delete mode 100644 vendor/go.uber.org/atomic/bool_ext.go delete mode 100644 vendor/go.uber.org/atomic/doc.go delete mode 100644 vendor/go.uber.org/atomic/duration.go delete mode 100644 vendor/go.uber.org/atomic/duration_ext.go delete mode 100644 vendor/go.uber.org/atomic/error.go delete mode 100644 vendor/go.uber.org/atomic/error_ext.go delete mode 100644 vendor/go.uber.org/atomic/float32.go delete mode 100644 vendor/go.uber.org/atomic/float32_ext.go delete mode 100644 vendor/go.uber.org/atomic/float64.go delete mode 100644 vendor/go.uber.org/atomic/float64_ext.go delete mode 100644 vendor/go.uber.org/atomic/gen.go delete mode 100644 vendor/go.uber.org/atomic/int32.go delete mode 100644 vendor/go.uber.org/atomic/int64.go delete mode 100644 vendor/go.uber.org/atomic/nocmp.go delete mode 100644 vendor/go.uber.org/atomic/pointer_go118.go delete mode 100644 vendor/go.uber.org/atomic/pointer_go118_pre119.go delete mode 100644 vendor/go.uber.org/atomic/pointer_go119.go delete mode 100644 vendor/go.uber.org/atomic/string.go delete mode 100644 vendor/go.uber.org/atomic/string_ext.go delete mode 100644 vendor/go.uber.org/atomic/time.go delete mode 100644 vendor/go.uber.org/atomic/time_ext.go delete mode 100644 vendor/go.uber.org/atomic/uint32.go delete mode 100644 vendor/go.uber.org/atomic/uint64.go delete mode 100644 vendor/go.uber.org/atomic/uintptr.go delete mode 100644 vendor/go.uber.org/atomic/unsafe_pointer.go delete mode 100644 vendor/go.uber.org/atomic/value.go delete mode 100644 vendor/go.uber.org/multierr/.codecov.yml delete mode 100644 vendor/go.uber.org/multierr/.gitignore delete mode 100644 vendor/go.uber.org/multierr/CHANGELOG.md delete mode 100644 vendor/go.uber.org/multierr/LICENSE.txt delete mode 100644 vendor/go.uber.org/multierr/Makefile delete mode 100644 vendor/go.uber.org/multierr/README.md delete mode 100644 vendor/go.uber.org/multierr/error.go delete mode 100644 vendor/go.uber.org/multierr/error_post_go120.go delete mode 100644 vendor/go.uber.org/multierr/error_pre_go120.go delete mode 100644 vendor/go.uber.org/zap/.codecov.yml delete mode 100644 vendor/go.uber.org/zap/.gitignore delete mode 100644 vendor/go.uber.org/zap/.golangci.yml delete mode 100644 vendor/go.uber.org/zap/.readme.tmpl delete mode 100644 vendor/go.uber.org/zap/CHANGELOG.md delete mode 100644 vendor/go.uber.org/zap/CODE_OF_CONDUCT.md delete mode 100644 vendor/go.uber.org/zap/CONTRIBUTING.md delete mode 100644 vendor/go.uber.org/zap/FAQ.md delete mode 100644 vendor/go.uber.org/zap/LICENSE delete mode 100644 vendor/go.uber.org/zap/Makefile delete mode 100644 vendor/go.uber.org/zap/README.md delete mode 100644 vendor/go.uber.org/zap/array.go delete mode 100644 vendor/go.uber.org/zap/buffer/buffer.go delete mode 100644 vendor/go.uber.org/zap/buffer/pool.go delete mode 100644 vendor/go.uber.org/zap/checklicense.sh delete mode 100644 vendor/go.uber.org/zap/config.go delete mode 100644 vendor/go.uber.org/zap/doc.go delete mode 100644 vendor/go.uber.org/zap/encoder.go delete mode 100644 vendor/go.uber.org/zap/error.go delete mode 100644 vendor/go.uber.org/zap/field.go delete mode 100644 vendor/go.uber.org/zap/flag.go delete mode 100644 vendor/go.uber.org/zap/glide.yaml delete mode 100644 vendor/go.uber.org/zap/global.go delete mode 100644 vendor/go.uber.org/zap/http_handler.go delete mode 100644 vendor/go.uber.org/zap/internal/bufferpool/bufferpool.go delete mode 100644 vendor/go.uber.org/zap/internal/color/color.go delete mode 100644 vendor/go.uber.org/zap/internal/exit/exit.go delete mode 100644 vendor/go.uber.org/zap/internal/level_enabler.go delete mode 100644 vendor/go.uber.org/zap/internal/pool/pool.go delete mode 100644 vendor/go.uber.org/zap/internal/stacktrace/stack.go delete mode 100644 vendor/go.uber.org/zap/level.go delete mode 100644 vendor/go.uber.org/zap/logger.go delete mode 100644 vendor/go.uber.org/zap/options.go delete mode 100644 vendor/go.uber.org/zap/sink.go delete mode 100644 vendor/go.uber.org/zap/sugar.go delete mode 100644 vendor/go.uber.org/zap/time.go delete mode 100644 vendor/go.uber.org/zap/writer.go delete mode 100644 vendor/go.uber.org/zap/zapcore/buffered_write_syncer.go delete mode 100644 vendor/go.uber.org/zap/zapcore/clock.go delete mode 100644 vendor/go.uber.org/zap/zapcore/console_encoder.go delete mode 100644 vendor/go.uber.org/zap/zapcore/core.go delete mode 100644 vendor/go.uber.org/zap/zapcore/doc.go delete mode 100644 vendor/go.uber.org/zap/zapcore/encoder.go delete mode 100644 vendor/go.uber.org/zap/zapcore/entry.go delete mode 100644 vendor/go.uber.org/zap/zapcore/error.go delete mode 100644 vendor/go.uber.org/zap/zapcore/field.go delete mode 100644 vendor/go.uber.org/zap/zapcore/hook.go delete mode 100644 vendor/go.uber.org/zap/zapcore/increase_level.go delete mode 100644 vendor/go.uber.org/zap/zapcore/json_encoder.go delete mode 100644 vendor/go.uber.org/zap/zapcore/lazy_with.go delete mode 100644 vendor/go.uber.org/zap/zapcore/level.go delete mode 100644 vendor/go.uber.org/zap/zapcore/level_strings.go delete mode 100644 vendor/go.uber.org/zap/zapcore/marshaler.go delete mode 100644 vendor/go.uber.org/zap/zapcore/memory_encoder.go delete mode 100644 vendor/go.uber.org/zap/zapcore/reflected_encoder.go delete mode 100644 vendor/go.uber.org/zap/zapcore/sampler.go delete mode 100644 vendor/go.uber.org/zap/zapcore/tee.go delete mode 100644 vendor/go.uber.org/zap/zapcore/write_syncer.go delete mode 100644 vendor/go.uber.org/zap/zapgrpc/zapgrpc.go delete mode 100644 vendor/golang.org/x/crypto/cryptobyte/asn1.go delete mode 100644 vendor/golang.org/x/crypto/cryptobyte/asn1/asn1.go delete mode 100644 vendor/golang.org/x/crypto/cryptobyte/builder.go delete mode 100644 vendor/golang.org/x/crypto/cryptobyte/string.go delete mode 100644 vendor/golang.org/x/crypto/pkcs12/bmp-string.go delete mode 100644 vendor/golang.org/x/crypto/pkcs12/crypto.go delete mode 100644 vendor/golang.org/x/crypto/pkcs12/errors.go delete mode 100644 vendor/golang.org/x/crypto/pkcs12/internal/rc2/rc2.go delete mode 100644 vendor/golang.org/x/crypto/pkcs12/mac.go delete mode 100644 vendor/golang.org/x/crypto/pkcs12/pbkdf.go delete mode 100644 vendor/golang.org/x/crypto/pkcs12/pkcs12.go delete mode 100644 vendor/golang.org/x/crypto/pkcs12/safebags.go delete mode 100644 vendor/golang.org/x/oauth2/authhandler/authhandler.go delete mode 100644 vendor/golang.org/x/oauth2/google/appengine.go delete mode 100644 vendor/golang.org/x/oauth2/google/default.go delete mode 100644 vendor/golang.org/x/oauth2/google/doc.go delete mode 100644 vendor/golang.org/x/oauth2/google/error.go delete mode 100644 vendor/golang.org/x/oauth2/google/externalaccount/aws.go delete mode 100644 vendor/golang.org/x/oauth2/google/externalaccount/basecredentials.go delete mode 100644 vendor/golang.org/x/oauth2/google/externalaccount/executablecredsource.go delete mode 100644 vendor/golang.org/x/oauth2/google/externalaccount/filecredsource.go delete mode 100644 vendor/golang.org/x/oauth2/google/externalaccount/header.go delete mode 100644 vendor/golang.org/x/oauth2/google/externalaccount/programmaticrefreshcredsource.go delete mode 100644 vendor/golang.org/x/oauth2/google/externalaccount/urlcredsource.go delete mode 100644 vendor/golang.org/x/oauth2/google/google.go delete mode 100644 vendor/golang.org/x/oauth2/google/internal/externalaccountauthorizeduser/externalaccountauthorizeduser.go delete mode 100644 vendor/golang.org/x/oauth2/google/internal/impersonate/impersonate.go delete mode 100644 vendor/golang.org/x/oauth2/google/internal/stsexchange/clientauth.go delete mode 100644 vendor/golang.org/x/oauth2/google/internal/stsexchange/sts_exchange.go delete mode 100644 vendor/golang.org/x/oauth2/google/jwt.go delete mode 100644 vendor/golang.org/x/oauth2/google/sdk.go delete mode 100644 vendor/golang.org/x/oauth2/jws/jws.go delete mode 100644 vendor/golang.org/x/oauth2/jwt/jwt.go delete mode 100644 vendor/golang.org/x/text/encoding/simplifiedchinese/all.go delete mode 100644 vendor/golang.org/x/text/encoding/simplifiedchinese/gbk.go delete mode 100644 vendor/golang.org/x/text/encoding/simplifiedchinese/hzgb2312.go delete mode 100644 vendor/golang.org/x/text/encoding/simplifiedchinese/tables.go delete mode 100644 vendor/golang.org/x/xerrors/LICENSE delete mode 100644 vendor/golang.org/x/xerrors/PATENTS delete mode 100644 vendor/golang.org/x/xerrors/README delete mode 100644 vendor/golang.org/x/xerrors/adaptor.go delete mode 100644 vendor/golang.org/x/xerrors/codereview.cfg delete mode 100644 vendor/golang.org/x/xerrors/doc.go delete mode 100644 vendor/golang.org/x/xerrors/errors.go delete mode 100644 vendor/golang.org/x/xerrors/fmt.go delete mode 100644 vendor/golang.org/x/xerrors/format.go delete mode 100644 vendor/golang.org/x/xerrors/frame.go delete mode 100644 vendor/golang.org/x/xerrors/internal/internal.go delete mode 100644 vendor/golang.org/x/xerrors/wrap.go delete mode 100644 vendor/google.golang.org/api/AUTHORS delete mode 100644 vendor/google.golang.org/api/CONTRIBUTORS delete mode 100644 vendor/google.golang.org/api/LICENSE delete mode 100644 vendor/google.golang.org/api/dns/v1/dns-api.json delete mode 100644 vendor/google.golang.org/api/dns/v1/dns-gen.go delete mode 100644 vendor/google.golang.org/api/googleapi/googleapi.go delete mode 100644 vendor/google.golang.org/api/googleapi/transport/apikey.go delete mode 100644 vendor/google.golang.org/api/googleapi/types.go delete mode 100644 vendor/google.golang.org/api/internal/cba.go delete mode 100644 vendor/google.golang.org/api/internal/cert/default_cert.go delete mode 100644 vendor/google.golang.org/api/internal/cert/enterprise_cert.go delete mode 100644 vendor/google.golang.org/api/internal/cert/secureconnect_cert.go delete mode 100644 vendor/google.golang.org/api/internal/conn_pool.go delete mode 100644 vendor/google.golang.org/api/internal/creds.go delete mode 100644 vendor/google.golang.org/api/internal/gensupport/buffer.go delete mode 100644 vendor/google.golang.org/api/internal/gensupport/doc.go delete mode 100644 vendor/google.golang.org/api/internal/gensupport/error.go delete mode 100644 vendor/google.golang.org/api/internal/gensupport/json.go delete mode 100644 vendor/google.golang.org/api/internal/gensupport/jsonfloat.go delete mode 100644 vendor/google.golang.org/api/internal/gensupport/media.go delete mode 100644 vendor/google.golang.org/api/internal/gensupport/params.go delete mode 100644 vendor/google.golang.org/api/internal/gensupport/resumable.go delete mode 100644 vendor/google.golang.org/api/internal/gensupport/retry.go delete mode 100644 vendor/google.golang.org/api/internal/gensupport/send.go delete mode 100644 vendor/google.golang.org/api/internal/gensupport/version.go delete mode 100644 vendor/google.golang.org/api/internal/impersonate/impersonate.go delete mode 100644 vendor/google.golang.org/api/internal/s2a.go delete mode 100644 vendor/google.golang.org/api/internal/settings.go delete mode 100644 vendor/google.golang.org/api/internal/third_party/uritemplates/LICENSE delete mode 100644 vendor/google.golang.org/api/internal/third_party/uritemplates/METADATA delete mode 100644 vendor/google.golang.org/api/internal/third_party/uritemplates/uritemplates.go delete mode 100644 vendor/google.golang.org/api/internal/third_party/uritemplates/utils.go delete mode 100644 vendor/google.golang.org/api/internal/version.go delete mode 100644 vendor/google.golang.org/api/option/internaloption/internaloption.go delete mode 100644 vendor/google.golang.org/api/option/option.go delete mode 100644 vendor/google.golang.org/api/transport/http/dial.go delete mode 100644 vendor/google.golang.org/genproto/googleapis/rpc/code/code.pb.go delete mode 100644 vendor/google.golang.org/grpc/resolver/manual/manual.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/LICENSE delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/LICENSE-3rdparty.csv delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/LICENSE-APACHE delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/LICENSE-BSD3 delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/NOTICE delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/appsec/events/block.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/datastreams/options/options.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ddtrace.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext/app_types.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext/db.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext/log_key.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext/messaging.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext/peer.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext/priority.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext/rpc.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext/span_kind.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext/system.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext/tags.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/internal/globaltracer.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/opentracer/option.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/opentracer/span.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/opentracer/tracer.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/span_link_msgp.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/abandonedspans.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/civisibility_payload.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/civisibility_transport.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/civisibility_tslv.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/civisibility_tslv_msgp.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/civisibility_writer.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/context.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/data_streams.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/doc.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/dynamic_config.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/log.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/meta_struct.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/metrics.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/option.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/orchestrion.yml delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/otel_dd_mappings.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/payload.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/propagating_tags.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/propagator.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/rand.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/remote_config.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/rules_sampler.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/sampler.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/slog.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/span.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/span_msgp.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/spancontext.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/sqlcomment.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/stats.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/telemetry.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/textmap.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/time.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/time_windows.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/tracer.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/transport.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/util.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer/writer.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/active_span_key.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/agent-otel-workaround.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/agent.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/README.md delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/appsec.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/config/config.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/config/rules_manager.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/dyngo/operation.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/emitter/graphqlsec/README.md delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/emitter/graphqlsec/execution.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/emitter/graphqlsec/request.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/emitter/graphqlsec/resolve.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/emitter/grpcsec/grpc.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/emitter/httpsec/config.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/emitter/httpsec/http.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/emitter/httpsec/roundtripper.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/emitter/ossec/lfi.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/emitter/sqlsec/sql.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/emitter/trace/service_entry_span.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/emitter/trace/span.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/emitter/trace/tag_setter.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/emitter/usersec/user.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/emitter/waf/actions/actions.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/emitter/waf/actions/block.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/emitter/waf/actions/blocked-template.html delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/emitter/waf/actions/blocked-template.json delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/emitter/waf/actions/http_redirect.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/emitter/waf/actions/stacktrace.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/emitter/waf/addresses/addresses.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/emitter/waf/addresses/builder.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/emitter/waf/context.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/emitter/waf/run.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/features.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/listener/feature.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/listener/graphqlsec/graphql.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/listener/grpcsec/grpc.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/listener/httpsec/http.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/listener/httpsec/request.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/listener/httpsec/roundtripper.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/listener/ossec/lfi.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/listener/sqlsec/sql.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/listener/trace/trace.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/listener/usersec/usec.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/listener/waf/tags.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/listener/waf/waf.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/remoteconfig.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/telemetry.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/appsec/telemetry_cgo.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/civisibility/constants/ci.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/civisibility/constants/env.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/civisibility/constants/git.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/civisibility/constants/os.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/civisibility/constants/runtime.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/civisibility/constants/span_types.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/civisibility/constants/tags.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/civisibility/constants/test_tags.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/civisibility/utils/ci_providers.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/civisibility/utils/codeowners.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/civisibility/utils/environmentTags.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/civisibility/utils/git.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/civisibility/utils/home.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/civisibility/utils/names.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/civisibility/utils/telemetry/telemetry.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/civisibility/utils/telemetry/telemetry_count.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/civisibility/utils/telemetry/telemetry_distribution.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/container_linux.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/container_stub.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/datastreams/fast_queue.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/datastreams/hash_cache.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/datastreams/pathway.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/datastreams/payload.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/datastreams/payload_msgp.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/datastreams/processor.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/datastreams/propagator.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/datastreams/transport.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/env.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/gitmetadata.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/globalconfig/globalconfig.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/hostname/azure/azure.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/hostname/cachedfetch/fetcher.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/hostname/ec2/ec2.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/hostname/ecs/aws.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/hostname/fqdn_nix.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/hostname/fqdn_windows.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/hostname/gce/gce.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/hostname/httputils/helpers.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/hostname/providers.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/hostname/validate/validate.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/log/log.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/meta_internal_types.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/namingschema/namingschema.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/namingschema/op.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/namingschema/service_name.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/normalizer/normalizer.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/orchestrion/context.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/orchestrion/context_stack.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/orchestrion/gls.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/orchestrion/gls.orchestrion.yml delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/orchestrion/orchestrion.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/osinfo/osinfo.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/osinfo/osinfo_unix.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/osinfo/osinfo_windows.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/remoteconfig/config.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/remoteconfig/remoteconfig.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/remoteconfig/types.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/samplernames/samplernames.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/stacktrace/event.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/stacktrace/event_msgp.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/stacktrace/stacktrace.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/stacktrace/stacktrace_msgp.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/statsd.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/telemetry/client.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/telemetry/message.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/telemetry/option.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/telemetry/telemetry.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/telemetry/utils.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/trace_context.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/traceprof/endpoint_counter.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/traceprof/profiler.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/traceprof/traceprof.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/utils.go delete mode 100644 vendor/gopkg.in/DataDog/dd-trace-go.v1/internal/version/version.go delete mode 100644 vendor/gopkg.in/ini.v1/.editorconfig delete mode 100644 vendor/gopkg.in/ini.v1/.gitignore delete mode 100644 vendor/gopkg.in/ini.v1/.golangci.yml delete mode 100644 vendor/gopkg.in/ini.v1/LICENSE delete mode 100644 vendor/gopkg.in/ini.v1/Makefile delete mode 100644 vendor/gopkg.in/ini.v1/README.md delete mode 100644 vendor/gopkg.in/ini.v1/codecov.yml delete mode 100644 vendor/gopkg.in/ini.v1/data_source.go delete mode 100644 vendor/gopkg.in/ini.v1/deprecated.go delete mode 100644 vendor/gopkg.in/ini.v1/error.go delete mode 100644 vendor/gopkg.in/ini.v1/file.go delete mode 100644 vendor/gopkg.in/ini.v1/helper.go delete mode 100644 vendor/gopkg.in/ini.v1/ini.go delete mode 100644 vendor/gopkg.in/ini.v1/key.go delete mode 100644 vendor/gopkg.in/ini.v1/parser.go delete mode 100644 vendor/gopkg.in/ini.v1/section.go delete mode 100644 vendor/gopkg.in/ini.v1/struct.go diff --git a/go.mod b/go.mod index d1ba5ad6..52b54c88 100644 --- a/go.mod +++ b/go.mod @@ -6,8 +6,6 @@ require ( github.com/cilium/ipam v0.0.0-20230509084518-fd66eae7909b github.com/containerd/containerd v1.7.27 github.com/containernetworking/cni v1.1.2 - github.com/coredns/caddy v1.1.2-0.20241029205200-8de985351a98 - github.com/coredns/coredns v1.12.1 github.com/distribution/reference v0.6.0 github.com/docker/cli v27.5.1+incompatible github.com/docker/docker v27.5.1+incompatible @@ -48,7 +46,6 @@ require ( golang.org/x/oauth2 v0.28.0 golang.org/x/sys v0.32.0 golang.org/x/term v0.31.0 - golang.org/x/text v0.24.0 golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 golang.zx2c4.com/wireguard v0.0.0-20220920152132-bb719d3a6e2c golang.zx2c4.com/wireguard/windows v0.5.3 @@ -72,39 +69,12 @@ require ( require ( cel.dev/expr v0.19.1 // indirect - cloud.google.com/go/auth v0.15.0 // indirect - cloud.google.com/go/auth/oauth2adapt v0.2.7 // indirect - cloud.google.com/go/compute/metadata v0.6.0 // indirect dario.cat/mergo v1.0.1 // indirect filippo.io/edwards25519 v1.1.0 // indirect github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 // indirect - github.com/Azure/azure-sdk-for-go v68.0.0+incompatible // indirect github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect - github.com/Azure/go-autorest v14.2.0+incompatible // indirect - github.com/Azure/go-autorest/autorest v0.11.30 // indirect - github.com/Azure/go-autorest/autorest/adal v0.9.23 // indirect - github.com/Azure/go-autorest/autorest/azure/auth v0.5.13 // indirect - github.com/Azure/go-autorest/autorest/azure/cli v0.4.6 // indirect - github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect - github.com/Azure/go-autorest/autorest/to v0.4.0 // indirect - github.com/Azure/go-autorest/logger v0.2.1 // indirect - github.com/Azure/go-autorest/tracing v0.6.0 // indirect github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c // indirect - github.com/DataDog/appsec-internal-go v1.9.0 // indirect - github.com/DataDog/datadog-agent/pkg/obfuscate v0.58.0 // indirect - github.com/DataDog/datadog-agent/pkg/proto v0.58.0 // indirect - github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.58.0 // indirect - github.com/DataDog/datadog-agent/pkg/trace v0.58.0 // indirect - github.com/DataDog/datadog-agent/pkg/util/log v0.58.0 // indirect - github.com/DataDog/datadog-agent/pkg/util/scrubber v0.58.0 // indirect - github.com/DataDog/datadog-go/v5 v5.5.0 // indirect - github.com/DataDog/go-libddwaf/v3 v3.5.1 // indirect - github.com/DataDog/go-runtime-metrics-internal v0.0.4-0.20241206090539-a14610dc22b6 // indirect - github.com/DataDog/go-sqllexer v0.0.14 // indirect - github.com/DataDog/go-tuf v1.1.0-0.5.2 // indirect - github.com/DataDog/opentelemetry-mapping-go/pkg/otlp/attributes v0.20.0 // indirect - github.com/DataDog/sketches-go v1.4.5 // indirect github.com/MakeNowJust/heredoc v1.0.0 // indirect github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver/v3 v3.3.0 // indirect @@ -114,23 +84,7 @@ require ( github.com/Microsoft/hcsshim v0.12.9 // indirect github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa // indirect github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect - github.com/apparentlymart/go-cidr v1.1.0 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect - github.com/aws/aws-sdk-go v1.55.6 // indirect - github.com/aws/aws-sdk-go-v2 v1.36.3 // indirect - github.com/aws/aws-sdk-go-v2/config v1.29.9 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.17.62 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 // indirect - github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.35.2 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.25.1 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.29.1 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.33.17 // indirect - github.com/aws/smithy-go v1.22.2 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.13.0 // indirect github.com/blang/semver/v4 v4.0.0 // indirect @@ -141,27 +95,20 @@ require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chai2010/gettext-go v1.0.2 // indirect github.com/chmduquesne/rollinghash v4.0.0+incompatible // indirect - github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575 // indirect github.com/cilium/ebpf v0.16.0 // indirect github.com/cncf/xds/go v0.0.0-20241223141626-cff3c89139a3 // indirect github.com/containerd/log v0.1.0 // indirect github.com/containerd/platforms v0.2.1 // indirect github.com/coreos/go-iptables v0.7.1-0.20240112124308-65c67c9f46e6 // indirect - github.com/coreos/go-semver v0.3.1 // indirect - github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/cyphar/filepath-securejoin v0.4.1 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dblohm7/wingoes v0.0.0-20240119213807-a09d6be7affa // indirect - github.com/dimchansky/utfbom v1.1.1 // indirect - github.com/dnstap/golang-dnstap v0.4.0 // indirect github.com/docker/distribution v2.8.3+incompatible // indirect github.com/docker/docker-credential-helpers v0.8.2 // indirect github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c // indirect github.com/docker/go-events v0.0.0-20250114142523-c867878c5e32 // indirect github.com/docker/go-metrics v0.0.1 // indirect github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 // indirect - github.com/dustin/go-humanize v1.0.1 // indirect - github.com/eapache/queue/v2 v2.0.0-20230407133247-75960ed334e4 // indirect github.com/ebitengine/purego v0.8.3 // indirect github.com/emicklei/go-restful/v3 v3.12.2 // indirect github.com/envoyproxy/go-control-plane/ratelimit v0.1.0 // indirect @@ -169,12 +116,9 @@ require ( github.com/evanphx/json-patch v5.9.11+incompatible // indirect github.com/evanphx/json-patch/v5 v5.9.11 // indirect github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect - github.com/expr-lang/expr v1.17.2 // indirect - github.com/farsightsec/golang-framestream v0.3.0 // indirect github.com/fatih/camelcase v1.0.0 // indirect github.com/fatih/color v1.18.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 // indirect github.com/fvbommel/sortorder v1.1.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/gaissmai/bart v0.11.1 // indirect @@ -194,7 +138,6 @@ require ( github.com/gobwas/glob v0.2.3 // indirect github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang-jwt/jwt/v4 v4.5.2 // indirect github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/btree v1.1.3 // indirect @@ -202,36 +145,29 @@ require ( github.com/google/gofuzz v1.2.0 // indirect github.com/google/nftables v0.2.1-0.20240414091927-5e242ec57806 // indirect github.com/google/pprof v0.0.0-20250202011525-fc3143867406 // indirect - github.com/google/s2a-go v0.1.9 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect - github.com/googleapis/gax-go/v2 v2.14.1 // indirect github.com/gorilla/mux v1.8.1 // indirect github.com/gorilla/websocket v1.5.3 // indirect github.com/gosuri/uitable v0.0.4 // indirect github.com/greatroar/blobloom v0.8.0 // indirect github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 // indirect - github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/go-secure-stdlib/parseutil v0.1.7 // indirect - github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect - github.com/hashicorp/go-sockaddr v1.0.2 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect + github.com/hashicorp/hcl v1.0.1-vault-5 // indirect github.com/hdevalence/ed25519consensus v0.2.0 // indirect github.com/huandu/xstrings v1.5.0 // indirect github.com/illarion/gonotify/v2 v2.0.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/infobloxopen/go-trees v0.0.0-20221216143356-66ceba885ebc // indirect github.com/jackpal/gateway v1.0.16 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jcmturner/aescts/v2 v2.0.0 // indirect github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect github.com/jcmturner/goidentity/v6 v6.0.1 // indirect github.com/jcmturner/rpc/v2 v2.0.3 // indirect - github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/jinzhu/gorm v1.9.16 // indirect github.com/jmoiron/sqlx v1.4.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/josharian/native v1.1.1-0.20230202152459-5c7d0dd6ab86 // indirect @@ -248,14 +184,12 @@ require ( github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mdlayher/netlink v1.7.2 // indirect github.com/mdlayher/socket v0.5.0 // indirect github.com/miekg/pkcs11 v1.1.1 // indirect github.com/miscreant/miscreant.go v0.0.0-20200214223636-26d376326b75 // indirect github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect github.com/mitchellh/copystructure v1.2.0 // indirect - github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect @@ -270,15 +204,9 @@ require ( github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect github.com/onsi/ginkgo/v2 v2.22.2 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect - github.com/openzipkin-contrib/zipkin-go-opentracing v0.5.0 // indirect - github.com/openzipkin/zipkin-go v0.4.3 // indirect - github.com/oschwald/geoip2-golang v1.11.0 // indirect - github.com/oschwald/maxminddb-golang v1.13.1 // indirect - github.com/outcaste-io/ristretto v0.2.3 // indirect + github.com/pelletier/go-toml/v2 v2.0.9 // indirect github.com/peterbourgon/diskv v2.0.1+incompatible // indirect - github.com/philhofer/fwd v1.1.3-0.20240612014219-fbbf4953d986 // indirect github.com/pierrec/lz4/v4 v4.1.22 // indirect github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect @@ -292,11 +220,7 @@ require ( github.com/rivo/uniseg v0.4.7 // indirect github.com/rubenv/sql-migrate v1.7.1 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/ryanuber/go-glob v1.0.0 // indirect - github.com/secure-systems-lab/go-securesystemslib v0.8.0 // indirect - github.com/shirou/gopsutil/v3 v3.24.4 // indirect github.com/shirou/gopsutil/v4 v4.25.1 // indirect - github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/shopspring/decimal v1.4.0 // indirect github.com/spf13/cast v1.7.0 // indirect github.com/stretchr/objx v0.5.2 // indirect @@ -305,7 +229,6 @@ require ( github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect github.com/tailscale/netlink v1.1.1-0.20240822203006-4d49adab4de7 // indirect github.com/theupdateframework/notary v0.7.0 // indirect - github.com/tinylib/msgp v1.2.1 // indirect github.com/tklauser/go-sysconf v0.3.14 // indirect github.com/tklauser/numcpus v0.9.0 // indirect github.com/ulikunitz/xz v0.5.12 // indirect @@ -317,15 +240,7 @@ require ( github.com/xeipuuv/gojsonschema v1.2.0 // indirect github.com/xlab/treeprint v1.2.0 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect - go.etcd.io/etcd/api/v3 v3.5.20 // indirect - go.etcd.io/etcd/client/pkg/v3 v3.5.20 // indirect - go.etcd.io/etcd/client/v3 v3.5.20 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/collector/component v0.104.0 // indirect - go.opentelemetry.io/collector/config/configtelemetry v0.104.0 // indirect - go.opentelemetry.io/collector/pdata v1.11.0 // indirect - go.opentelemetry.io/collector/pdata/pprofile v0.104.0 // indirect - go.opentelemetry.io/collector/semconv v0.104.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect go.opentelemetry.io/otel v1.35.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.34.0 // indirect @@ -336,27 +251,21 @@ require ( go.opentelemetry.io/otel/sdk/metric v1.35.0 // indirect go.opentelemetry.io/otel/trace v1.35.0 // indirect go.opentelemetry.io/proto/otlp v1.5.0 // indirect - go.uber.org/atomic v1.11.0 // indirect go.uber.org/mock v0.5.0 // indirect - go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.27.0 // indirect go4.org/mem v0.0.0-20220726221520-4f986261bf13 // indirect go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect golang.org/x/exp v0.0.0-20250207012021-f9890c6ad9f3 // indirect golang.org/x/mod v0.23.0 // indirect golang.org/x/sync v0.13.0 // indirect + golang.org/x/text v0.24.0 // indirect golang.org/x/time v0.11.0 // indirect golang.org/x/tools v0.30.0 // indirect - golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 // indirect gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect - google.golang.org/api v0.227.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250414145226-207652e42e2e // indirect - gopkg.in/DataDog/dd-trace-go.v1 v1.72.2 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/fsnotify.v1 v1.4.7 // indirect gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 4a9f4661..e63fcf3a 100644 --- a/go.sum +++ b/go.sum @@ -1,45 +1,13 @@ cel.dev/expr v0.19.1 h1:NciYrtDRIR0lNCnH1LFJegdjspNx9fI59O7TWcua/W4= cel.dev/expr v0.19.1/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= -cloud.google.com/go/auth v0.15.0 h1:Ly0u4aA5vG/fsSsxu98qCQBemXtAtJf+95z9HK+cxps= -cloud.google.com/go/auth v0.15.0/go.mod h1:WJDGqZ1o9E9wKIL+IwStfyn/+s59zl4Bi+1KQNVXLZ8= -cloud.google.com/go/auth/oauth2adapt v0.2.7 h1:/Lc7xODdqcEw8IrZ9SvwnlLX6j9FHQM74z6cBk9Rw6M= -cloud.google.com/go/auth/oauth2adapt v0.2.7/go.mod h1:NTbTTzfvPl1Y3V1nPpOgl2w6d/FjO7NNUQaWSox6ZMc= -cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I= -cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg= dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 h1:He8afgbRMd7mFxO99hRNu+6tazq8nFF9lIwo9JFroBk= github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= -github.com/Azure/azure-sdk-for-go v68.0.0+incompatible h1:fcYLmCpyNYRnvJbPerq7U0hS+6+I79yEDJBqVNcqUzU= -github.com/Azure/azure-sdk-for-go v68.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg= github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= -github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= -github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-autorest/autorest v0.11.28/go.mod h1:MrkzG3Y3AH668QyF9KRk5neJnGgmhQ6krbhR8Q5eMvA= -github.com/Azure/go-autorest/autorest v0.11.30 h1:iaZ1RGz/ALZtN5eq4Nr1SOFSlf2E4pDI3Tcsl+dZPVE= -github.com/Azure/go-autorest/autorest v0.11.30/go.mod h1:t1kpPIOpIVX7annvothKvb0stsrXa37i7b+xpmBW8Fs= -github.com/Azure/go-autorest/autorest/adal v0.9.18/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= -github.com/Azure/go-autorest/autorest/adal v0.9.22/go.mod h1:XuAbAEUv2Tta//+voMI038TrJBqjKam0me7qR+L8Cmk= -github.com/Azure/go-autorest/autorest/adal v0.9.23 h1:Yepx8CvFxwNKpH6ja7RZ+sKX+DWYNldbLiALMC3BTz8= -github.com/Azure/go-autorest/autorest/adal v0.9.23/go.mod h1:5pcMqFkdPhviJdlEy3kC/v1ZLnQl0MH6XA5YCcMhy4c= -github.com/Azure/go-autorest/autorest/azure/auth v0.5.13 h1:Ov8avRZi2vmrE2JcXw+tu5K/yB41r7xK9GZDiBF7NdM= -github.com/Azure/go-autorest/autorest/azure/auth v0.5.13/go.mod h1:5BAVfWLWXihP47vYrPuBKKf4cS0bXI+KM9Qx6ETDJYo= -github.com/Azure/go-autorest/autorest/azure/cli v0.4.6 h1:w77/uPk80ZET2F+AfQExZyEWtn+0Rk/uw17m9fv5Ajc= -github.com/Azure/go-autorest/autorest/azure/cli v0.4.6/go.mod h1:piCfgPho7BiIDdEQ1+g4VmKyD5y+p/XtSNqE6Hc4QD0= -github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw= -github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= -github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= -github.com/Azure/go-autorest/autorest/mocks v0.4.2 h1:PGN4EDXnuQbojHbU0UWoNvmu9AGVwYHG9/fkDYhtAfw= -github.com/Azure/go-autorest/autorest/mocks v0.4.2/go.mod h1:Vy7OitM9Kei0i1Oj+LvyAWMXJHeKH1MVlzFugfVrmyU= -github.com/Azure/go-autorest/autorest/to v0.4.0 h1:oXVqrxakqqV1UZdSazDOPOLvOIz+XA683u8EctwboHk= -github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE= -github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg= -github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= -github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= -github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+s7s0MwaRv9igoPqLRdzOLzw/8Xvq8= github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= @@ -47,36 +15,6 @@ github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c h1:pxW6RcqyfI9/k github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU= github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU= -github.com/DataDog/appsec-internal-go v1.9.0 h1:cGOneFsg0JTRzWl5U2+og5dbtyW3N8XaYwc5nXe39Vw= -github.com/DataDog/appsec-internal-go v1.9.0/go.mod h1:wW0cRfWBo4C044jHGwYiyh5moQV2x0AhnwqMuiX7O/g= -github.com/DataDog/datadog-agent/pkg/obfuscate v0.58.0 h1:nOrRNCHyriM/EjptMrttFOQhRSmvfagESdpyknb5VPg= -github.com/DataDog/datadog-agent/pkg/obfuscate v0.58.0/go.mod h1:MfDvphBMmEMwE3a30h27AtPO7OzmvdoVTiGY1alEmo4= -github.com/DataDog/datadog-agent/pkg/proto v0.58.0 h1:JX2Q0C5QnKcYqnYHWUcP0z7R0WB8iiQz3aWn+kT5DEc= -github.com/DataDog/datadog-agent/pkg/proto v0.58.0/go.mod h1:0wLYojGxRZZFQ+SBbFjay9Igg0zbP88l03TfZaVZ6Dc= -github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.58.0 h1:5hGO0Z8ih0bRojuq+1ZwLFtdgsfO3TqIjbwJAH12sOQ= -github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.58.0/go.mod h1:jN5BsZI+VilHJV1Wac/efGxS4TPtXa1Lh9SiUyv93F4= -github.com/DataDog/datadog-agent/pkg/trace v0.58.0 h1:4AjohoBWWN0nNaeD/0SDZ8lRTYmnJ48CqREevUfSets= -github.com/DataDog/datadog-agent/pkg/trace v0.58.0/go.mod h1:MFnhDW22V5M78MxR7nv7abWaGc/B4L42uHH1KcIKxZs= -github.com/DataDog/datadog-agent/pkg/util/log v0.58.0 h1:2MENBnHNw2Vx/ebKRyOPMqvzWOUps2Ol2o/j8uMvN4U= -github.com/DataDog/datadog-agent/pkg/util/log v0.58.0/go.mod h1:1KdlfcwhqtYHS1szAunsgSfvgoiVsf3mAJc+WvNTnIE= -github.com/DataDog/datadog-agent/pkg/util/scrubber v0.58.0 h1:Jkf91q3tuIer4Hv9CLJIYjlmcelAsoJRMmkHyz+p1Dc= -github.com/DataDog/datadog-agent/pkg/util/scrubber v0.58.0/go.mod h1:krOxbYZc4KKE7bdEDu10lLSQBjdeSFS/XDSclsaSf1Y= -github.com/DataDog/datadog-go/v5 v5.5.0 h1:G5KHeB8pWBNXT4Jtw0zAkhdxEAWSpWH00geHI6LDrKU= -github.com/DataDog/datadog-go/v5 v5.5.0/go.mod h1:K9kcYBlxkcPP8tvvjZZKs/m1edNAUFzBbdpTUKfCsuw= -github.com/DataDog/go-libddwaf/v3 v3.5.1 h1:GWA4ln4DlLxiXm+X7HA/oj0ZLcdCwOS81KQitegRTyY= -github.com/DataDog/go-libddwaf/v3 v3.5.1/go.mod h1:n98d9nZ1gzenRSk53wz8l6d34ikxS+hs62A31Fqmyi4= -github.com/DataDog/go-runtime-metrics-internal v0.0.4-0.20241206090539-a14610dc22b6 h1:bpitH5JbjBhfcTG+H2RkkiUXpYa8xSuIPnyNtTaSPog= -github.com/DataDog/go-runtime-metrics-internal v0.0.4-0.20241206090539-a14610dc22b6/go.mod h1:quaQJ+wPN41xEC458FCpTwyROZm3MzmTZ8q8XOXQiPs= -github.com/DataDog/go-sqllexer v0.0.14 h1:xUQh2tLr/95LGxDzLmttLgTo/1gzFeOyuwrQa/Iig4Q= -github.com/DataDog/go-sqllexer v0.0.14/go.mod h1:KwkYhpFEVIq+BfobkTC1vfqm4gTi65skV/DpDBXtexc= -github.com/DataDog/go-tuf v1.1.0-0.5.2 h1:4CagiIekonLSfL8GMHRHcHudo1fQnxELS9g4tiAupQ4= -github.com/DataDog/go-tuf v1.1.0-0.5.2/go.mod h1:zBcq6f654iVqmkk8n2Cx81E1JnNTMOAx1UEO/wZR+P0= -github.com/DataDog/gostackparse v0.7.0 h1:i7dLkXHvYzHV308hnkvVGDL3BR4FWl7IsXNPz/IGQh4= -github.com/DataDog/gostackparse v0.7.0/go.mod h1:lTfqcJKqS9KnXQGnyQMCugq3u1FP6UZMfWR0aitKFMM= -github.com/DataDog/opentelemetry-mapping-go/pkg/otlp/attributes v0.20.0 h1:fKv05WFWHCXQmUTehW1eEZvXJP65Qv00W4V01B1EqSA= -github.com/DataDog/opentelemetry-mapping-go/pkg/otlp/attributes v0.20.0/go.mod h1:dvIWN9pA2zWNTw5rhDWZgzZnhcfpH++d+8d1SWW6xkY= -github.com/DataDog/sketches-go v1.4.5 h1:ki7VfeNz7IcNafq7yI/j5U/YCkO3LJiMDtXz9OMQbyE= -github.com/DataDog/sketches-go v1.4.5/go.mod h1:7Y8GN8Jf66DLyDhc94zuWA3uHEt/7ttt8jHOBWWrSOg= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= @@ -87,62 +25,29 @@ github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0= github.com/Masterminds/squirrel v1.5.4 h1:uUcX/aBc8O7Fg9kaISIUsHXdKuqehiXAMQTYX8afzqM= github.com/Masterminds/squirrel v1.5.4/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10= -github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/Microsoft/hcsshim v0.12.9 h1:2zJy5KA+l0loz1HzEGqyNnjd3fyZA31ZBCGKacp6lLg= github.com/Microsoft/hcsshim v0.12.9/go.mod h1:fJ0gkFAna6ukt0bLdKB8djt4XIJhF/vEPuoIWYVvZ8Y= +github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc= github.com/Shopify/logrus-bugsnag v0.0.0-20170309145241-6dbc35f2c30d h1:hi6J4K6DKrR4/ljxn6SF6nURyu785wKMuQcjt7H3VCQ= github.com/Shopify/logrus-bugsnag v0.0.0-20170309145241-6dbc35f2c30d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa h1:LHTHcTQiSGT7VVbI0o4wBRNQIgn917usHWOd6VAffYI= github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= +github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= -github.com/apparentlymart/go-cidr v1.1.0 h1:2mAhrMoF+nhXqxTzSZMUzDHkLjmIHC+Zzn4tdgBZjnU= -github.com/apparentlymart/go-cidr v1.1.0/go.mod h1:EBcsNrHc3zQeuaeCeCtQruQm+n9/YjEn/vI25Lg7Gwc= -github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= -github.com/aws/aws-sdk-go v1.55.6 h1:cSg4pvZ3m8dgYcgqB97MrcdjUmZ1BeMYKUxMMB89IPk= -github.com/aws/aws-sdk-go v1.55.6/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= -github.com/aws/aws-sdk-go-v2 v1.36.3 h1:mJoei2CxPutQVxaATCzDUjcZEjVRdpsiiXi2o38yqWM= -github.com/aws/aws-sdk-go-v2 v1.36.3/go.mod h1:LLXuLpgzEbD766Z5ECcRmi8AzSwfZItDtmABVkRLGzg= -github.com/aws/aws-sdk-go-v2/config v1.29.9 h1:Kg+fAYNaJeGXp1vmjtidss8O2uXIsXwaRqsQJKXVr+0= -github.com/aws/aws-sdk-go-v2/config v1.29.9/go.mod h1:oU3jj2O53kgOU4TXq/yipt6ryiooYjlkqqVaZk7gY/U= -github.com/aws/aws-sdk-go-v2/credentials v1.17.62 h1:fvtQY3zFzYJ9CfixuAQ96IxDrBajbBWGqjNTCa79ocU= -github.com/aws/aws-sdk-go-v2/credentials v1.17.62/go.mod h1:ElETBxIQqcxej++Cs8GyPBbgMys5DgQPTwo7cUPDKt8= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 h1:x793wxmUWVDhshP8WW2mlnXuFrO4cOd3HLBroh1paFw= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30/go.mod h1:Jpne2tDnYiFascUEs2AWHJL9Yp7A5ZVy3TNyxaAjD6M= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 h1:ZK5jHhnrioRkUNOc+hOgQKlUL5JeC3S6JgLxtQ+Rm0Q= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34/go.mod h1:p4VfIceZokChbA9FzMbRGz5OV+lekcVtHlPKEO0gSZY= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 h1:SZwFm17ZUNNg5Np0ioo/gq8Mn6u9w19Mri8DnJ15Jf0= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34/go.mod h1:dFZsC0BLo346mvKQLWmoJxT+Sjp+qcVR1tRVHQGOH9Q= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 h1:eAh2A4b5IzM/lum78bZ590jy36+d/aFLgKF/4Vd1xPE= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3/go.mod h1:0yKJC/kb8sAnmlYa6Zs3QVYqaC8ug2AbnNChv5Ox3uA= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 h1:dM9/92u2F1JbDaGooxTq18wmmFzbJRfXfVfy96/1CXM= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15/go.mod h1:SwFBy2vjtA0vZbjjaFtfN045boopadnoVPhu4Fv66vY= -github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.35.2 h1:vlYXbindmagyVA3RS2SPd47eKZ00GZZQcr+etTviHtc= -github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.35.2/go.mod h1:yGhDiLKguA3iFJYxbrQkQiNzuy+ddxesSZYWVeeEH5Q= -github.com/aws/aws-sdk-go-v2/service/sso v1.25.1 h1:8JdC7Gr9NROg1Rusk25IcZeTO59zLxsKgE0gkh5O6h0= -github.com/aws/aws-sdk-go-v2/service/sso v1.25.1/go.mod h1:qs4a9T5EMLl/Cajiw2TcbNt2UNo/Hqlyp+GiuG4CFDI= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.29.1 h1:KwuLovgQPcdjNMfFt9OhUd9a2OwcOKhxfvF4glTzLuA= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.29.1/go.mod h1:MlYRNmYu/fGPoxBQVvBYr9nyr948aY/WLUvwBMBJubs= -github.com/aws/aws-sdk-go-v2/service/sts v1.33.17 h1:PZV5W8yk4OtH1JAuhV2PXwwO9v5G5Aoj+eMCn4T+1Kc= -github.com/aws/aws-sdk-go-v2/service/sts v1.33.17/go.mod h1:cQnB8CUnxbMU82JvlqjKR2HBOm3fe9pWorWBza6MBJ4= -github.com/aws/smithy-go v1.22.2 h1:6D9hW43xKFrRx/tXXfAlIZc4JI+yQe6snnWcQyxSyLQ= -github.com/aws/smithy-go v1.22.2/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= github.com/beorn7/perks v0.0.0-20150223135152-b965b613227f/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bitly/go-hostpool v0.1.0/go.mod h1:4gOCgp6+NZnVqlKyZ/iBZFTAJKembaVENUpMkpg42fw= github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= github.com/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJRUA0wFAVE= @@ -166,7 +71,6 @@ github.com/ccding/go-stun v0.1.5 h1:qEM367nnezmj7dv+SdT52prv5x6HUTG3nlrjX5aitlo= github.com/ccding/go-stun v0.1.5/go.mod h1:cCZjJ1J3WFSJV6Wj8Y9Di8JMTsEXh6uv2eNmLzKaUeM= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= 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/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk= @@ -176,8 +80,6 @@ github.com/chmduquesne/rollinghash v4.0.0+incompatible/go.mod h1:Uc2I36RRfTAf7Dg github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575 h1:kHaBemcxl8o/pQ5VM1c8PVE1PubbNx3mjUr09OqWGCs= -github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575/go.mod h1:9d6lWj8KzO/fd/NrVaLscBKmPigpZpn5YawRPw+e3Yo= github.com/cilium/ebpf v0.16.0 h1:+BiEnHL6Z7lXnlGUsXQPPAE7+kenAd4ES8MQ5min0Ok= github.com/cilium/ebpf v0.16.0/go.mod h1:L7u2Blt2jMM/vLAVgjxluxtBKlz3/GWjB0dMOEngfwE= github.com/cilium/ipam v0.0.0-20230509084518-fd66eae7909b h1:yTDNdo6hd8ABJYeLUvmqKAYj3jaRzLYx3UwM+/jSeBY= @@ -194,14 +96,9 @@ github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpS github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw= github.com/containernetworking/cni v1.1.2 h1:wtRGZVv7olUHMOqouPpn3cXJWpJgM6+EUl31EQbXALQ= github.com/containernetworking/cni v1.1.2/go.mod h1:sDpYKmGVENF3s6uvMvGgldDWeG8dMxakj/u+i9ht9vw= -github.com/coredns/caddy v1.1.2-0.20241029205200-8de985351a98 h1:c+Epklw9xk6BZ1OFBPWLA2PcL8QalKvl3if8CP9x8uw= -github.com/coredns/caddy v1.1.2-0.20241029205200-8de985351a98/go.mod h1:A6ntJQlAWuQfFlsd9hvigKbo2WS0VUs2l1e2F+BawD4= -github.com/coredns/coredns v1.12.1 h1:haptbGscSbdWU46xrjdPj1vp3wvH1Z2FgCSQKEdgN5s= -github.com/coredns/coredns v1.12.1/go.mod h1:V26ngiKdNvAiEre5PTAvklrvTjnNjl6lakq1nbE/NbU= github.com/coreos/go-iptables v0.7.1-0.20240112124308-65c67c9f46e6 h1:8h5+bWd7R6AYUslN6c6iuZWTKsKxUFDlpnmilO6R2n0= github.com/coreos/go-iptables v0.7.1-0.20240112124308-65c67c9f46e6/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= -github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= -github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= +github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf h1:iW4rZ826su+pqaw19uhpSCzhj44qo35pNgKFGqzDKkU= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= @@ -218,20 +115,14 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dblohm7/wingoes v0.0.0-20240119213807-a09d6be7affa h1:h8TfIT1xc8FWbwwpmHn1J5i43Y0uZP97GqasGCzSRJk= github.com/dblohm7/wingoes v0.0.0-20240119213807-a09d6be7affa/go.mod h1:Nx87SkVqTKd8UtT+xu7sM/l+LgXs6c0aHrlKusR+2EQ= +github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= github.com/denisenkom/go-mssqldb v0.0.0-20191128021309-1d7a30a10f73/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= -github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y= -github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= -github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U= -github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= github.com/distribution/distribution/v3 v3.0.0-rc.3 h1:JRJso9IVLoooKX76oWR+DWCCdZlK5m4nRtDWvzB1ITg= github.com/distribution/distribution/v3 v3.0.0-rc.3/go.mod h1:offoOgrnYs+CFwis8nE0hyzYZqRCZj5EFc5kgfszwiE= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/dnstap/golang-dnstap v0.4.0 h1:KRHBoURygdGtBjDI2w4HifJfMAhhOqDuktAokaSa234= -github.com/dnstap/golang-dnstap v0.4.0/go.mod h1:FqsSdH58NAmkAvKcpyxht7i4FoBjKu8E4JUPt8ipSUs= github.com/docker/cli v27.5.1+incompatible h1:JB9cieUT9YNiMITtIsguaN55PLOHhBSz3LKVc6cqWaY= github.com/docker/cli v27.5.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= @@ -257,12 +148,7 @@ github.com/docker/libcontainer v2.2.1+incompatible h1:++SbbkCw+X8vAd4j2gOCzZ2Nn7 github.com/docker/libcontainer v2.2.1+incompatible/go.mod h1:osvj61pYsqhNCMLGX31xr7klUBhHb/ZBuXS0o1Fvwbw= github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 h1:UhxFibDNY/bfvqU5CAUmr9zpesgbU6SWc8/B4mflAE4= github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= -github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= -github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/dvsekhvalnov/jose2go v0.0.0-20170216131308-f21a8cedbbae/go.mod h1:7BvyPhdbLxMXIYTFPLsyJRFMsKmOZnQmzh6Gb+uquuM= -github.com/eapache/queue/v2 v2.0.0-20230407133247-75960ed334e4 h1:8EXxF+tCLqaVk8AOC29zl2mnhQjwyLxxOTuhUazWRsg= -github.com/eapache/queue/v2 v2.0.0-20230407133247-75960ed334e4/go.mod h1:I5sHm0Y0T1u5YjlyqC5GVArM7aNZRUYtTjmJ8mPJFds= github.com/ebitengine/purego v0.8.3 h1:K+0AjQp63JEZTEMZiwsI9g0+hAMNohwUOtY0RPGexmc= github.com/ebitengine/purego v0.8.3/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU= @@ -282,19 +168,12 @@ github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjT github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM= github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f h1:Wl78ApPPB2Wvf/TIe2xdyJxTlb6obmF18d8QdkxNDu4= github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f/go.mod h1:OSYXu++VVOHnXeitef/D8n/6y4QV8uLHSFXX4NeXMGc= -github.com/expr-lang/expr v1.17.2 h1:o0A99O/Px+/DTjEnQiodAgOIK9PPxL8DtXhBRKC+Iso= -github.com/expr-lang/expr v1.17.2/go.mod h1:8/vRC7+7HBzESEqt5kKpYXxrxkr31SaO8r40VO/1IT4= -github.com/farsightsec/golang-framestream v0.3.0 h1:/spFQHucTle/ZIPkYqrfshQqPe2VQEzesH243TjIwqA= -github.com/farsightsec/golang-framestream v0.3.0/go.mod h1:eNde4IQyEiA5br02AouhEHCu3p3UzrCdFR4LuQHklMI= github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8= github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ= -github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/foxcpp/go-mockdns v1.1.0 h1:jI0rD8M0wuYAxL7r/ynTrCQQq0BVqfB99Vgk7DlmewI= github.com/foxcpp/go-mockdns v1.1.0/go.mod h1:IhLeSFGed3mJIAXPH2aiRQB+kqz7oqu8ld2qVbOu7Wk= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= @@ -342,6 +221,7 @@ github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDsl github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU= github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0= github.com/go-sql-driver/mysql v1.3.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= @@ -352,22 +232,15 @@ github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIx github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466 h1:sQspH8M4niEijh3PFscJRLDnkL547IeP7kpPe3uUhEg= github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466/go.mod h1:ZiQxhyQ+bbbfxUKVvjfO498oPYvtYhZzycal3G/NHmU= github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= -github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= -github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= -github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI= -github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ= github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -394,7 +267,6 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= @@ -409,17 +281,10 @@ github.com/google/nftables v0.2.1-0.20240414091927-5e242ec57806/go.mod h1:Beg6V6 github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20250202011525-fc3143867406 h1:wlQI2cYY0BsWmmPPAnxfQ8SDW0S3Jasn+4B8kXFxprg= github.com/google/pprof v0.0.0-20250202011525-fc3143867406/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= -github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= -github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4= -github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA= -github.com/googleapis/gax-go/v2 v2.14.1 h1:hb0FFeiPaQskmvakKu5EbCbpntQn48jyHuvrkurSS/Q= -github.com/googleapis/gax-go/v2 v2.14.1/go.mod h1:Hb/NubMaVM88SrNkvl8X/o8XWwDJEPqouaLeN2IUxoA= github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE= github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w= github.com/gorilla/mux v1.7.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= @@ -440,29 +305,18 @@ github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJr github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 h1:VNqngBF40hVlDloBruUehVYC3ArSgIyScOAyMRqBxRg= github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1/go.mod h1:RBRO7fro65R6tjKzYgLAFo0t1QEXY1Dp+i/bvpRiqiQ= -github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 h1:MJG/KsmcqMwFAkh8mTnAwhyKoB+sTAnY4CACC110tbU= -github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-secure-stdlib/parseutil v0.1.7 h1:UpiO20jno/eV1eVZcxqWnUohyKRe1g8FPV/xH1s/2qs= -github.com/hashicorp/go-secure-stdlib/parseutil v0.1.7/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8= -github.com/hashicorp/go-secure-stdlib/strutil v0.1.1/go.mod h1:gKOamz3EwoIoJq7mlMIRBpVTAUn8qPCrEclOKKWhD3U= -github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts= -github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4= -github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc= -github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= github.com/hashicorp/golang-lru/arc/v2 v2.0.5 h1:l2zaLDubNhW4XO3LnliVj0GXO3+/CGNJAg1dcN2Fpfw= github.com/hashicorp/golang-lru/arc/v2 v2.0.5/go.mod h1:ny6zBSQZi2JxIeYcv7kt2sH2PXJtirBN7RDhRpxPkxU= github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= @@ -481,8 +335,6 @@ github.com/illarion/gonotify/v2 v2.0.3/go.mod h1:38oIJTgFqupkEydkkClkbL6i5lXV/bx github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/infobloxopen/go-trees v0.0.0-20221216143356-66ceba885ebc h1:RhT2pjLo3EVRmldbEcBdeRA7CGPWsNEJC+Y/N1aXQbg= -github.com/infobloxopen/go-trees v0.0.0-20221216143356-66ceba885ebc/go.mod h1:BaIJzjD2ZnHmx2acPF6XfGLPzNCMiBbMRqJr+8/8uRI= github.com/jackpal/gateway v1.0.16 h1:mTBRuHSW8qviVqX7kXnxKevqlfS/OA01ys6k6fxSX7w= github.com/jackpal/gateway v1.0.16/go.mod h1:IOn1OUbso/cGYmnCBZbCEqhNCLSz0xxdtIpUpri5/nA= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= @@ -505,11 +357,8 @@ github.com/jinzhu/gorm v1.9.16/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBef github.com/jinzhu/inflection v0.0.0-20170102125226-1c35d901db3d/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= -github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= -github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= -github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= -github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o= github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= @@ -552,6 +401,7 @@ github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtB github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 h1:P6pPBnrTSX3DEVR4fDembhRWSsG5rVo6hYhAB/ADZrk= github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw= github.com/lib/pq v0.0.0-20150723085316-0dad96c0b94f/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU= @@ -560,7 +410,6 @@ github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhn github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= github.com/lithammer/dedent v1.1.0 h1:VNzHMVCBNG1j0fh3OrsFRkVUwStdDArbgBWoPAffktY= github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc= -github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683 h1:7UMa6KCCMjZEMDtTVdcGu0B1GmmC7QJKiCCjyTAWQy0= github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k= github.com/magiconair/properties v1.5.3/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= @@ -570,26 +419,22 @@ github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4 github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mattbaird/jsonpatch v0.0.0-20240118010651-0ba75a80ca38 h1:hQWBtNqRYrI7CWIaUSXXtNKR90KzcUA5uiuxFVWw7sU= github.com/mattbaird/jsonpatch v0.0.0-20240118010651-0ba75a80ca38/go.mod h1:M1qoD/MqPgTZIk0EWKB38wE28ACRfVcn+cU08jyArI0= -github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.6.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus= github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= -github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/mdlayher/netlink v1.7.2 h1:/UtM3ofJap7Vl4QWCPDGXY8d3GIY2UGSDbK+QWmY8/g= github.com/mdlayher/netlink v1.7.2/go.mod h1:xraEF7uJbxLhc5fpHL4cPe221LI2bdttWlU+ZGLfQSw= github.com/mdlayher/socket v0.5.0 h1:ilICZmJcQz70vrWVes1MFera4jGiWNocSkykwwoy3XI= github.com/mdlayher/socket v0.5.0/go.mod h1:WkcBFfvyG8QENs5+hfQPl1X6Jpd2yeLIYgrGFmJiJxI= -github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/miekg/dns v1.1.64 h1:wuZgD9wwCE6XMT05UU/mlSko71eRSXEAm2EbjQXLKnQ= github.com/miekg/dns v1.1.64/go.mod h1:Dzw9769uoKVaLuODMDZz9M6ynFU6Em65csPuoi8G0ck= github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= @@ -597,18 +442,13 @@ github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU= github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/miscreant/miscreant.go v0.0.0-20200214223636-26d376326b75 h1:cUVxyR+UfmdEAZGJ8IiKld1O0dbGotEnkMolG5hfMSY= github.com/miscreant/miscreant.go v0.0.0-20200214223636-26d376326b75/go.mod h1:pBbZyGwC5i16IBkjVKoy/sznA8jPD/K9iedwe1ESE6w= -github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= -github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= github.com/mitchellh/mapstructure v0.0.0-20150613213606-2caf8efc9366/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c h1:cqn374mizHuIWj+OSJCajGr/phAmuMug9qIX3l9CflE= github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= @@ -666,30 +506,15 @@ github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3I github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M= -github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492 h1:lM6RxxfUMrYL/f8bWEUqdXrANWtrL7Nndbm9iFN0DlU= -github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= -github.com/openzipkin-contrib/zipkin-go-opentracing v0.5.0 h1:uhcF5Jd7rP9DVEL10Siffyepr6SvlKbUsjH5JpNCRi8= -github.com/openzipkin-contrib/zipkin-go-opentracing v0.5.0/go.mod h1:+oCZ5GXXr7KPI/DNOQORPTq5AWHfALJj9c72b0+YsEY= -github.com/openzipkin/zipkin-go v0.4.3 h1:9EGwpqkgnwdEIJ+Od7QVSEIH+ocmm5nPat0G7sjsSdg= -github.com/openzipkin/zipkin-go v0.4.3/go.mod h1:M9wCJZFWCo2RiY+o1eBCEMe0Dp2S5LDHcMZmk3RmK7c= -github.com/oschwald/geoip2-golang v1.11.0 h1:hNENhCn1Uyzhf9PTmquXENiWS6AlxAEnBII6r8krA3w= -github.com/oschwald/geoip2-golang v1.11.0/go.mod h1:P9zG+54KPEFOliZ29i7SeYZ/GM6tfEL+rgSn03hYuUo= -github.com/oschwald/maxminddb-golang v1.13.1 h1:G3wwjdN9JmIK2o/ermkHM+98oX5fS+k5MbwsmL4MRQE= -github.com/oschwald/maxminddb-golang v1.13.1/go.mod h1:K4pgV9N/GcK694KSTmVSDTODk4IsCNThNdTmnaBZ/F8= -github.com/outcaste-io/ristretto v0.2.3 h1:AK4zt/fJ76kjlYObOeNwh4T3asEuaCmp26pOvUOL9w0= -github.com/outcaste-io/ristretto v0.2.3/go.mod h1:W8HywhmtlopSB1jeMg3JtdIhf+DYkLAr0VN/s4+MHac= -github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml/v2 v2.0.9 h1:uH2qQXheeefCCkuBBSLi7jCiSmj3VRh2+Goq2N7Xxu0= github.com/pelletier/go-toml/v2 v2.0.9/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 h1:Ii+DKncOVM8Cu1Hc+ETb5K+23HdAMvESYE3ZJ5b5cMI= github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= -github.com/philhofer/fwd v1.1.3-0.20240612014219-fbbf4953d986 h1:jYi87L8j62qkXzaYHAQAhEapgukhenIMZRBKTNRLHJ4= -github.com/philhofer/fwd v1.1.3-0.20240612014219-fbbf4953d986/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM= github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU= github.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -701,8 +526,6 @@ github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU= github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/poy/onpar v1.1.2 h1:QaNrNiZx0+Nar5dLgTVp5mXkyoVFIbepjyEoGSnhbAY= @@ -745,10 +568,6 @@ github.com/redis/go-redis/v9 v9.1.0 h1:137FnGdk+EQdCbye1FW+qOEcY5S+SpY9T0Niuqvtf github.com/redis/go-redis/v9 v9.1.0/go.mod h1:urWj3He21Dj5k4TK1y59xH8Uj6ATueP8AH1cY3lZl4c= github.com/regclient/regclient v0.8.0 h1:xNAMDlADcyMvFAlGXoqDOxlSUBG4mqWBFgjQqVTP8Og= github.com/regclient/regclient v0.8.0/go.mod h1:h9+Y6dBvqBkdlrj6EIhbTOv0xUuIFl7CdI1bZvEB42g= -github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= -github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= -github.com/richardartoul/molecule v1.0.1-0.20240531184615-7ca0df43c0b3 h1:4+LEVOB87y175cLJC/mbsgKmoDOjrBldtXvioEy96WY= -github.com/richardartoul/molecule v1.0.1-0.20240531184615-7ca0df43c0b3/go.mod h1:vl5+MqJ1nBINuSsUI2mGgH79UweUT/B5Fy8857PqyyI= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= @@ -758,33 +577,19 @@ github.com/rubenv/sql-migrate v1.7.1 h1:f/o0WgfO/GqNuVg+6801K/KW3WdDSupzSjDYODmi github.com/rubenv/sql-migrate v1.7.1/go.mod h1:Ob2Psprc0/3ggbM6wCzyYVFFuc6FyZrb2AS+ezLDFb4= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= -github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= github.com/schollz/progressbar/v3 v3.14.2 h1:EducH6uNLIWsr560zSV1KrTeUb/wZGAHqyMFIEa99ks= github.com/schollz/progressbar/v3 v3.14.2/go.mod h1:aQAZQnhF4JGFtRJiw/eobaXpsqpVQAftEQ+hLGXaRc4= -github.com/secure-systems-lab/go-securesystemslib v0.8.0 h1:mr5An6X45Kb2nddcFlbmfHkLguCE9laoZCUzEEpIZXA= -github.com/secure-systems-lab/go-securesystemslib v0.8.0/go.mod h1:UH2VZVuJfCYR8WgMlCU1uFsOUU+KeyrTWcSS73NBOzU= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= -github.com/shirou/gopsutil/v3 v3.24.4 h1:dEHgzZXt4LMNm+oYELpzl9YCqV65Yr/6SfrvgRBtXeU= -github.com/shirou/gopsutil/v3 v3.24.4/go.mod h1:lTd2mdiOspcqLgAnr9/nGi71NkeMpWKdmhuxm9GusH8= github.com/shirou/gopsutil/v4 v4.25.1 h1:QSWkTc+fu9LTAWfkZwZ6j8MSUk4A2LV7rbH0ZqmLjXs= github.com/shirou/gopsutil/v4 v4.25.1/go.mod h1:RoUCUpndaJFtT+2zsZzzmhvbfGoDCJ7nFXKJf8GqJbI= -github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= -github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= -github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= -github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= -github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= -github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.10.0 h1:EaGW2JJh15aKOejeuJ+wpFSHnbd7GE6Wvp3TsNhb6LY= github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= github.com/spf13/cast v0.0.0-20150508191742-4d07383ffe94/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg= @@ -819,9 +624,7 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= @@ -838,12 +641,8 @@ github.com/thejerf/suture/v4 v4.0.6 h1:QsuCEsCqb03xF9tPAsWAj8QOAJBgQI1c0VqJNaing github.com/thejerf/suture/v4 v4.0.6/go.mod h1:gu9Y4dXNUWFrByqRt30Rm9/UZ0wzRSt9AJS6xu/ZGxU= github.com/theupdateframework/notary v0.7.0 h1:QyagRZ7wlSpjT5N2qQAh/pN+DVqgekv4DzbAiAiEL3c= github.com/theupdateframework/notary v0.7.0/go.mod h1:c9DRxcmhHmVLDay4/2fUYdISnHqbFDGRSlXPO0AhYWw= -github.com/tinylib/msgp v1.2.1 h1:6ypy2qcCznxpP4hpORzhtXyTqrBs7cfM9MCCWY8zsmU= -github.com/tinylib/msgp v1.2.1/go.mod h1:2vIGs3lcUo8izAATNobrCHevYZC/LMsJtw4JPiYPHro= -github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= github.com/tklauser/go-sysconf v0.3.14 h1:g5vzr9iPFFz24v2KZXs/pvpvh8/V9Fw6vQK5ZZb78yU= github.com/tklauser/go-sysconf v0.3.14/go.mod h1:1ym4lWMLUOhuBOPGtRcJm7tEGX4SCYNEEEtghGG/8uY= -github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= github.com/tklauser/numcpus v0.9.0 h1:lmyCHtANi8aRUgkckBgoDk1nHCux3n2cgkJLXdQGPDo= github.com/tklauser/numcpus v0.9.0/go.mod h1:SN6Nq1O3VychhC1npsWostA+oW+VOQTxZrS604NSRyI= github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc= @@ -853,10 +652,6 @@ github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1Y github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= github.com/vitrun/qart v0.0.0-20160531060029-bf64b92db6b0 h1:okhMind4q9H1OxF44gNegWkiP4H/gsTFLalHFa4OOUI= github.com/vitrun/qart v0.0.0-20160531060029-bf64b92db6b0/go.mod h1:TTbGUfE+cXXceWtbTHq6lqcTvYPBKLNejBEbnUsQJtU= -github.com/vmihailenco/msgpack/v4 v4.3.12 h1:07s4sz9IReOgdikxLTKNbBdqDMLsjPKXwvCazn8G65U= -github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= -github.com/vmihailenco/tagparser v0.1.2 h1:gnjoVuB/kljJ5wICEEOpx98oXMWPLj22G67Vbd1qPqc= -github.com/vmihailenco/tagparser v0.1.2/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= @@ -870,28 +665,11 @@ github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= -go.etcd.io/etcd/api/v3 v3.5.20 h1:aKfz3nPZECWoZJXMSH9y6h2adXjtOHaHTGEVCuCmaz0= -go.etcd.io/etcd/api/v3 v3.5.20/go.mod h1:QqKGViq4KTgOG43dr/uH0vmGWIaoJY3ggFi6ZH0TH/U= -go.etcd.io/etcd/client/pkg/v3 v3.5.20 h1:sZIAtra+xCo56gdf6BR62to/hiie5Bwl7hQIqMzVTEM= -go.etcd.io/etcd/client/pkg/v3 v3.5.20/go.mod h1:qaOi1k4ZA9lVLejXNvyPABrVEe7VymMF2433yyRQ7O0= -go.etcd.io/etcd/client/v3 v3.5.20 h1:jMT2MwQEhyvhQg49Cec+1ZHJzfUf6ZgcmV0GjPv0tIQ= -go.etcd.io/etcd/client/v3 v3.5.20/go.mod h1:J5lbzYRMUR20YolS5UjlqqMcu3/wdEvG5VNBhzyo3m0= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/collector/component v0.104.0 h1:jqu/X9rnv8ha0RNZ1a9+x7OU49KwSMsPbOuIEykHuQE= -go.opentelemetry.io/collector/component v0.104.0/go.mod h1:1C7C0hMVSbXyY1ycCmaMUAR9fVwpgyiNQqxXtEWhVpw= -go.opentelemetry.io/collector/config/configtelemetry v0.104.0 h1:eHv98XIhapZA8MgTiipvi+FDOXoFhCYOwyKReOt+E4E= -go.opentelemetry.io/collector/config/configtelemetry v0.104.0/go.mod h1:WxWKNVAQJg/Io1nA3xLgn/DWLE/W1QOB2+/Js3ACi40= -go.opentelemetry.io/collector/pdata v1.11.0 h1:rzYyV1zfTQQz1DI9hCiaKyyaczqawN75XO9mdXmR/hE= -go.opentelemetry.io/collector/pdata v1.11.0/go.mod h1:IHxHsp+Jq/xfjORQMDJjSH6jvedOSTOyu3nbxqhWSYE= -go.opentelemetry.io/collector/pdata/pprofile v0.104.0 h1:MYOIHvPlKEJbWLiBKFQWGD0xd2u22xGVLt4jPbdxP4Y= -go.opentelemetry.io/collector/pdata/pprofile v0.104.0/go.mod h1:7WpyHk2wJZRx70CGkBio8klrYTTXASbyIhf+rH4FKnA= -go.opentelemetry.io/collector/semconv v0.104.0 h1:dUvajnh+AYJLEW/XOPk0T0BlwltSdi3vrjO7nSOos3k= -go.opentelemetry.io/collector/semconv v0.104.0/go.mod h1:yMVUCNoQPZVq/IPfrHrnntZTWsLf5YGZ7qwKulIl5hw= go.opentelemetry.io/contrib/bridges/prometheus v0.57.0 h1:UW0+QyeyBVhn+COBec3nGhfnFe5lwB0ic1JBVjzhk0w= go.opentelemetry.io/contrib/bridges/prometheus v0.57.0/go.mod h1:ppciCHRLsyCio54qbzQv0E4Jyth/fLWDTJYfvWpcSVk= go.opentelemetry.io/contrib/exporters/autoexport v0.57.0 h1:jmTVJ86dP60C01K3slFQa2NQ/Aoi7zA+wy7vMOKD9H4= @@ -936,9 +714,6 @@ go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4= go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4= -go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= -go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs= go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -957,14 +732,13 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= @@ -976,7 +750,6 @@ golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPI golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= @@ -984,20 +757,20 @@ golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM= golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= @@ -1018,7 +791,6 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= @@ -1027,7 +799,6 @@ golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610= golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= -golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180926160741-c2ed4eda69e7/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1037,7 +808,6 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1049,16 +819,12 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1068,11 +834,8 @@ golang.org/x/sys v0.4.1-0.20230131160137-e7d7f63158de/go.mod h1:oPkhp1MJrh7nUepC golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= @@ -1084,7 +847,6 @@ golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuX golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= -golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= @@ -1106,12 +868,10 @@ golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= @@ -1123,8 +883,6 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 h1:LLhsEBxRTBLuKlQxFBYUOU8xyFgXv6cOTp2HASDlsDk= -golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg= golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI= golang.zx2c4.com/wireguard v0.0.0-20220920152132-bb719d3a6e2c h1:Okh6a1xpnJslG9Mn84pId1Mn+Q8cvpo4HCeeFWHo0cA= @@ -1133,10 +891,6 @@ golang.zx2c4.com/wireguard/windows v0.5.3 h1:On6j2Rpn3OEMXqBq00QEDC7bWSZrPIHKIus golang.zx2c4.com/wireguard/windows v0.5.3/go.mod h1:9TEe8TJmtwyQebdFwAkEWOPr3prrtqm+REGFifP60hI= gomodules.xyz/jsonpatch/v2 v2.5.0 h1:JELs8RLM12qJGXU4u/TO3V25KW8GreMKl9pdkk14RM0= gomodules.xyz/jsonpatch/v2 v2.5.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= -google.golang.org/api v0.227.0 h1:QvIHF9IuyG6d6ReE+BNd11kIB8hZvjN8Z5xY5t21zYc= -google.golang.org/api v0.227.0/go.mod h1:EIpaG6MbTgQarWF5xJvX0eOJPK9n/5D4Bynb9j2HXvQ= -google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= -google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a h1:OQ7sHVzkx6L57dQpzUS4ckfWJ51KDH74XHTDe23xWAs= google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a/go.mod h1:2R6XrVC8Oc08GlNh8ujEpc7HkLiEZ16QeY7FxIs20ac= google.golang.org/genproto/googleapis/rpc v0.0.0-20250414145226-207652e42e2e h1:ztQaXfzEXTmCBvbtWYRhJxW+0iJcz2qXfd38/e9l7bA= @@ -1154,8 +908,6 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= -gopkg.in/DataDog/dd-trace-go.v1 v1.72.2 h1:SLcih9LB+I1l76Wd7aUSpzISemewzjq6djntMnBnzkA= -gopkg.in/DataDog/dd-trace-go.v1 v1.72.2/go.mod h1:XqDhDqsLpThFnJc4z0FvAEItISIAUka+RHwmQ6EfN1U= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/cenkalti/backoff.v2 v2.2.1 h1:eJ9UAg01/HIHG987TwxvnzK2MgxXq97YY6rYDpY9aII= @@ -1217,26 +969,6 @@ k8s.io/kubectl v0.32.3 h1:VMi584rbboso+yjfv0d8uBHwwxbC438LKq+dXd5tOAI= k8s.io/kubectl v0.32.3/go.mod h1:6Euv2aso5GKzo/UVMacV6C7miuyevpfI91SvBvV9Zdg= k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e h1:KqK5c/ghOm8xkHYhlodbp6i6+r+ChV2vuAuVRdFbLro= k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -lukechampine.com/uint128 v1.3.0 h1:cDdUVfRwDUDovz610ABgFD17nXD4/uDgVHl2sC3+sbo= -lukechampine.com/uint128 v1.3.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= -modernc.org/cc/v3 v3.41.0 h1:QoR1Sn3YWlmA1T4vLaKZfawdVtSiGx8H+cEojbC7v1Q= -modernc.org/cc/v3 v3.41.0/go.mod h1:Ni4zjJYJ04CDOhG7dn640WGfwBzfE0ecX8TyMB0Fv0Y= -modernc.org/ccgo/v3 v3.16.15 h1:KbDR3ZAVU+wiLyMESPtbtE/Add4elztFyfsWoNTgxS0= -modernc.org/ccgo/v3 v3.16.15/go.mod h1:yT7B+/E2m43tmMOT51GMoM98/MtHIcQQSleGnddkUNI= -modernc.org/libc v1.37.6 h1:orZH3c5wmhIQFTXF+Nt+eeauyd+ZIt2BX6ARe+kD+aw= -modernc.org/libc v1.37.6/go.mod h1:YAXkAZ8ktnkCKaN9sw/UDeUVkGYJ/YquGO4FTi5nmHE= -modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= -modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= -modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E= -modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E= -modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= -modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= -modernc.org/sqlite v1.28.0 h1:Zx+LyDDmXczNnEQdvPuEfcFVA2ZPyaD7UCZDjef3BHQ= -modernc.org/sqlite v1.28.0/go.mod h1:Qxpazz0zH8Z1xCFyi5GSL3FzbtZ3fvbjmywNogldEW0= -modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= -modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= -modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= -modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= oras.land/oras-go/v2 v2.5.0 h1:o8Me9kLY74Vp5uw07QXPiitjsw7qNXi8Twd+19Zf02c= oras.land/oras-go/v2 v2.5.0/go.mod h1:z4eisnLP530vwIOUOJeBIj0aGI0L1C3d53atvCBqZHg= sigs.k8s.io/controller-runtime v0.20.4 h1:X3c+Odnxz+iPTRobG4tp092+CvBU9UK0t/bRf+n0DGU= diff --git a/go.work.sum b/go.work.sum index 6ea4ac60..f6fea2cb 100644 --- a/go.work.sum +++ b/go.work.sum @@ -1,670 +1,7 @@ -4d63.com/gocheckcompilerdirectives v1.2.1/go.mod h1:yjDJSxmDTtIHHCqX0ufRYZDL6vQtMG7tJdKVeWwsqvs= -4d63.com/gochecknoglobals v0.2.1/go.mod h1:KRE8wtJB3CXCsb1xy421JfTHIIbmT3U5ruxw2Qu8fSU= -cloud.google.com/go v0.112.2 h1:ZaGT6LiG7dBzi6zNOvVZwacaXlmf3lRqnC4DQzqyRQw= -cloud.google.com/go v0.112.2/go.mod h1:iEqjp//KquGIJV/m+Pk3xecgKNhV+ry+vVTsy4TbDms= -cloud.google.com/go v0.120.0 h1:wc6bgG9DHyKqF5/vQvX1CiZrtHnxJjBlKUyF9nP6meA= -cloud.google.com/go v0.120.0/go.mod h1:/beW32s8/pGRuj4IILWQNd4uuebeT4dkOhKmkfit64Q= -cloud.google.com/go/accessapproval v1.8.5/go.mod h1:aO61iJuMRAaugpD0rWgpwj9aXvWimCWTEbA/kYAFddE= -cloud.google.com/go/accesscontextmanager v1.9.5/go.mod h1:i6WSokkuePCT3jWwRzhge/pZicoErUBbDWjAUd8AoQU= -cloud.google.com/go/aiplatform v1.81.0/go.mod h1:uwLaCFXLvVnKzxl3OXQRw1Hry3KJOIgpofYorq0ZMPk= -cloud.google.com/go/analytics v0.27.1/go.mod h1:2itQDvSWyGiBvs80ocjFjfu/ZUIo25fC93hsEX4fnoU= -cloud.google.com/go/apigateway v1.7.5/go.mod h1:iJ9zoE4KMNF1CHBFV4pZDCJRZzonqKj4BECymhvAwWk= -cloud.google.com/go/apigeeconnect v1.7.5/go.mod h1:XAGnQGiFakRMV3H6bawRb5JAIXIbFSfzGKLDqL1dYgQ= -cloud.google.com/go/apigeeregistry v0.9.5/go.mod h1:e6oNKW1utj+A1fpTw+YUpPkFusNT8gfFbqx/8upsgCY= -cloud.google.com/go/appengine v1.9.5/go.mod h1:x4zKNF1qRX++Joni0nQFJoNobodzWX1bieiGRMWx+4U= -cloud.google.com/go/area120 v0.9.5/go.mod h1:1rAIWfyOiCXk/kuTqFU//pfrHiA8GM8LziM79Lm0zxk= -cloud.google.com/go/artifactregistry v1.16.3/go.mod h1:eiLO70Qh5Z9Jbwctl0KdW5VzJ5HncWgNaYN0NdF8lmM= -cloud.google.com/go/asset v1.20.5/go.mod h1:0pbY+F3Pr3teQLK1ZXpUjGPNBPfUiL1tpxRxRmLCV/c= -cloud.google.com/go/assuredworkloads v1.12.5/go.mod h1:OHjBWxs611PdU/VkGDoNQ/SFZHIYQTPtZlfDAUWN8K0= -cloud.google.com/go/automl v1.14.6/go.mod h1:mEn1QHZmPTnmrq6zj33gyKX1K7L32izry14I6LQCO5M= -cloud.google.com/go/baremetalsolution v1.3.5/go.mod h1:FfLWTwf9g7MVh0jhomxs1ErK9J/E9GBALdsunmFo50Q= -cloud.google.com/go/batch v1.12.1/go.mod h1:hB6jwKyX2zoFoIXw6/pT2CPIbvo0ya7mpQXFJ9QbnAY= -cloud.google.com/go/beyondcorp v1.1.5/go.mod h1:C77HvHG9ntYvI3+/WXht0tqx/fNxfD4MahSutTOkJYg= -cloud.google.com/go/bigquery v1.67.0/go.mod h1:HQeP1AHFuAz0Y55heDSb0cjZIhnEkuwFRBGo6EEKHug= -cloud.google.com/go/bigtable v1.36.0/go.mod h1:u98oqNAXiAufepkRGAd95lq2ap4kHGr3wLeFojvJwew= -cloud.google.com/go/billing v1.20.3/go.mod h1:DJt75ird7g3zrTODh2Eo8ZT2d3jtoEI5L6qNXIHwOY0= -cloud.google.com/go/binaryauthorization v1.9.4/go.mod h1:LimAql4UPC7B/F+RW9rQpsUpzDFNO+VKwVRyHG9txKU= -cloud.google.com/go/certificatemanager v1.9.4/go.mod h1:KneWp8OAhBVD4fqMUB6daOA90MHh9xVB8E3ZFN8w2dc= -cloud.google.com/go/channel v1.19.4/go.mod h1:W82e3qLLe9wvZShy3aAg/6frvMYOdHKSaIwTLJT2Yxs= -cloud.google.com/go/cloudbuild v1.22.1/go.mod h1:/3syBgG56xUK1UD8dXAOSnPWF4Cs0ZZ/eXhoTIBipwg= -cloud.google.com/go/clouddms v1.8.6/go.mod h1:++xrkEPp1mAKZKFk3MMD63UkK7KpnSBt9kRLRSOYliE= -cloud.google.com/go/cloudtasks v1.13.5/go.mod h1:AReQFk11yF7sHEOKHXP3/SufAeiHn4yXWpqQGds9Of0= -cloud.google.com/go/compute v1.25.1 h1:ZRpHJedLtTpKgr3RV1Fx23NuaAEN1Zfx9hw1u4aJdjU= -cloud.google.com/go/compute v1.25.1/go.mod h1:oopOIR53ly6viBYxaDhBfJwzUAxf1zE//uf3IB011ls= -cloud.google.com/go/compute v1.36.0 h1:QzLrJRxytIGE8OJWzmMweIdiu2pIlRVq9kSi7+xnDkU= -cloud.google.com/go/compute v1.36.0/go.mod h1:+GZuz5prSWFLquViP55zcjRrOm7vRpIllx2MaYpzuiI= -cloud.google.com/go/contactcenterinsights v1.17.2/go.mod h1:9yuX5Y7KFqsQgNydM7WeuGcYWWs/0dBCElXaOF6ltmo= -cloud.google.com/go/container v1.42.3/go.mod h1:8ZT9RBJXjWXqRMM/sEW8dxolZUofxKJUaO9mMXSkDz0= -cloud.google.com/go/containeranalysis v0.14.0/go.mod h1:vct7OEtK07Azaiyo6aCyae4teFL28t7JZQkr1DlTC5s= -cloud.google.com/go/datacatalog v1.25.0/go.mod h1:Bodb/U9ZV549+0sQPoX6WtYnbFwqayuYldw5p6PmbH4= -cloud.google.com/go/dataflow v0.10.5/go.mod h1:rLRbgv1ZK34XW72xrmJysN7z0PCwgsh0wtjWx5Yavoc= -cloud.google.com/go/dataform v0.11.1/go.mod h1:2TYH+Dmqnx9ewr/YG8HbMpcNQBX5gdCyP8W/8GwprWk= -cloud.google.com/go/datafusion v1.8.5/go.mod h1:xMoW16ciCOQpS8rNUDU1tWgHkhbQ3KKaV9o7UTggEtQ= -cloud.google.com/go/datalabeling v0.9.5/go.mod h1:xJzHTfjCvPeF87QreDSFTl98mRS/vp47EWwDBHvQiMU= -cloud.google.com/go/dataplex v1.24.0/go.mod h1:rNqsuS0Yag0NDGybhNpCaeqU/Jq8z4gFqqF0MUajHwE= -cloud.google.com/go/dataproc/v2 v2.11.1/go.mod h1:KDbkJUYjcz+t8nfapg0upz665P0SrsDW7I9RC9GZf4o= -cloud.google.com/go/dataqna v0.9.5/go.mod h1:UFRToVzSTCgwDkeSa4J0WE6bmbemdOZhUCUfs+DlJFc= -cloud.google.com/go/datastore v1.20.0/go.mod h1:uFo3e+aEpRfHgtp5pp0+6M0o147KoPaYNaPAKpfh8Ew= -cloud.google.com/go/datastream v1.14.0/go.mod h1:H0luYVOhiyUrzE2efbv1OHFRjzgZfHO9snDuBXmnQXE= -cloud.google.com/go/deploy v1.26.4/go.mod h1:MaPXP4rU984LmRF+DmJ1qNEZrTI7Rez+hfku0oRudTk= -cloud.google.com/go/dialogflow v1.68.1/go.mod h1:CpfTOpLjhM9ZXu+VzJ56xrX9GMBJt1aIjPMChiLUGso= -cloud.google.com/go/dlp v1.22.0/go.mod h1:2cMTKdeReZI64BDsYzsBZFtXdDqb3nhDKHRsRUl7J9Y= -cloud.google.com/go/documentai v1.36.0/go.mod h1:LsX1RO08WDd8mFBviYB03jgCytz2oIcwIZ9lBw5bKiM= -cloud.google.com/go/domains v0.10.5/go.mod h1:VP7djhZJy47uxUoJGfDilXpUnAaIExcHL86vv3yfaQs= -cloud.google.com/go/edgecontainer v1.4.2/go.mod h1:MhrgxorZIp/4myFe2a/Y0OHSx8PCxeyHBRZATvcTTZs= -cloud.google.com/go/errorreporting v0.3.2/go.mod h1:s5kjs5r3l6A8UUyIsgvAhGq6tkqyBCUss0FRpsoVTww= -cloud.google.com/go/essentialcontacts v1.7.5/go.mod h1:AzwvwPKMUnf8bwfLP0R/+BjzC7bi3OTaLABtUF/q428= -cloud.google.com/go/eventarc v1.15.4/go.mod h1:E5vNWMxaZOwfMfQlQOsoE5TY07tKtOiMLF9s99/btyo= -cloud.google.com/go/filestore v1.10.1/go.mod h1:uZfxcuSzAK8NZGflw9bvB0YOT2O8vhyfEVaFAG+vTkg= -cloud.google.com/go/firestore v1.18.0/go.mod h1:5ye0v48PhseZBdcl0qbl3uttu7FIEwEYVaWm0UIEOEU= -cloud.google.com/go/functions v1.19.4/go.mod h1:qmx3Yrm8ZdwQrWplvnpoL4tHW7s8ULNKwP2SjfX9zSM= -cloud.google.com/go/gkebackup v1.6.4/go.mod h1:ZYY7CdiOKobk3gzEKBbRymaEo22bkR1EPkwZ7Tvts/U= -cloud.google.com/go/gkeconnect v0.12.3/go.mod h1:Ra5w3QcA+ybM2hopIz4ZsQQsDqzoYws3Zn21CLGzfrw= -cloud.google.com/go/gkehub v0.15.5/go.mod h1:hIIoZAGNuiKWp6y4fW9JCEPg9xM7OX9sZwgiJrozrWQ= -cloud.google.com/go/gkemulticloud v1.5.2/go.mod h1:THwE0upZyYmgjEZtgbvGkf0VRkEdPkML9dF/J3lSahg= -cloud.google.com/go/gsuiteaddons v1.7.6/go.mod h1:TPlgcxjwv+L3fx9S6El4dDWItBxJpIyYTs4YPk6Zc48= -cloud.google.com/go/iam v1.1.7/go.mod h1:J4PMPg8TtyurAUvSmPj8FF3EDgY1SPRZxcUGrn7WXGA= -cloud.google.com/go/iam v1.5.0/go.mod h1:U+DOtKQltF/LxPEtcDLoobcsZMilSRwR7mgNL7knOpo= -cloud.google.com/go/iap v1.10.5/go.mod h1:Sal3oNlcIiv9YWkXWLD9fYzbSCbnrqOD4Pm8JyaiZZY= -cloud.google.com/go/ids v1.5.5/go.mod h1:XHNjg7KratNBxruoiG2Mfx2lFMnRQZWCr/p7T7AV724= -cloud.google.com/go/iot v1.8.5/go.mod h1:BlwypQBsnaiVRCy2+49Zz4ClJLDidldn05+Fp1uGFOs= -cloud.google.com/go/kms v1.21.1/go.mod h1:s0wCyByc9LjTdCjG88toVs70U9W+cc6RKFc8zAqX7nE= -cloud.google.com/go/language v1.14.4/go.mod h1:EqwoMieV6UsNeqHV2tRxuhmfDyC3YqEu1er53CrRkeA= -cloud.google.com/go/lifesciences v0.10.5/go.mod h1:p+vxvHLx0/4QeVp3DU5Gcnyoi+kKNFWRqfgn2d8HuNc= -cloud.google.com/go/logging v1.13.0/go.mod h1:36CoKh6KA/M0PbhPKMq6/qety2DCAErbhXT62TuXALA= -cloud.google.com/go/longrunning v0.5.6/go.mod h1:vUaDrWYOMKRuhiv6JBnn49YxCPz2Ayn9GqyjaBT8/mA= -cloud.google.com/go/longrunning v0.6.6/go.mod h1:hyeGJUrPHcx0u2Uu1UFSoYZLn4lkMrccJig0t4FI7yw= -cloud.google.com/go/managedidentities v1.7.5/go.mod h1:cD8aai2c7nWdOzBMP48wJUM9zsdIu1VbdojGSlLGqjM= -cloud.google.com/go/maps v1.20.1/go.mod h1:aMmv5a4nJBF3WpbPoGathd05Wbl4uuHEw2/bXX+2gZ4= -cloud.google.com/go/mediatranslation v0.9.5/go.mod h1:JGsL9cldTUtRi3u6Q+BMXzY1zZFOWdbmZLf1C69G2Zs= -cloud.google.com/go/memcache v1.11.5/go.mod h1:SYrG9bR51Q82rGpj04gA5YwL0aZGdDcqPvxfQiaxio4= -cloud.google.com/go/metastore v1.14.5/go.mod h1:mWHoEHrIFMv4yjKxczc1S6LIwhDQ7rTcAIix2BEIad8= -cloud.google.com/go/monitoring v1.24.1/go.mod h1:Z05d1/vn9NaujqY2voG6pVQXoJGbp+r3laV+LySt9K0= -cloud.google.com/go/networkconnectivity v1.17.0/go.mod h1:RiX351sXmQ/iScNWUBLN+4L9HJeP3etBCIsXCt366Mc= -cloud.google.com/go/networkmanagement v1.18.2/go.mod h1:QOOTm+LgXEPeA9u9bAeDETBYkibzMVTYH4mIi9GJATc= -cloud.google.com/go/networksecurity v0.10.5/go.mod h1:CqJMtLG67gxHEAjGjccwEm5a7Tb6h0kPtHK5SEHnwMc= -cloud.google.com/go/notebooks v1.12.5/go.mod h1:265WkAl2d3YKqxB+nFFkI+xwnc9CWDdvHs+Pl3TUhLM= -cloud.google.com/go/optimization v1.7.5/go.mod h1:/nM8SUgl5C43X8Bb/AzEZdCL9CrUv9JtOVx6Ql4Ohg8= -cloud.google.com/go/orchestration v1.11.7/go.mod h1:0u82lPJh6P5DpeaLtoeyrYafLEBAQ6m7gZwdhVSM1Ag= -cloud.google.com/go/orgpolicy v1.14.3/go.mod h1:bc5nFdnE+4vwCLvv3uNFWUtsywFf6Szv+eW8SmAbQlQ= -cloud.google.com/go/osconfig v1.14.4/go.mod h1:WQ5UV8yf1yhqrFrMD//dsqF/dqpepo9nzSF34aQ4vC8= -cloud.google.com/go/oslogin v1.14.5/go.mod h1:H/wQ2JrheJ/NqGomDgRGj7YwRUKPl/EqQYUse5z+eCU= -cloud.google.com/go/phishingprotection v0.9.5/go.mod h1:9eflfOQ/ZBWXzjX7Y5GCEDgK3KzpQafnFuGzdwt/AFM= -cloud.google.com/go/policytroubleshooter v1.11.5/go.mod h1:/AnSQG4qCijhusdepnPROvb34cqvwZozTpnPmLt09Uk= -cloud.google.com/go/privatecatalog v0.10.6/go.mod h1:rXuTtOfEicEN2bZRBkz/KTdDJndzvc4zb1b2Jaxkc8w= -cloud.google.com/go/pubsub v1.37.0/go.mod h1:YQOQr1uiUM092EXwKs56OPT650nwnawc+8/IjoUeGzQ= -cloud.google.com/go/pubsub v1.49.0/go.mod h1:K1FswTWP+C1tI/nfi3HQecoVeFvL4HUOB1tdaNXKhUY= -cloud.google.com/go/pubsublite v1.8.2/go.mod h1:4r8GSa9NznExjuLPEJlF1VjOPOpgf3IT6k8x/YgaOPI= -cloud.google.com/go/recaptchaenterprise/v2 v2.20.2/go.mod h1:BuZevlArTGydeIvlO3Mp4nQwLWPsnzUDUF/84+1bmfc= -cloud.google.com/go/recommendationengine v0.9.5/go.mod h1:7Ngg07UK3Ix45dwj/DXgWJa0661YyKfE84XKXnM6qo0= -cloud.google.com/go/recommender v1.13.4/go.mod h1:2xpcTYCOy2JlePWcMcVqS+dNiiMNCNGT/PtsjGP1BTQ= -cloud.google.com/go/redis v1.18.1/go.mod h1:lZQIhkqbhlmqGlFws6yzxSt2qNrAsPDHozWYGvXywqM= -cloud.google.com/go/resourcemanager v1.10.5/go.mod h1:3h1p8//AxBksoqJR/sD5AeGKVuuhZi805WC9nGogRGE= -cloud.google.com/go/resourcesettings v1.8.3/go.mod h1:BzgfXFHIWOOmHe6ZV9+r3OWfpHJgnqXy8jqwx4zTMLw= -cloud.google.com/go/retail v1.19.3/go.mod h1:o34bfr78e/gDLbHeDp0jiXKkXK7onYCJc86qrTM4Pac= -cloud.google.com/go/run v1.9.2/go.mod h1:QD5H5hNuz900FYLQGtbMlA0dqZogy/Wj0xpLwTzK2+Q= -cloud.google.com/go/scheduler v1.11.6/go.mod h1:gb8qfU07hAyXXtwrKXs7nbc9ar/R8vNsaRHswZpgPyM= -cloud.google.com/go/secretmanager v1.14.6/go.mod h1:0OWeM3qpJ2n71MGgNfKsgjC/9LfVTcUqXFUlGxo5PzY= -cloud.google.com/go/security v1.18.4/go.mod h1:+oNVB34sloqG2K3IpoT2KUDgNAbAJ9A2uENjAUvgzRQ= -cloud.google.com/go/securitycenter v1.36.1/go.mod h1:SxE1r7Y5V9AVPa+DU0d+4QAOIJzcKglO3Vc4zvcQtPo= -cloud.google.com/go/servicedirectory v1.12.5/go.mod h1:v/sr/Z4lbZzJBSn5H7bObu8FKoS6NZZ0ysQ3gi0vMMM= -cloud.google.com/go/shell v1.8.5/go.mod h1:vuRxgLhy5pR9TZVqWvR/7lfSiMCLv6ucuoYDtQKKuJ8= -cloud.google.com/go/spanner v1.79.0/go.mod h1:224ub0ngSaiy7SJI7QZ1pu9zoVPt6CgfwDGBNhUUuzU= -cloud.google.com/go/speech v1.26.1/go.mod h1:YTt2qy3GFlzxNJmWj7aDEZjTqESvP2pWpExdOqtCQ6k= -cloud.google.com/go/storagetransfer v1.12.3/go.mod h1:JzyP1ymNdy+F0VjyVCKzuk1WjLJ1yZGhtXcBlzBkPjk= -cloud.google.com/go/talent v1.8.2/go.mod h1:SAIKGqmpKBCOf1LZLtL/7yzNqY2YTYHk0CgMlEWBXMY= -cloud.google.com/go/texttospeech v1.12.0/go.mod h1:BdrVnsA7LnGe9v+zY3nfNJ2veaqLFbpkpBz3U+jsY34= -cloud.google.com/go/tpu v1.8.2/go.mod h1:W/fW8HHjrzx1Ae5ahXiWnc/O0FNAQCbXdGdE7Hac3dc= -cloud.google.com/go/trace v1.11.5/go.mod h1:TwblCcqNInriu5/qzaeYEIH7wzUcchSdeY2l5wL3Eec= -cloud.google.com/go/translate v1.10.3/go.mod h1:GW0vC1qvPtd3pgtypCv4k4U8B7EdgK9/QEF2aJEUovs= -cloud.google.com/go/translate v1.12.4/go.mod h1:u3NmYPWGXeNVz94QYzdd8kI7Rvi3wyp2jsjN3qAciCY= -cloud.google.com/go/video v1.23.4/go.mod h1:G95szckwF/7LatG9fGfNXceMzLf7W0UhKTZi6zXKHPs= -cloud.google.com/go/videointelligence v1.12.5/go.mod h1:OFaZL0H53vQl/uyz/8gqXMJ5nr69RIC3ffPGJwKCNww= -cloud.google.com/go/vision/v2 v2.9.4/go.mod h1:VotOrCFm0DbWKU7KvtyuAm72okClHDoERxrgeeQNPN4= -cloud.google.com/go/vmmigration v1.8.5/go.mod h1:6/VVofjrSGi14/0ZcaoSoZcy9VHDhJ6fNFxnYAPxuLg= -cloud.google.com/go/vmwareengine v1.3.4/go.mod h1:2W2NdtnfEe/0rEKoDfGOpBPtbAAf9ZN/SecH1WwLX6w= -cloud.google.com/go/vpcaccess v1.8.5/go.mod h1:R/oMa0mkPbi5GuIascldW5g/IHXq9YX0TBxJyOzyy28= -cloud.google.com/go/webrisk v1.10.5/go.mod h1:Cd8ce1mCt1fbiufmVkHeZZlPGfe4LQVHw006MtBIxvk= -cloud.google.com/go/websecurityscanner v1.7.5/go.mod h1:QGRxdN0ihdyjwDPaLf96O+ks4u+SBG7/bPNs+fc+LR0= -cloud.google.com/go/workflows v1.14.0/go.mod h1:kjar2tf4qQu7VoCTFX+L3yy+2dIFTWr6R4i52DN6ySk= -filippo.io/mkcert v1.4.4/go.mod h1:VyvOchVuAye3BoUsPUOOofKygVwLV2KQMVFJNRq+1dA= -fyne.io/systray v1.11.0/go.mod h1:RVwqP9nYMo7h5zViCBHri2FgjXF7H2cub7MAq4NSoLs= -github.com/99designs/gqlgen v0.17.36/go.mod h1:6RdyY8puhCoWAQVr2qzF2OMVfudQzc8ACxzpzluoQm4= -github.com/Abirdcfly/dupword v0.0.11/go.mod h1:wH8mVGuf3CP5fsBTkfWwwwKTjDnVVCxtU8d8rgeVYXA= -github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20230306123547-8075edf89bb0/go.mod h1:OahwfttHWG6eJ0clwcfBAHoDI6X/LV/15hx/wlMZSrU= -github.com/AlekSi/pointer v1.2.0/go.mod h1:gZGfd3dpW4vEc/UlyfKKi1roIqcCgwOIvb0tSNSBle0= -github.com/Antonboom/errname v0.1.9/go.mod h1:nLTcJzevREuAsgTbG85UsuiWpMpAqbKD1HNZ29OzE58= -github.com/Antonboom/nilnil v0.1.4/go.mod h1:iOov/7gRcXkeEU+EMGpBu2ORih3iyVEiWjeste1SJm8= -github.com/AudriusButkevicius/recli v0.0.7-0.20220911121932-d000ce8fbf0f/go.mod h1:Nhfib1j/VFnLrXL9cHgA+/n2O6P5THuWelOnbfPNd78= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0/go.mod h1:XCW7KnZet0Opnr7HccfUw1PLc4CjHqpcaxW8DHklNkQ= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0/go.mod h1:iZDifYGJTIgIIkYRNWPENUnqx6bJ2xnSDFI2tjwZNuY= -github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.6.0/go.mod h1:cTvi54pg19DoT07ekoeMgE/taAwNtCShVeZqA+Iv2xI= -github.com/DataDog/datadog-agent/comp/trace/compression/def v0.58.0/go.mod h1:samFXdP0HVSwD223LPLzcPKUjRQ6/uwr/1wMPo2HhRg= -github.com/DataDog/datadog-agent/comp/trace/compression/impl-gzip v0.58.0/go.mod h1:FTweq0EZjbOgeWgV7+3R1Zx9l2b9de7LwceYSNNdZvM= -github.com/DataDog/datadog-agent/comp/trace/compression/impl-zstd v0.58.0/go.mod h1:wIlhI+gwxKQzDQFr4PjvXXuKHUsx3QWY2TbwDv1yaDs= -github.com/DataDog/datadog-agent/pkg/util/cgroups v0.58.0/go.mod h1:XjTdv3Kb7EqpPnMlmmQK1MV6EFOArwoa6wSVB+P7TdU= -github.com/DataDog/datadog-agent/pkg/util/pointer v0.58.0/go.mod h1:t1DlnUEMltkvwPLc7zCtP1u5cBDu+30daR2VhQO5bvA= -github.com/DataDog/zstd v1.5.5/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= -github.com/Djarvur/go-err113 v0.1.0/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= -github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0/go.mod h1:b3g59n2Y+T5xmcxJL+UEG2f8cQploZm1mR/v6BW0mU0= -github.com/GoogleCloudPlatform/gke-networking-api v0.1.2-0.20240904205008-bc15495fd43f/go.mod h1:YnoYXo/cwpqFmIXKblHOV5jFEpsSL3PZeo0zaR3oGTI= -github.com/GoogleCloudPlatform/k8s-cloud-provider v1.25.0/go.mod h1:UTfhBnADaj2rybPT049NScSh7Eall3u2ib43wmz3deg= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.25.0/go.mod h1:obipzmGjfSjam60XLwGfqUkJsfiheAl+TUjG+4yzyPM= -github.com/IBM/sarama v1.43.1/go.mod h1:GG5q1RURtDNPz8xxJs3mgX6Ytak8Z9eLhAkJPObe2xE= github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= -github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60= -github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= -github.com/Masterminds/vcs v1.13.3/go.mod h1:TiE7xuEjl1N4j016moRd6vezp6e6Lz23gypeXfzXeW8= -github.com/Microsoft/cosesign1go v1.2.0/go.mod h1:1La/HcGw19rRLhPW0S6u55K6LKfti+GQSgGCtrfhVe8= -github.com/Microsoft/didx509go v0.0.3/go.mod h1:wWt+iQsLzn3011+VfESzznLIp/Owhuj7rLF7yLglYbk= -github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= -github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= -github.com/OpenPeeDeeP/depguard v1.1.1/go.mod h1:JtAMzWkmFEzDPyAd+W0NHl1lvpQKTvT9jnRVsohBKpc= -github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= -github.com/Shopify/sarama v1.38.1/go.mod h1:iwv9a67Ha8VNa+TifujYoWGxWnu2kNVAQdSdZ4X2o5g= -github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= -github.com/akavel/rsrc v0.10.2/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= -github.com/akutz/memconn v0.1.0/go.mod h1:Jo8rI7m0NieZyLI5e2CDlRdRqRRB4S7Xp77ukDjH+Fw= -github.com/alecthomas/kingpin/v2 v2.4.0/go.mod h1:0gyi0zQnjuFk8xrkNKamJoyUo382HRL7ATRpFZCw6tE= -github.com/alecthomas/kong v1.6.0/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU= -github.com/alecthomas/kong v1.10.0/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU= -github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= -github.com/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cvfHR56wJVlKE= -github.com/alingse/asasalint v0.0.11/go.mod h1:nCaoMhw7a9kSJObvQyVzNTPBDbNpdocqrSP7t/cW5+I= -github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= -github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g= -github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw= -github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= -github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/ashanbrown/forbidigo v1.5.1/go.mod h1:Y8j9jy9ZYAEHXdu723cUlraTqbzjKF1MUyfOKL+AjcU= -github.com/ashanbrown/makezero v1.1.1/go.mod h1:i1bJLCRSCHOcOa9Y6MyF2FTfMZMFdHvxKHxgO5Z1axI= -github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.13/go.mod h1:gpAbvyDGQFozTEmlTFO8XcQKHzubdq0LzRyJpG6MiXM= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.64/go.mod h1:4Q7R9MFpXRdjO3YnAfUTdnuENs32WzBkASt6VxSYDYQ= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.1.3/go.mod h1:jYLMm3Dh0wbeV3lxth5ryks/O2M/omVXWyYm3YcEVqQ= -github.com/aws/aws-sdk-go-v2/service/dynamodb v1.21.4/go.mod h1:aryF4jxgjhbqpdhj8QybUZI3xYrX8MQIKm4WbOv8Whg= -github.com/aws/aws-sdk-go-v2/service/ec2 v1.93.2/go.mod h1:VX22JN3HQXDtQ3uS4h4TtM+K11vydq58tpHTlsm8TL8= -github.com/aws/aws-sdk-go-v2/service/eventbridge v1.20.4/go.mod h1:XlbY5AGZhlipCdhRorT18/HEThKAxo51hMmhixreJoM= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.35/go.mod h1:YVHrksq36j0sbXCT6rSuQafpfYkMYqy0QTk7JTCTBIU= -github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.7.34/go.mod h1:CDPcT6pljRaqz1yLsOgPUvOPOczFvXuJxOKzDzAbF0c= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.15.3/go.mod h1:TXBww3ANB+QRj+/dUoYDvI8d/u4F4WzTxD4mxtDoxrg= -github.com/aws/aws-sdk-go-v2/service/kinesis v1.18.4/go.mod h1:HnjgmL8TNmYtGcrA3N6EeCnDvlX6CteCdUbZ1wV8QWQ= -github.com/aws/aws-sdk-go-v2/service/s3 v1.33.0/go.mod h1:J9kLNzEiHSeGMyN7238EjJmBpCniVzFda75Gxl/NqB8= -github.com/aws/aws-sdk-go-v2/service/sfn v1.19.4/go.mod h1:uWCH4ATwNrkRO40j8Dmy7u/Y1/BVWgCM+YjBNYZeOro= -github.com/aws/aws-sdk-go-v2/service/sns v1.21.4/go.mod h1:bbB779DXXOnPXvB7F3dP7AjuV1Eyr7fNyrA058ExuzY= -github.com/aws/aws-sdk-go-v2/service/sqs v1.24.4/go.mod h1:c1AF/ac4k4xz32FprEk6AqqGFH/Fkub9VUPSrASlllA= -github.com/aws/aws-sdk-go-v2/service/ssm v1.44.7/go.mod h1:Q7XIWsMo0JcMpI/6TGD6XXcXcV1DbTj6e9BKNntIMIM= -github.com/bazelbuild/rules_go v0.44.2/go.mod h1:Dhcz716Kqg1RHNWos+N6MlXNkjNP2EwZQ0LukRKJfMs= -github.com/bkielbasa/cyclop v1.2.0/go.mod h1:qOI0yy6A7dYC4Zgsa72Ppm9kONl0RoIlPbzot9mhmeI= -github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI= -github.com/blizzy78/varnamelen v0.8.0/go.mod h1:V9TzQZ4fLJ1DSrjVDfl89H7aMnTvKkApdHeyESmyR7k= -github.com/bombsimon/wsl/v3 v3.4.0/go.mod h1:KkIB+TXkqy6MvK9BDZVbZxKNYsE1/oLRJbIFtf14qqo= -github.com/bradfitz/gomemcache v0.0.0-20230611145640-acc696258285/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA= -github.com/bramvdbogaerde/go-scp v1.4.0/go.mod h1:on2aH5AxaFb2G0N5Vsdy6B0Ml7k9HuHSwfo1y0QzAbQ= -github.com/breml/bidichk v0.2.4/go.mod h1:7Zk0kRFt1LIZxtQdl9W9JwGAcLTTkOs+tN7wuEYGJ3s= -github.com/breml/errchkjson v0.3.1/go.mod h1:XroxrzKjdiutFyW3nWhw34VGg7kiMsDQox73yWCGI2U= -github.com/butuzov/ireturn v0.2.0/go.mod h1:Wh6Zl3IMtTpaIKbmwzqi6olnM9ptYQxxVacMsOEFPoc= -github.com/bytedance/sonic v1.12.0/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk= -github.com/bytedance/sonic/loader v0.2.0/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= -github.com/cavaliergopher/cpio v1.0.1/go.mod h1:pBdaqQjnvXxdS/6CvNDwIANIFSP0xRKI16PX4xejRQc= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= -github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= -github.com/cenkalti/backoff/v3 v3.2.2/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs= -github.com/certifi/gocertifi v0.0.0-20210507211836-431795d63e8d/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= -github.com/charithe/durationcheck v0.0.10/go.mod h1:bCWXb7gYRysD1CU3C+u4ceO49LoGOY1C1L6uouGNreQ= -github.com/chavacava/garif v0.0.0-20230227094218-b8c73b2037b8/go.mod h1:gakxgyXaaPkxvLw1XQxNGK4I37ys9iBRzNUx/B7pUCo= -github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk= -github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= -github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= -github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= -github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb/go.mod h1:ZjrT6AXHbDs86ZSdt/osfBi5qfexBrKUdONk989Wnk4= -github.com/coder/websocket v1.8.12/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs= -github.com/confluentinc/confluent-kafka-go v1.9.2/go.mod h1:ptXNqsuDfYbAE/LBW6pnwWZElUoWxHoV8E43DCrliyo= -github.com/confluentinc/confluent-kafka-go/v2 v2.4.0/go.mod h1:E1dEQy50ZLfqs7T9luxz0rLxaeFZJZE92XvApJOr/Rk= -github.com/containerd/aufs v1.0.0/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU= -github.com/containerd/btrfs/v2 v2.0.0/go.mod h1:swkD/7j9HApWpzl8OHfrHNxppPd9l44DFZdF94BUj9k= -github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= -github.com/containerd/cgroups/v3 v3.0.3/go.mod h1:8HBe7V3aWGLFPd/k03swSIsGjZhHI2WzJmticMgVuz0= -github.com/containerd/console v1.0.4/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk= -github.com/containerd/containerd/api v1.8.0/go.mod h1:dFv4lt6S20wTu/hMcP4350RL87qPWLVa/OHOwmmdnYc= -github.com/containerd/continuity v0.4.4/go.mod h1:/lNJvtJKUQStBzpVQ1+rasXO1LAWtUQssk28EZvJ3nE= -github.com/containerd/errdefs v0.3.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M= -github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk= -github.com/containerd/fifo v1.1.0/go.mod h1:bmC4NWMbXlt2EZ0Hc7Fx7QzTFxgPID13eH0Qu+MAb2o= -github.com/containerd/go-cni v1.1.9/go.mod h1:XYrZJ1d5W6E2VOvjffL3IZq0Dz6bsVlERHbekNK90PM= -github.com/containerd/go-runc v1.0.0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok= -github.com/containerd/imgcrypt v1.1.8/go.mod h1:x6QvFIkMyO2qGIY2zXc88ivEzcbgvLdWjoZyGqDap5U= -github.com/containerd/nri v0.8.0/go.mod h1:uSkgBrCdEtAiEz4vnrq8gmAC4EnVAM5Klt0OuK5rZYQ= -github.com/containerd/protobuild v0.3.0/go.mod h1:5mNMFKKAwCIAkFBPiOdtRx2KiQlyEJeMXnL5R1DsWu8= -github.com/containerd/stargz-snapshotter/estargz v0.15.1/go.mod h1:gr2RNwukQ/S9Nv33Lt6UC7xEx58C+LHRdoqbEKjz1Kk= -github.com/containerd/ttrpc v1.2.7/go.mod h1:YCXHsb32f+Sq5/72xHubdiJRQY9inL4a4ZQrAbN1q9o= -github.com/containerd/typeurl v1.0.2/go.mod h1:9trJWW2sRlGub4wZJRTW83VtbOLS6hwcDZXTn6oPz9s= -github.com/containerd/typeurl/v2 v2.2.0/go.mod h1:8XOOxnyatxSWuG8OfsZXVnAF4iZfedjS/8UHSPJnX4g= -github.com/containerd/zfs v1.1.0/go.mod h1:oZF9wBnrnQjpWLaPKEinrx3TQ9a+W/RJO7Zb41d8YLE= -github.com/containernetworking/plugins v1.2.0/go.mod h1:/VjX4uHecW5vVimFa1wkG4s+r/s9qIfPdqlLF4TW8c4= -github.com/containers/ocicrypt v1.1.10/go.mod h1:YfzSSr06PTHQwSTUKqDSjish9BeW1E4HUmreluQcMd8= -github.com/coreos/go-oidc v2.2.1+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= -github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf h1:iW4rZ826su+pqaw19uhpSCzhj44qo35pNgKFGqzDKkU= -github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/curioswitch/go-reassign v0.2.0/go.mod h1:x6OpXuWvgfQaMGks2BZybTngWjT84hqJfKoO8Tt/Roc= -github.com/daixiang0/gci v0.10.1/go.mod h1:xtHP9N7AHdNvtRNfcx9gwTDfw7FRJx4bZUsiEfiNNAI= -github.com/danieljoos/wincred v1.2.1/go.mod h1:uGaFL9fDn3OLTvzCGulzE+SzjEe5NGlh5FdCcyfPwps= -github.com/dave/astrid v0.0.0-20170323122508-8c2895878b14/go.mod h1:Sth2QfxfATb/nW4EsrSi2KyJmbcniZ8TgTaji17D6ms= -github.com/dave/brenda v1.1.0/go.mod h1:4wCUr6gSlu5/1Tk7akE5X7UorwiQ8Rij0SKH3/BGMOM= -github.com/dave/courtney v0.4.0/go.mod h1:3WSU3yaloZXYAxRuWt8oRyVb9SaRiMBt5Kz/2J227tM= -github.com/dave/patsy v0.0.0-20210517141501-957256f50cba/go.mod h1:qfR88CgEGLoiqDaE+xxDCi5QA5v4vUoW0UCX2Nd5Tlc= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= -github.com/denis-tingaikin/go-header v0.4.3/go.mod h1:0wOCWuN71D5qIgE2nz9KrKmuYBAC2Mra5RassOIQ2/c= -github.com/denisenkom/go-mssqldb v0.11.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= -github.com/digitalocean/go-smbios v0.0.0-20180907143718-390a4f403a8e/go.mod h1:YTIHhz/QFSYnu/EhlF2SpU2Uk+32abacUYA5ZPljz1A= -github.com/dimfeld/httptreemux/v5 v5.5.0/go.mod h1:QeEylH57C0v3VO0tkKraVz9oD3Uu93CKPnTLbsidvSw= -github.com/djherbis/times v1.6.0/go.mod h1:gOHeRAz2h+VJNZ5Gmc/o7iD9k4wW7NMVqieYCY99oc0= -github.com/dsnet/try v0.0.3/go.mod h1:WBM8tRpUmnXXhY1U6/S8dt6UWdHTQ7y8A5YSkRCkq40= -github.com/dvyukov/go-fuzz v0.0.0-20210103155950-6a8e9d1f2415/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw= -github.com/eapache/go-resiliency v1.6.0/go.mod h1:5yPzW0MIvSe0JDsv0v+DvcjEv2FyD6iZYSs1ZI+iQho= -github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3/go.mod h1:YvSRo5mw33fLEx1+DlK6L2VV43tJt5Eyel9n9XBcR+0= -github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc= -github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/elastic/crd-ref-docs v0.0.12/go.mod h1:X83mMBdJt05heJUYiS3T0yJ/JkCuliuhSUNav5Gjo/U= -github.com/elastic/elastic-transport-go/v8 v8.1.0/go.mod h1:87Tcz8IVNe6rVSLdBux1o/PEItLtyabHU3naC7IoqKI= -github.com/elastic/go-elasticsearch/v6 v6.8.5/go.mod h1:UwaDJsD3rWLM5rKNFzv9hgox93HoX8utj1kxD9aFUcI= -github.com/elastic/go-elasticsearch/v7 v7.17.1/go.mod h1:OJ4wdbtDNk5g503kvlHLyErCgQwwzmDtaFC4XyOxXA4= -github.com/elastic/go-elasticsearch/v8 v8.4.0/go.mod h1:yY52i2Vj0unLz+N3Nwx1gM5LXwoj3h2dgptNGBYkMLA= -github.com/emicklei/go-restful v2.16.0+incompatible h1:rgqiKNjTnFQA6kkhFe16D8epTksy9HQ1MyrbDXSdYhM= -github.com/emicklei/go-restful v2.16.0+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= -github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= -github.com/esimonov/ifshort v1.0.4/go.mod h1:Pe8zjlRrJ80+q2CxHLfEOfTwxCZ4O+MuhcHcfgNWTk0= -github.com/ettle/strcase v0.1.1/go.mod h1:hzDLsPC7/lwKyBOywSHEP89nt2pDgdy+No1NBA9o9VY= -github.com/evanw/esbuild v0.19.11/go.mod h1:D2vIQZqV/vIf/VRHtViaUtViZmG7o+kKmlBfVQuRi48= -github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= -github.com/firefart/nonamedreturns v1.0.4/go.mod h1:TDhe/tjI1BXo48CmYbUduTV7BdIga8MAO/xbKdcVsGI= -github.com/flynn/go-docopt v0.0.0-20140912013429-f6dd2ebbb31e/go.mod h1:HyVoz1Mz5Co8TFO8EupIdlcpwShBmY98dkT2xeHkvEI= -github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= -github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= -github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA= -github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= -github.com/garyburd/redigo v1.6.4/go.mod h1:rTb6epsqigu3kYKBnaF028A7Tf/Aw5s0cqA47doKKqw= -github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= -github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= -github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= -github.com/go-chi/chi v1.5.4/go.mod h1:uaf8YgoFazUOkPBG7fxPftUylNumIev9awIWOENIuEg= -github.com/go-chi/chi/v5 v5.0.10/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= -github.com/go-critic/go-critic v0.8.0/go.mod h1:5TjdkPI9cu/yKbYS96BTsslihjKd6zg6vd8O9RZXj2s= -github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= -github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= -github.com/go-git/go-git/v5 v5.11.0/go.mod h1:6GFcX2P3NM7FPBfpePbpLd21XxsgdAt+lKqXmCUiUCY= -github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= -github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= -github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= -github.com/go-pg/pg/v10 v10.11.1/go.mod h1:ExJWndhDNNftBdw1Ow83xqpSf4WMSJK8urmXD5VXS1I= -github.com/go-pg/zerochecker v0.2.0/go.mod h1:NJZ4wKL0NmTtz0GKCoJ8kym6Xn/EQzXRl2OnAe7MmDo= -github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= -github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.15.1/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= -github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow= -github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= -github.com/go-redis/redis/v7 v7.4.1/go.mod h1:JDNMw23GTyLNC4GZu9njt15ctBQVn7xjRfnwdHj/Dcg= -github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= -github.com/go-toolsmith/astcast v1.1.0/go.mod h1:qdcuFWeGGS2xX5bLM/c3U9lewg7+Zu4mr+xPwZIB4ZU= -github.com/go-toolsmith/astcopy v1.1.0/go.mod h1:hXM6gan18VA1T/daUEHCFcYiW8Ai1tIwIzHY6srfEAw= -github.com/go-toolsmith/astequal v1.1.0/go.mod h1:sedf7VIdCL22LD8qIvv7Nn9MuWJruQA/ysswh64lffQ= -github.com/go-toolsmith/astfmt v1.1.0/go.mod h1:OrcLlRwu0CuiIBp/8b5PYF9ktGVZUjlNMV634mhwuQ4= -github.com/go-toolsmith/astp v1.1.0/go.mod h1:0T1xFGz9hicKs8Z5MfAqSUitoUYS30pDMsRVIDHs8CA= -github.com/go-toolsmith/strparse v1.1.0/go.mod h1:7ksGy58fsaQkGQlY8WVoBFNyEPMGuJin1rfoPS4lBSQ= -github.com/go-toolsmith/typep v1.1.0/go.mod h1:fVIw+7zjdsMxDA3ITWnH1yOiw1rnTQKCsF/sk2H/qig= -github.com/go-xmlfmt/xmlfmt v1.1.2/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= -github.com/gobuffalo/flect v1.0.2/go.mod h1:A5msMlrHtLqh9umBSnvabjsMrCcCpAyzglnDvkbYKHs= -github.com/gobuffalo/flect v1.0.3/go.mod h1:A5msMlrHtLqh9umBSnvabjsMrCcCpAyzglnDvkbYKHs= -github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= -github.com/goccy/go-yaml v1.12.0/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU= -github.com/gocql/gocql v1.6.0/go.mod h1:3gM2c4D3AnkISwBxGnMMsS8Oy4y2lhbPRsH4xnJrHG8= -github.com/godror/godror v0.40.4/go.mod h1:i8YtVTHUJKfFT3wTat4A9UoqScUtZXiYB9Rf3SVARgc= -github.com/godror/knownpb v0.1.1/go.mod h1:4nRFbQo1dDuwKnblRXDxrfCFYeT4hjg3GjMqef58eRE= -github.com/gofiber/fiber/v2 v2.52.5/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ= -github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0= -github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= -github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI= -github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= -github.com/golang/glog v1.2.4/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= -github.com/golang/mock v1.7.0-rc.1/go.mod h1:s42URUywIqd+OcERslBJvOjepvNymP31m3q8d/GkuRs= -github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4= -github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk= -github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe/go.mod h1:gjqyPShc/m8pEMpk0a3SeagVb0kaqvhscv+i9jI5ZhQ= -github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2/go.mod h1:9wOXstvyDRshQ9LggQuzBCGysxs3b6Uo/1MvYCR2NMs= -github.com/golangci/golangci-lint v1.52.2/go.mod h1:S5fhC5sHM5kE22/HcATKd1XLWQxX+y7mHj8B5H91Q/0= -github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg= -github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZqDe4LMs4ZHD0oMUlt9G2LWuDGoisJTBzLMV9o= -github.com/golangci/misspell v0.4.0/go.mod h1:W6O/bwV6lGDxUCChm2ykw9NQdd5bYd1Xkjo88UcWyJc= -github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6/go.mod h1:0AKcRCkMoKvUvlf89F6O7H2LYdhr1zBh736mBItOdRs= -github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ= -github.com/gomodule/redigo v1.8.9/go.mod h1:7ArFNvsTjH8GMMzB4uy1snslv2BwmginuMs06a1uzZE= -github.com/google/cel-go v0.22.0/go.mod h1:BuznPXXfQDpXKWQ9sPW3TzlAJN5zzFe+i9tIs0yC4s8= -github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= -github.com/google/go-containerregistry v0.20.1/go.mod h1:YCMFNQeeXeLF+dnhhWkqDItx/JSkH01j1Kis4PsjzFI= -github.com/google/go-github/v56 v56.0.0/go.mod h1:D8cdcX98YWJvi7TLo7zM4/h8ZTx6u6fwGEkCdisopo0= -github.com/google/go-pkcs11 v0.3.0/go.mod h1:6eQoGcuNJpa7jnd5pMGdkSaQpNDYvPlXWMcjXXThLlY= -github.com/google/goterm v0.0.0-20200907032337-555d40f16ae2/go.mod h1:nOFQdrUlIlx6M6ODdSpBj1NVA+VgLC6kmw60mkw34H4= -github.com/google/rpmpack v0.5.0/go.mod h1:uqVAUVQLq8UY2hCDfmJ/+rtO3aw7qyhc90rCVEabEfI= -github.com/google/subcommands v1.0.2-0.20190508160503-636abe8753b8/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= -github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA= -github.com/gordonklaus/ineffassign v0.0.0-20230107090616-13ace0543b28/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0= -github.com/goreleaser/chglog v0.5.0/go.mod h1:Ri46M3lrMuv76FHszs3vtABR8J8k1w9JHYAzxeeOl28= -github.com/goreleaser/fileglob v1.3.0/go.mod h1:Jx6BoXv3mbYkEzwm9THo7xbr5egkAraxkGorbJb4RxU= -github.com/goreleaser/nfpm/v2 v2.33.1/go.mod h1:8wwWWvJWmn84xo/Sqiv0aMvEGTHlHZTXTEuVSgQpkIM= -github.com/gorilla/csrf v1.7.2/go.mod h1:F1Fj3KG23WYHE6gozCmBAezKookxbIvUJT+121wTuLk= -github.com/gostaticanalysis/analysisutil v0.7.1/go.mod h1:v21E3hY37WKMGSnbsw2S/ojApNWb6C1//mXO48CXbVc= -github.com/gostaticanalysis/comment v1.4.2/go.mod h1:KLUTGDv6HOCotCH8h2erHKmpci2ZoR8VPu34YA2uzdM= -github.com/gostaticanalysis/forcetypeassert v0.1.0/go.mod h1:qZEedyP/sY1lTGV1uJ3VhWZ2mqag3IkWsDHVbplHXak= -github.com/gostaticanalysis/nilerr v0.1.1/go.mod h1:wZYb6YI5YAxxq0i1+VJbY0s2YONW0HU0GPE3+5PWN4A= -github.com/graph-gophers/graphql-go v1.5.0/go.mod h1:YtmJZDLbF1YYNrlNAuiO5zAStUWc3XZT07iGsVqe1Os= -github.com/graphql-go/graphql v0.8.1/go.mod h1:nKiHzRM0qopJEwCITUuIsxk9PlVlwIiiI8pnJEhordQ= -github.com/graphql-go/handler v0.2.3/go.mod h1:leLF6RpV5uZMN1CdImAxuiayrYYhOk33bZciaUGaXeU= -github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= -github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/hanwen/go-fuse/v2 v2.3.0/go.mod h1:xKwi1cF7nXAOBCXujD5ie0ZKsxc8GGSA1rlMJc+8IJs= -github.com/hashicorp/consul/api v1.24.0/go.mod h1:NZJGRFYruc/80wYowkPFCp1LbGmJC9L8izrwfyVx/Wg= -github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= -github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= -github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= -github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4= -github.com/hashicorp/vault/api v1.9.2/go.mod h1:jo5Y/ET+hNyz+JnKDt8XLAdKs+AM0G5W0Vp1IrFI8N8= -github.com/hashicorp/vault/sdk v0.9.2/go.mod h1:gG0lA7P++KefplzvcD3vrfCmgxVAM7Z/SqX5NeOL/98= -github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= -github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= -github.com/ianlancetaylor/demangle v0.0.0-20240312041847-bd984b5ce465/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw= -github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= -github.com/inetaf/tcpproxy v0.0.0-20240214030015-3ce58045626c/go.mod h1:Di7LXRyUcnvAcLicFhtM9/MlZl/TNgRSDHORM2c6CMI= -github.com/insomniacslk/dhcp v0.0.0-20231206064809-8c70d406f6d2/go.mod h1:3A9PQ1cunSDF/1rbTq99Ts4pVnycWg+vlPkfeD2NLFI= -github.com/intel/goresctrl v0.5.0/go.mod h1:mIe63ggylWYr0cU/l8n11FAkesqfvuP3oktIsxvu0T0= -github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= -github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= -github.com/jackc/pgx/v5 v5.6.0/go.mod h1:DNZ/vlrUnhWCoFGxHAG8U2ljioxukquj7utPDgtQdTw= -github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= -github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= -github.com/jellydator/ttlcache/v3 v3.1.0/go.mod h1:hi7MGFdMAwZna5n2tuvh63DvFLzVKySzCVW6+0gA2n4= -github.com/jessevdk/go-flags v1.6.1/go.mod h1:Mk8T1hIAWpOiJiHa9rJASDK2UGWji0EuPGBnNLMooyc= -github.com/jgautheron/goconst v1.5.1/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4= -github.com/jingyugao/rowserrcheck v1.1.1/go.mod h1:4yvlZSDb3IyDTUZJUmpZfm2Hwok+Dtp+nu2qOq+er9c= -github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= -github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= -github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc= -github.com/josephspurrier/goversioninfo v1.4.0/go.mod h1:JWzv5rKQr+MmW+LvM412ToT/IkYDZjaclF2pKDss8IY= -github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/jsimonetti/rtnetlink/v2 v2.0.1/go.mod h1:7MoNYNbb3UaDHtF8udiJo/RH6VsTKP1pqKLUTVCvToE= -github.com/julz/importas v0.1.0/go.mod h1:oSFU2R4XK/P7kNBrnL/FEQlDGN1/6WoxXEjSSXO0DV0= -github.com/junk1tm/musttag v0.5.0/go.mod h1:PcR7BA+oREQYvHwgjIDmw3exJeds5JzRcvEJTfjrA0M= -github.com/karrick/godirwalk v1.17.0/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk= -github.com/kisielk/errcheck v1.6.3/go.mod h1:nXw/i/MfnvRHqXa7XXmQMUB0oNFGuBrNI8d8NLy0LPw= -github.com/kkHAIKE/contextcheck v1.1.4/go.mod h1:1+i/gWqokIa+dm31mqGLZhZJ7Uh44DJGZVmr6QRBNJg= -github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= -github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= -github.com/knadh/koanf/maps v0.1.1/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= -github.com/knadh/koanf/providers/confmap v0.1.0/go.mod h1:2uLhxQzJnyHKfxG927awZC7+fyHFdQkd697K4MdLnIU= -github.com/knadh/koanf/v2 v2.0.2/go.mod h1:HN9uZ+qFAejH1e4G41gnoffIanINWQuONLXiV7kir6k= -github.com/kortschak/wol v0.0.0-20200729010619-da482cc4850a/go.mod h1:YTtCCM3ryyfiu4F7t8HQ1mxvp1UBdWM2r6Xa+nGWvDk= -github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= -github.com/kulti/thelper v0.6.3/go.mod h1:DsqKShOvP40epevkFrvIwkCMNYxMeTNjdWL4dqWHZ6I= -github.com/kunwardeep/paralleltest v1.0.6/go.mod h1:Y0Y0XISdZM5IKm3TREQMZ6iteqn1YuwCsJO/0kL9Zes= -github.com/kyoh86/exportloopref v0.1.11/go.mod h1:qkV4UF1zGl6EkF1ox8L5t9SwyeBAZ3qLMd6up458uqA= -github.com/labstack/echo v3.3.10+incompatible/go.mod h1:0INS7j/VjnFxD4E2wkz67b8cVwCLbBmJyDaka6Cmk1s= -github.com/labstack/echo/v4 v4.11.1/go.mod h1:YuYRTSM3CHs2ybfrL8Px48bO6BAnYIN4l8wSTMP6BDQ= -github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= -github.com/ldez/gomoddirectives v0.2.3/go.mod h1:cpgBogWITnCfRq2qGoDkKMEVSaarhdBr6g8G04uz6d0= -github.com/ldez/tagliatelle v0.5.0/go.mod h1:rj1HmWiL1MiKQuOONhd09iySTEkUuE/8+5jtPYz9xa4= -github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= -github.com/leonklingele/grouper v1.1.1/go.mod h1:uk3I3uDfi9B6PeUjsCKi6ndcf63Uy7snXgR4yDYQVDY= -github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y= -github.com/lestrrat-go/blackmagic v1.0.2/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU= -github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E= -github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4= -github.com/lestrrat-go/jwx v1.2.29/go.mod h1:hU8k2l6WF0ncx20uQdOmik/Gjg6E3/wIRtXSNFeZuB8= -github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= -github.com/linuxkit/virtsock v0.0.0-20201010232012-f8cee7dfc7a3/go.mod h1:3r6x7q95whyfWQpmGZTu3gk3v2YkMi05HEzl7Tf7YEo= -github.com/lufeee/execinquery v1.2.1/go.mod h1:EC7DrEKView09ocscGHC+apXMIaorh4xqSxS/dy8SbM= -github.com/lxn/walk v0.0.0-20210112085537-c389da54e794/go.mod h1:E23UucZGqpuUANJooIbHWCufXvOcT6E7Stq81gU+CSQ= -github.com/lxn/win v0.0.0-20210218163916-a377121e959e/go.mod h1:KxxjdtRkfNoYDCUP5ryK7XJJNTnpC8atvtmTheChOtk= -github.com/lyft/protoc-gen-star/v2 v2.0.4-0.20230330145011-496ad1ac90a4/go.mod h1:amey7yeodaJhXSbf/TlLvWiqQfLOSpEk//mLlc+axEk= -github.com/maratori/testableexamples v1.0.0/go.mod h1:4rhjL1n20TUTT4vdh3RDqSizKLyXp7K2u6HgraZCGzE= -github.com/maratori/testpackage v1.1.1/go.mod h1:s4gRK/ym6AMrqpOa/kEbQTV4Q4jb7WeLZzVhVVVOQMc= -github.com/maruel/panicparse/v2 v2.4.0/go.mod h1:nOY2OKe8csO3F3SA5+hsxot05JLgukrF54B9x88fVp4= -github.com/maruel/panicparse/v2 v2.5.0/go.mod h1:DA2fDiBk63bKfBf4CVZP9gb4fuvzdPbLDsSI873hweQ= -github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= -github.com/mattn/go-oci8 v0.1.1/go.mod h1:wjDx6Xm9q7dFtHJvIlrI99JytznLw5wQ4R+9mNXJwGI= -github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= -github.com/maxbrunsfeld/counterfeiter/v6 v6.8.1/go.mod h1:eyp4DdUJAKkr9tvxR3jWhw2mDK7CWABMG5r9uyaKC7I= -github.com/maxbrunsfeld/counterfeiter/v6 v6.11.2/go.mod h1:VzB2VoMh1Y32/QqDfg9ZJYHj99oM4LiGtqPZydTiQSQ= -github.com/maxmind/geoipupdate/v6 v6.1.0/go.mod h1:cZYCDzfMzTY4v6dKRdV7KTB6SStxtn3yFkiJ1btTGGc= -github.com/mbilski/exhaustivestruct v1.2.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aksxSUOUy+nvtVEfzXc= -github.com/mdlayher/genetlink v1.3.2/go.mod h1:tcC3pkCrPUGIKKsCsp0B3AdaaKuHtaxoJRz3cc+528o= -github.com/mdlayher/sdnotify v1.0.0/go.mod h1:HQUmpM4XgYkhDLtd+Uad8ZFK1T9D5+pNxnXQjCeJlGE= -github.com/mgechev/revive v1.3.1/go.mod h1:YlD6TTWl2B8A103R9KWJSPVI9DrEf+oqr15q21Ld+5I= -github.com/microsoft/go-mssqldb v0.21.0/go.mod h1:+4wZTUnz/SV6nffv+RRRB/ss8jPng5Sho2SmM1l2ts4= -github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= -github.com/mistifyio/go-zfs/v3 v3.0.1/go.mod h1:CzVgeB0RvF2EGzQnytKVvVSDwmKJXxkOTUGbNrTja/k= -github.com/mitchellh/cli v1.1.5/go.mod h1:v8+iFts2sPIKUV1ltktPXMCC8fumSKFItNcD2cLtRR4= -github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg= -github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= -github.com/moby/sys/mountinfo v0.6.2/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI= -github.com/moby/sys/signal v0.7.0/go.mod h1:GQ6ObYZfqacOwTtlXvcmh9A26dVRul/hbOZn88Kg8Tg= -github.com/moby/sys/symlink v0.2.0/go.mod h1:7uZVF2dqJjG/NsClqul95CqKOBRQyYSNnJ6BMgR/gFs= -github.com/moby/sys/user v0.3.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs= -github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28= -github.com/mohae/deepcopy v0.0.0-20170308212314-bb9b5e7adda9/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= -github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= -github.com/moricho/tparallel v0.3.1/go.mod h1:leENX2cUv7Sv2qDgdi0D0fCftN8fRC67Bcn8pqzeYNI= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nakabonne/nestif v0.3.1/go.mod h1:9EtoZochLn5iUprVDmDjqGKPofoUEBL8U4Ngq6aY7OE= -github.com/natefinch/atomic v1.0.1/go.mod h1:N/D/ELrljoqDyT3rZrsUmtsuzvHkeB/wWjHV22AZRbM= -github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354/go.mod h1:KSVJerMDfblTH7p5MZaTt+8zaT2iEk3AkVb9PQdZuE8= -github.com/nelsam/hel/v2 v2.3.3/go.mod h1:1ZTGfU2PFTOd5mx22i5O0Lc2GY933lQ2wb/ggy+rL3w= -github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= -github.com/nishanths/exhaustive v0.10.0/go.mod h1:IbwrGdVMizvDcIxPYGVdQn5BqWJaOwpCvg4RGb8r/TA= -github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c= -github.com/nunnatsa/ginkgolinter v0.11.2/go.mod h1:dJIGXYXbkBswqa/pIzG0QlVTTDSBMxDoCFwhsl4Uras= -github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= -github.com/open-policy-agent/opa v0.68.0/go.mod h1:5E5SvaPwTpwt2WM177I9Z3eT7qUpmOGjk1ZdHs+TZ4w= -github.com/open-telemetry/opentelemetry-collector-contrib/pkg/sampling v0.104.0/go.mod h1:4bLfc6BnVKRp3yY+ueEUEeyNWjW/InCGbFs9ZA7o/ko= -github.com/open-telemetry/opentelemetry-collector-contrib/processor/probabilisticsamplerprocessor v0.104.0/go.mod h1:I2so4Vn+ROaCECo0bdQXNxyUjY9tbq1JvcyuWPETLcM= -github.com/opencontainers/runc v1.1.14/go.mod h1:E4C2z+7BxR7GHXp0hAY53mek+x49X1LjPNeMTfRGvOA= -github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-tools v0.9.1-0.20221107090550-2e043c6bd626/go.mod h1:BRHJJd0E+cx42OybVYSgUvZmU0B8P9gZuRXlZUP7TKI= -github.com/opencontainers/selinux v1.11.0/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec= -github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/peterbourgon/ff/v3 v3.4.0/go.mod h1:zjJVUhx+twciwfDl0zBcFzl4dW8axCRyXE/eKY9RztQ= -github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= -github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= -github.com/pkg/sftp v1.13.6/go.mod h1:tz1ryNURKu77RL+GuCzmoJYxQczL3wLNNpPWagdg4Qk= -github.com/polyfloyd/go-errorlint v1.4.1/go.mod h1:k6fU/+fQe38ednoZS51T7gSIGQW1y94d6TkSr35OzH8= -github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= -github.com/pquerna/cachecontrol v0.1.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI= -github.com/prometheus/prometheus v0.49.2-0.20240125131847-c3b8ef1694ff/go.mod h1:FvE8dtQ1Ww63IlyKBn1V4s+zMwF9kHkVNkQBR1pM4CU= -github.com/puzpuzpuz/xsync/v3 v3.4.0/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA= -github.com/puzpuzpuz/xsync/v3 v3.5.1/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA= -github.com/quasilyte/go-ruleguard v0.3.19/go.mod h1:lHSn69Scl48I7Gt9cX3VrbsZYvYiBYszZOZW4A+oTEw= -github.com/quasilyte/gogrep v0.5.0/go.mod h1:Cm9lpz9NZjEoL1tgZ2OgeUKPIxL1meE7eo60Z6Sk+Ng= -github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0= -github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ= -github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg= -github.com/rabbitmq/amqp091-go v1.10.0/go.mod h1:Hy4jKW5kQART1u+JkDTF9YYOQUHXqMuhrgxOEeS7G4o= -github.com/rcrowley/go-metrics v0.0.0-20250401214520-65e299d6c5c9/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/riywo/loginshell v0.0.0-20200815045211-7d26008be1ab/go.mod h1:/PfPXh0EntGc3QAAyUaviy4S9tzy4Zp0e2ilq4voC6E= -github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= -github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww= -github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY= -github.com/ryancurrah/gomodguard v1.3.0/go.mod h1:ggBxb3luypPEzqVtq33ee7YSN35V28XeGnid8dnni50= -github.com/ryanrolds/sqlclosecheck v0.4.0/go.mod h1:TBRRjzL31JONc9i4XMinicuo+s+E8yKZ5FN8X3G6CKQ= -github.com/safchain/ethtool v0.3.0/go.mod h1:SA9BwrgyAqNo7M+uaL6IYbxpm5wk3L7Mm6ocLW+CJUs= -github.com/sanposhiho/wastedassign/v2 v2.0.7/go.mod h1:KyZ0MWTwxxBmfwn33zh3k1dmsbF2ud9pAAGfoLfjhtI= -github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY= -github.com/sashamelentyev/interfacebloat v1.1.0/go.mod h1:+Y9yU5YdTkrNvoX0xHc84dxiN1iBi9+G8zZIhPVoNjQ= -github.com/sashamelentyev/usestdlibvars v1.23.0/go.mod h1:YPwr/Y1LATzHI93CqoPUN/2BzGQ/6N/cl/KwgR0B/aU= -github.com/securego/gosec/v2 v2.15.0/go.mod h1:VOjTrZOkUtSDt2QLSJmQBMWnvwiQPEjg0l+5juIqGk8= -github.com/segmentio/kafka-go v0.4.42/go.mod h1:d0g15xPMqoUookug0OU75DhGZxXwCFxSLeJ4uphwJzg= -github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs= -github.com/shirou/gopsutil/v4 v4.25.3/go.mod h1:xbuxyoZj+UsgnZrENu3lQivsngRR5BdjbJwf2fv4szA= -github.com/sivchari/containedctx v1.0.3/go.mod h1:c1RDvCbnJLtH4lLcYD/GqwiBSSf4F5Qk0xld2rBqzJ4= -github.com/sivchari/nosnakecase v1.7.0/go.mod h1:CwDzrzPea40/GB6uynrNLiorAlgFRvRbFSgJx2Gs+QY= -github.com/sivchari/tenv v1.7.1/go.mod h1:64yStXKSOxDfX47NlhVwND4dHwfZDdbp2Lyl018Icvg= -github.com/skeema/knownhosts v1.2.1/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= -github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M= -github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= -github.com/sonatard/noctx v0.0.2/go.mod h1:kzFz+CzWSjQ2OzIm46uJZoXuBpa2+0y3T36U18dWqIo= -github.com/sourcegraph/go-diff v0.7.0/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs= -github.com/ssgreg/nlreturn/v2 v2.2.1/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I= -github.com/stbenjam/no-sprintf-host-port v0.1.1/go.mod h1:TLhvtIvONRzdmkFiio4O8LHsN9N74I+PhRquPsxpL0I= -github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6/go.mod h1:39R/xuhNgVhi+K0/zst4TLrJrVmbm6LVgl4A0+ZFS5M= -github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo= -github.com/studio-b12/gowebdav v0.9.0/go.mod h1:bHA7t77X/QFExdeAnDzK6vKM34kEZAcE1OX4MfiwjkE= -github.com/syncthing/notify v0.0.0-20250207082249-f0fa8f99c2bc/go.mod h1:J0q59IWjLtpRIJulohwqEZvjzwOfTEPp8SVhDJl+y0Y= -github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= -github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c/go.mod h1:SbErYREK7xXdsRiigaQiQkI9McGRzYMvlKYaP3Nimdk= -github.com/tailscale/certstore v0.1.1-0.20231202035212-d3fa0460f47e/go.mod h1:XrBNfAFN+pwoWuksbFS9Ccxnopa15zJGgXRFN90l3K4= -github.com/tailscale/depaware v0.0.0-20210622194025-720c4b409502/go.mod h1:p9lPsd+cx33L3H9nNoecRRxPssFKUwwI50I3pZ0yT+8= -github.com/tailscale/go-winio v0.0.0-20231025203758-c4f33415bf55/go.mod h1:4k4QO+dQ3R5FofL+SanAUZe+/QfeK0+OIuwDIRu2vSg= -github.com/tailscale/goexpect v0.0.0-20210902213824-6e8c725cea41/go.mod h1:/roCdA6gg6lQyw/Oz6gIIGu3ggJKYhF+WC/AQReE5XQ= -github.com/tailscale/golang-x-crypto v0.0.0-20240604161659-3fde5e568aa4/go.mod h1:ikbF+YT089eInTp9f2vmvy4+ZVnW5hzX1q2WknxSprQ= -github.com/tailscale/goupnp v1.0.1-0.20210804011211-c64d0f06ea05/go.mod h1:PdCqy9JzfWMJf1H5UJW2ip33/d4YkoKN0r67yKH1mG8= -github.com/tailscale/hujson v0.0.0-20221223112325-20486734a56a/go.mod h1:DFSS3NAGHthKo1gTlmEcSBiZrRJXi28rLNd/1udP1c8= -github.com/tailscale/mkctr v0.0.0-20240628074852-17ca944da6ba/go.mod h1:DxnqIXBplij66U2ZkL688xy07q97qQ83P+TVueLiHq4= -github.com/tailscale/peercred v0.0.0-20240214030740-b535050b2aa4/go.mod h1:phI29ccmHQBc+wvroosENp1IF9195449VDnFDhJ4rJU= -github.com/tailscale/web-client-prebuilt v0.0.0-20240226180453-5db17b287bf1/go.mod h1:agQPE6y6ldqCOui2gkIh7ZMztTkIQKH049tv8siLuNQ= -github.com/tailscale/wf v0.0.0-20240214030419-6fbb0a674ee6/go.mod h1:ZXRML051h7o4OcI0d3AaILDIad/Xw0IkXaHM17dic1Y= -github.com/tailscale/wireguard-go v0.0.0-20240905161824-799c1978fafc/go.mod h1:BOm5fXUBFM+m9woLNBoxI9TaBXXhGNP50LX/TGIvGb4= -github.com/tailscale/xnet v0.0.0-20240729143630-8497ac4dab2e/go.mod h1:orPd6JZXXRyuDusYilywte7k094d7dycXXU5YnWsrwg= -github.com/tc-hib/winres v0.2.1/go.mod h1:C/JaNhH3KBvhNKVbvdlDWkbMDO9H4fKKDaN7/07SSuk= -github.com/tchap/go-patricia/v2 v2.3.1/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k= -github.com/tcnksm/go-httpstat v0.2.0/go.mod h1:s3JVJFtQxtBEBC9dwcdTTXS9xFnM3SXAZwPG41aurT8= -github.com/tdakkota/asciicheck v0.2.0/go.mod h1:Qb7Y9EgjCLJGup51gDHFzbI08/gbGhL/UVhYIPWG2rg= -github.com/tetafro/godot v1.4.11/go.mod h1:LR3CJpxDVGlYOWn3ZZg1PgNZdTUvzsZWu8xaEohUpn8= -github.com/tidwall/btree v1.6.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EUQ2cKY= -github.com/tidwall/buntdb v1.3.0/go.mod h1:lZZrZUWzlyDJKlLQ6DKAy53LnG7m5kHyrEHvvcDmBpU= -github.com/tidwall/gjson v1.16.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/grect v0.1.4/go.mod h1:9FBsaYRaR0Tcy4UwefBX/UDcDcDy9V5jUcxHzv2jd5Q= -github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= -github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= -github.com/tidwall/rtred v0.1.2/go.mod h1:hd69WNXQ5RP9vHd7dqekAz+RIdtfBogmglkZSRxCHFQ= -github.com/tidwall/tinyqueue v0.1.1/go.mod h1:O/QNHwrnjqr6IHItYrzoHAKYhBkLI67Q096fQP5zMYw= -github.com/timakin/bodyclose v0.0.0-20230421092635-574207250966/go.mod h1:27bSVNWSBOHm+qRp1T9qzaIpsWEP6TbUnei/43HK+PQ= -github.com/timonwong/loggercheck v0.9.4/go.mod h1:caz4zlPcgvpEkXgVnAJGowHAMW2NwHaNlpS8xDbVhTg= -github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75/go.mod h1:KO6IkyS8Y3j8OdNO85qEYBsRPuteD+YciPomcXdrMnk= -github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc/go.mod h1:bciPuU6GHm1iF1pBvUfxfsH0Wmnc2VbpgvbI9ZWuIRs= -github.com/tomarrell/wrapcheck/v2 v2.8.1/go.mod h1:/n2Q3NZ4XFT50ho6Hbxg+RV1uyo2Uow/Vdm9NQcl5SE= -github.com/tommy-muehle/go-mnd/v2 v2.5.1/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw= -github.com/toqueteos/webbrowser v1.2.0/go.mod h1:XWoZq4cyp9WeUeak7w7LXRUQf1F1ATJMir8RTqb4ayM= -github.com/twitchtv/twirp v8.1.3+incompatible/go.mod h1:RRJoFSAmTEh2weEqWtpPE3vFK5YBhA6bqp2l1kfCC5A= -github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= -github.com/u-root/u-root v0.12.0/go.mod h1:FYjTOh4IkIZHhjsd17lb8nYW6udgXdJhG1c0r6u0arI= -github.com/u-root/uio v0.0.0-20240118234441-a3c409a6018e/go.mod h1:eLL9Nub3yfAho7qB0MzZizFhTU2QkLeoVsWdHtDW264= -github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/ultraware/funlen v0.0.3/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= -github.com/ultraware/whitespace v0.0.5/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA= -github.com/uptrace/bun v1.1.17/go.mod h1:hATAzivtTIRsSJR4B8AXR+uABqnQxr3myKDKEf5iQ9U= -github.com/uptrace/bun/dialect/sqlitedialect v1.1.17/go.mod h1:YF0FO4VVnY9GHNH6rM4r3STlVEBxkOc6L88Bm5X5mzA= -github.com/urfave/cli v1.22.16/go.mod h1:EeJR6BKodywf4zciqrdw6hpCPk68JO9z5LazXZMn5Po= -github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= -github.com/uudashr/gocognit v1.0.6/go.mod h1:nAIUuVBnYU7pcninia3BHOvQkpQCeO76Uscky5BOwcY= -github.com/valkey-io/valkey-go v1.0.52/go.mod h1:BXlVAPIL9rFQinSFM+N32JfWzfCaUAqBpZkc4vPY6fM= -github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdIA3Xl7cH8g= -github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= -github.com/vbatts/tar-split v0.11.5/go.mod h1:yZbwRsSeGjusneWgA781EKej9HF8vme8okylkAeNKLk= -github.com/vektah/gqlparser/v2 v2.5.16/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= -github.com/veraison/go-cose v1.1.0/go.mod h1:7ziE85vSq4ScFTg6wyoMXjucIGOf4JkFEZi/an96Ct4= -github.com/vishvananda/netlink v1.3.0/go.mod h1:i6NetklAujEcC6fK0JPjT8qSwWyO0HLn4UKG+hGqeJs= -github.com/vmihailenco/bufpool v0.1.11/go.mod h1:AFf/MOy3l2CFTKbxwt0mp2MwnqjNEs5H/UxrkA5jxTQ= -github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= -github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= -github.com/willabides/kongplete v0.4.0/go.mod h1:0P0jtWD9aTsqPSUAl4de35DLghrr57XcayPyvqSi2X8= -github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= -github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= -github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= -github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= -github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU= -github.com/xiang90/probing v0.0.0-20221125231312-a49e3df8f510/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/yagipy/maintidx v1.0.0/go.mod h1:0qNf/I/CCZXSMhsRsrEPDZ+DkekpKLXAJfsTACwgXLk= -github.com/yashtewari/glob-intersection v0.2.0/go.mod h1:LK7pIC3piUjovexikBbJ26Yml7g8xa5bsjfx2v1fwok= -github.com/yeya24/promlinter v0.2.0/go.mod h1:u54lkmBOZrpEbQQ6gox2zWKKLKu2SGe+2KOiextY+IA= -github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= -github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= -github.com/zenazn/goji v1.0.1/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= -gitlab.com/bosi/decorder v0.2.3/go.mod h1:9K1RB5+VPNQYtXtTDAzd2OEftsZb1oV0IrJrzChSdGE= -gitlab.com/digitalxero/go-conventional-commit v1.0.7/go.mod h1:05Xc2BFsSyC5tKhK0y+P3bs0AwUtNuTp+mTpbCU/DZ0= -go.einride.tech/aip v0.66.0/go.mod h1:qAhMsfT7plxBX+Oy7Huol6YUvZ0ZzdUz26yZsQwfl1M= -go.etcd.io/bbolt v1.3.11/go.mod h1:dksAq7YMXoljX0xu6VF5DMZGbhYYoLUalEiSySYAS4I= -go.etcd.io/etcd/client/v2 v2.305.16/go.mod h1:h9YxWCzcdvZENbfzBTFCnoNumr2ax3F19sKMqHFmXHE= -go.etcd.io/etcd/pkg/v3 v3.5.16/go.mod h1:+lutCZHG5MBBFI/U4eYT5yL7sJfnexsoM20Y0t2uNuY= -go.etcd.io/etcd/raft/v3 v3.5.16/go.mod h1:P4UP14AxofMJ/54boWilabqqWoW9eLodl6I5GdGzazI= -go.etcd.io/etcd/server/v3 v3.5.16/go.mod h1:ynhyZZpdDp1Gq49jkUg5mfkDWZwXnn3eIqCqtJnrD/s= -go.mongodb.org/mongo-driver v1.12.1/go.mod h1:/rGBTebI3XYboVmgz+Wv3Bcbl3aD0QF9zl6kDDw18rQ= -go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk= -go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/collector v0.104.0 h1:R3zjM4O3K3+ttzsjPV75P80xalxRbwYTURlK0ys7uyo= -go.opentelemetry.io/collector v0.104.0/go.mod h1:Tm6F3na9ajnOm6I5goU9dURKxq1fSBK1yA94nvUix3k= -go.opentelemetry.io/collector/confmap v0.94.1/go.mod h1:pCT5UtcHaHVJ5BIILv1Z2VQyjZzmT9uTdBmC9+Z0AgA= -go.opentelemetry.io/collector/consumer v0.104.0/go.mod h1:60zcIb0W9GW0z9uJCv6NmjpSbCfBOeRUyrtEwqK6Hzo= -go.opentelemetry.io/collector/pdata/testdata v0.104.0/go.mod h1:3SnYKu8gLfxURJMWS/cFEUFs+jEKS6jvfqKXnOZsdkQ= -go.opentelemetry.io/collector/processor v0.104.0/go.mod h1:qU2/xCCYdvVORkN6aq0H/WUWkvo505VGYg2eOwPvaTg= -go.opentelemetry.io/contrib/detectors/gcp v1.34.0/go.mod h1:cV4BMFcscUR/ckqLkbfQmF0PRsq8w/lMGzdbCSveBHo= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0/go.mod h1:ijPqXp5P6IRRByFVVg9DY8P5HkxkHE5ARIa+86aXPf4= -golang.org/x/arch v0.4.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/exp/typeparams v0.0.0-20240119083558-1b970713d09a/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= -golang.org/x/image v0.18.0/go.mod h1:4yyo5vMFQjVjUcVk4jEQcU9MGy/rulF5WvUILseCM2E= -golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= -golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0= -golang.org/x/tools v0.31.0/go.mod h1:naFTU+Cev749tSJRXJlna0T3WxKvb1kWEx15xA4SdmQ= -google.golang.org/genproto v0.0.0-20240325203815-454cdb8f5daa h1:ePqxpG3LVx+feAUOx8YmR5T7rc0rdzK8DyxM8cQ9zq0= -google.golang.org/genproto v0.0.0-20240325203815-454cdb8f5daa/go.mod h1:CnZenrTdRJb7jc+jOm0Rkywq+9wh0QC4U8tyiRbEPPM= -google.golang.org/genproto v0.0.0-20240924160255-9d4c2d233b61 h1:KipVMxePgXPFBzXOvpKbny3RVdVmJOD64R/Ob7GPWEs= -google.golang.org/genproto v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:HiAZQz/G7n0EywFjmncAwsfnmFm2bjm7qPjwl8hyzjM= -google.golang.org/genproto/googleapis/bytestream v0.0.0-20250313205543-e70fdf4c4cb4/go.mod h1:WkJpQl6Ujj3ElX4qZaNm5t6cT95ffI4K+HKQ0+1NyMw= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1/go.mod h1:5KF+wpkbTSbGcR9zteSqZV6fqFOWBl4Yde8En8MryZA= -gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= -gopkg.in/jinzhu/gorm.v1 v1.9.2/go.mod h1:56JJPUzbikvTVnoyP1nppSkbJ2L8sunqTBDY2fDrmFg= -gopkg.in/olivere/elastic.v3 v3.0.75/go.mod h1:yDEuSnrM51Pc8dM5ov7U8aI/ToR3PG0llA8aRv2qmw0= -gopkg.in/olivere/elastic.v5 v5.0.84/go.mod h1:LXF6q9XNBxpMqrcgax95C6xyARXWbbCXUrtTxrNrxJI= -gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= -gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= -gorm.io/driver/mysql v1.0.1/go.mod h1:KtqSthtg55lFp3S5kUXqlGaelnWpKitn4k1xZTnoiPw= -gorm.io/driver/postgres v1.4.6/go.mod h1:UJChCNLFKeBqQRE+HrkFUbKbq9idPXmTOk2u4Wok8S4= -gorm.io/driver/sqlserver v1.4.2/go.mod h1:XHwBuB4Tlh7DqO0x7Ema8dmyWsQW7wi38VQOAFkrbXY= -gorm.io/gorm v1.25.3/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= -honnef.co/go/tools v0.5.1/go.mod h1:e9irvo83WDG9/irijV44wr3tbhcFeRnfpVlRqVwpzMs= -howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g= -k8s.io/cloud-provider v0.32.2/go.mod h1:2s8TeAXhVezp5VISaTxM6vW3yDonOZXoN4Aryz1p1PQ= -k8s.io/code-generator v0.32.3/go.mod h1:+mbiYID5NLsBuqxjQTygKM/DAdKpAjvBzrJd64NU1G8= -k8s.io/component-helpers v0.32.3/go.mod h1:utTBXk8lhkJewBKNuNf32Xl3KT/0VV19DmiXU/SV4Ao= -k8s.io/controller-manager v0.32.2/go.mod h1:o5uo2tLCQhuoMt0RfKcQd0eqaNmSKOKiT+0YELCqXOk= -k8s.io/cri-api v0.27.1/go.mod h1:+Ts/AVYbIo04S86XbTD73UPp/DkTiYxtsFeOFEu32L0= -k8s.io/gengo/v2 v2.0.0-20240911193312-2b36238f13e9/go.mod h1:EJykeLsmFC60UQbYJezXkEsG2FLrt0GPNkU5iK5GWxU= -k8s.io/gengo/v2 v2.0.0-20250207200755-1244d31929d7/go.mod h1:EJykeLsmFC60UQbYJezXkEsG2FLrt0GPNkU5iK5GWxU= -k8s.io/kms v0.32.3/go.mod h1:Bk2evz/Yvk0oVrvm4MvZbgq8BD34Ksxs2SRHn4/UiOM= -k8s.io/kube-controller-manager v0.32.2/go.mod h1:x7998ZLC+2lYnoizUwvVtHVPuoLeb7BhQEneeiNyVOg= -k8s.io/kubelet v0.32.2/go.mod h1:cC1ms5RS+lu0ckVr6AviCQXHLSPKEBC3D5oaCBdTGkI= -k8s.io/kubernetes v1.32.2/go.mod h1:tiIKO63GcdPRBHW2WiUFm3C0eoLczl3f7qi56Dm1W8I= -k8s.io/metrics v0.32.3/go.mod h1:9R1Wk5cb+qJpCQon9h52mgkVCcFeYxcY+YkumfwHVCU= -mellium.im/sasl v0.3.1/go.mod h1:xm59PUYpZHhgQ9ZqoJ5QaCqzWMi8IeS49dhp6plPCzw= -mvdan.cc/gofumpt v0.5.0/go.mod h1:HBeVDtMKRZpXyxFciAirzdKklDlGu8aAy1wEbH5Y9js= -mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= -mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= -mvdan.cc/unparam v0.0.0-20230312165513-e84e2d14e3b8/go.mod h1:Oh/d7dEtzsNHGOq1Cdv8aMm3KdKhVvPbRQcM8WFpBR8= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.1/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= -sigs.k8s.io/controller-tools v0.15.1-0.20240618033008-7824932b0cab/go.mod h1:egedX5jq2KrZ3A2zaOz3e2DSsh5BhFyyjvNcBRIQel8= -sigs.k8s.io/controller-tools v0.17.2/go.mod h1:4q5tZG2JniS5M5bkiXY2/potOiXyhoZVw/U48vLkXk0= -sigs.k8s.io/kustomize/kustomize/v5 v5.5.0/go.mod h1:AeFCmgCrXzmvjWWaeZCyBp6XzG1Y0w1svYus8GhJEOE= -software.sslmate.com/src/go-pkcs12 v0.4.0/go.mod h1:Qiz0EyvDRJjjxGyUQa2cCNZn/wMyzrRJ/qcDXOQazLI= -tags.cncf.io/container-device-interface v0.8.1/go.mod h1:Apb7N4VdILW0EVdEMRYXIDVRZfNJZ+kmEUss2kRRQ6Y= -tags.cncf.io/container-device-interface/specs-go v0.8.0/go.mod h1:BhJIkjjPh4qpys+qm4DAYtUyryaTDg9zris+AczXyws= +google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 h1:KAeGQVN3M9nD0/bQXnr/ClcEMJ968gUXJQ9pwfSynuQ= diff --git a/pkg/dns/coredns.go b/pkg/dns/coredns.go deleted file mode 100644 index 1d68fd4f..00000000 --- a/pkg/dns/coredns.go +++ /dev/null @@ -1,60 +0,0 @@ -package dns - -import ( - "bytes" - "text/template" -) - -type CoreFile struct { - Content []byte -} - -// Body Gets the Caddyfile contents -func (c *CoreFile) Body() []byte { - return c.Content -} - -// Path Gets the path to the origin file -func (c *CoreFile) Path() string { - return "CoreFile" -} - -// ServerType The type of server this input is intended for -func (c *CoreFile) ServerType() string { - return "dns" -} - -type CoreFileTmpl struct { - UpstreamDNS string - Nameservers string -} - -func BuildCoreFile(corefileTmpl CoreFileTmpl) (*CoreFile, error) { - tplText := ` -.:53 { - bind 127.0.0.1 - forward cluster.local {{ .UpstreamDNS }} - forward . {{ .Nameservers }} {{ .UpstreamDNS }} { - policy sequential - max_concurrent 1 - } - cache 30 - log - errors - reload -}` - - tpl, err := template.New("corefile").Parse(tplText) - if err != nil { - return nil, err - } - - data := bytes.NewBuffer(nil) - if err := tpl.Execute(data, corefileTmpl); err != nil { - return nil, err - } - - return &CoreFile{ - Content: data.Bytes(), - }, nil -} diff --git a/pkg/dns/dns_linux.go b/pkg/dns/dns_linux.go index 7bfc535f..7f9db4db 100644 --- a/pkg/dns/dns_linux.go +++ b/pkg/dns/dns_linux.go @@ -13,9 +13,6 @@ import ( "os/exec" "strings" - "github.com/coredns/caddy" - _ "github.com/coredns/coredns/core/dnsserver" - _ "github.com/coredns/coredns/core/plugin" "github.com/docker/docker/libnetwork/resolvconf" miekgdns "github.com/miekg/dns" "k8s.io/apimachinery/pkg/util/sets" @@ -31,24 +28,7 @@ func (c *Config) SetupDNS(ctx context.Context) error { config := c.Config tunName := c.TunName - // 1) setup dns by magicDNS - plog.G(ctx).Debugf("Use library to setup DNS...") - // https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/store-information-in-variables#default-environment-variables - if _, found := os.LookupEnv("GITHUB_ACTIONS"); !found { - err := c.UseLibraryDNS(tunName, config) - if err == nil { - plog.G(ctx).Debugf("Use library to setup DNS done") - return nil - } else if errors.Is(err, ErrorNotSupportSplitDNS) { - plog.G(ctx).Debugf("Library not support on current OS") - err = nil - } else { - plog.G(ctx).Errorf("Setup DNS by library failed: %v", err) - err = nil - } - } - - // 2) use systemctl or resolvectl to setup dns + // 1) use systemctl or resolvectl to setup dns plog.G(ctx).Debugf("Use systemd to setup DNS...") // TODO consider use https://wiki.debian.org/NetworkManager and nmcli to config DNS // try to solve: @@ -66,20 +46,30 @@ func (c *Config) SetupDNS(ctx context.Context) error { _, err := exec.LookPath(cmd) return err == nil } - var success bool plog.G(ctx).Debugf("Try to setup DNS by resolvectl or systemd-resolve...") if exists("resolvectl") { if setupDnsByCmdResolvectl(ctx, tunName, config) == nil { - success = true + return nil } } if exists("systemd-resolve") { if setupDNSbyCmdSystemdResolve(ctx, tunName, config) == nil { - success = true + return nil } } - if success { + + // 2) setup dns by magicDNS + plog.G(ctx).Debugf("Use library to setup DNS...") + err := c.UseLibraryDNS(tunName, config) + if err == nil { + plog.G(ctx).Debugf("Use library to setup DNS done") return nil + } else if errors.Is(err, ErrorNotSupportSplitDNS) { + plog.G(ctx).Debugf("Library not support on current OS") + err = nil + } else { + plog.G(ctx).Errorf("Setup DNS by library failed: %v", err) + err = nil } // 3) write dns info to file: /etc/resolv.conf @@ -164,32 +154,6 @@ func (c *Config) UseLibraryDNS(tunName string, clientConfig *miekgdns.ClientConf return c.OSConfigurator.SetDNS(config) } -func SetupLocalDNS(ctx context.Context, clientConfig *miekgdns.ClientConfig, existNameservers []string) error { - corefile, err := BuildCoreFile(CoreFileTmpl{ - UpstreamDNS: clientConfig.Servers[0], - Nameservers: strings.Join(existNameservers, " "), - }) - if err != nil { - return err - } - - plog.G(ctx).Debugf("Corefile content: %s", string(corefile.Body())) - - // Start your engines - instance, err := caddy.Start(corefile) - if err != nil { - return err - } - - // Twiddle your thumbs - go instance.Wait() - go func() { - <-ctx.Done() - instance.Stop() - }() - return nil -} - func (c *Config) CancelDNS() { c.removeHosts(sets.New[Entry]().Insert(c.Hosts...).UnsortedList()) if c.OSConfigurator != nil { diff --git a/pkg/dns/forwardserver.go b/pkg/dns/forward_server.go similarity index 100% rename from pkg/dns/forwardserver.go rename to pkg/dns/forward_server.go diff --git a/pkg/dns/forwardserver_test.go b/pkg/dns/forward_server_test.go similarity index 100% rename from pkg/dns/forwardserver_test.go rename to pkg/dns/forward_server_test.go diff --git a/pkg/handler/function_test.go b/pkg/handler/function_test.go index 2d09a65d..04b1e364 100644 --- a/pkg/handler/function_test.go +++ b/pkg/handler/function_test.go @@ -393,7 +393,7 @@ func udpClient(t *testing.T, ip string, port int) error { func udpServer(t *testing.T, port int) { // 创建监听 udpConn, err := net.ListenUDP("udp4", &net.UDPAddr{ - IP: net.IPv4(0, 0, 0, 0), + IP: net.ParseIP("127.0.0.1"), Port: port, }) if err != nil { diff --git a/vendor/cloud.google.com/go/auth/CHANGES.md b/vendor/cloud.google.com/go/auth/CHANGES.md deleted file mode 100644 index 500c34cf..00000000 --- a/vendor/cloud.google.com/go/auth/CHANGES.md +++ /dev/null @@ -1,396 +0,0 @@ -# Changelog - -## [0.15.0](https://github.com/googleapis/google-cloud-go/compare/auth/v0.14.1...auth/v0.15.0) (2025-02-19) - - -### Features - -* **auth:** Add hard-bound token request to compute token provider. ([#11588](https://github.com/googleapis/google-cloud-go/issues/11588)) ([0e608bb](https://github.com/googleapis/google-cloud-go/commit/0e608bb5ac3d694c8ad36ca4340071d3a2c78699)) - -## [0.14.1](https://github.com/googleapis/google-cloud-go/compare/auth/v0.14.0...auth/v0.14.1) (2025-01-24) - - -### Documentation - -* **auth:** Add warning about externally-provided credentials ([#11462](https://github.com/googleapis/google-cloud-go/issues/11462)) ([49fb6ff](https://github.com/googleapis/google-cloud-go/commit/49fb6ff4d754895f82c9c4d502fc7547d3b5a941)) - -## [0.14.0](https://github.com/googleapis/google-cloud-go/compare/auth/v0.13.0...auth/v0.14.0) (2025-01-08) - - -### Features - -* **auth:** Add universe domain support to idtoken ([#11059](https://github.com/googleapis/google-cloud-go/issues/11059)) ([72add7e](https://github.com/googleapis/google-cloud-go/commit/72add7e9f8f455af695e8ef79212a4bd3122fb3a)) - - -### Bug Fixes - -* **auth/oauth2adapt:** Update golang.org/x/net to v0.33.0 ([e9b0b69](https://github.com/googleapis/google-cloud-go/commit/e9b0b69644ea5b276cacff0a707e8a5e87efafc9)) -* **auth:** Fix copy of delegates in impersonate.NewIDTokenCredentials ([#11386](https://github.com/googleapis/google-cloud-go/issues/11386)) ([ff7ef8e](https://github.com/googleapis/google-cloud-go/commit/ff7ef8e7ade7171bce3e4f30ff10a2e9f6c27ca0)), refs [#11379](https://github.com/googleapis/google-cloud-go/issues/11379) -* **auth:** Update golang.org/x/net to v0.33.0 ([e9b0b69](https://github.com/googleapis/google-cloud-go/commit/e9b0b69644ea5b276cacff0a707e8a5e87efafc9)) - -## [0.13.0](https://github.com/googleapis/google-cloud-go/compare/auth/v0.12.1...auth/v0.13.0) (2024-12-13) - - -### Features - -* **auth:** Add logging support ([#11079](https://github.com/googleapis/google-cloud-go/issues/11079)) ([c80e31d](https://github.com/googleapis/google-cloud-go/commit/c80e31df5ecb33a810be3dfb9d9e27ac531aa91d)) -* **auth:** Pass logger from auth layer to metadata package ([#11288](https://github.com/googleapis/google-cloud-go/issues/11288)) ([b552efd](https://github.com/googleapis/google-cloud-go/commit/b552efd6ab34e5dfded18438e0fbfd925805614f)) - - -### Bug Fixes - -* **auth:** Check compute cred type before non-default flag for DP ([#11255](https://github.com/googleapis/google-cloud-go/issues/11255)) ([4347ca1](https://github.com/googleapis/google-cloud-go/commit/4347ca141892be8ae813399b4b437662a103bc90)) - -## [0.12.1](https://github.com/googleapis/google-cloud-go/compare/auth/v0.12.0...auth/v0.12.1) (2024-12-10) - - -### Bug Fixes - -* **auth:** Correct typo in link ([#11160](https://github.com/googleapis/google-cloud-go/issues/11160)) ([af6fb46](https://github.com/googleapis/google-cloud-go/commit/af6fb46d7cd694ddbe8c9d63bc4cdcd62b9fb2c1)) - -## [0.12.0](https://github.com/googleapis/google-cloud-go/compare/auth/v0.11.0...auth/v0.12.0) (2024-12-04) - - -### Features - -* **auth:** Add support for providing custom certificate URL ([#11006](https://github.com/googleapis/google-cloud-go/issues/11006)) ([ebf3657](https://github.com/googleapis/google-cloud-go/commit/ebf36579724afb375d3974cf1da38f703e3b7dbc)), refs [#11005](https://github.com/googleapis/google-cloud-go/issues/11005) - - -### Bug Fixes - -* **auth:** Ensure endpoints are present in Validator ([#11209](https://github.com/googleapis/google-cloud-go/issues/11209)) ([106cd53](https://github.com/googleapis/google-cloud-go/commit/106cd53309facaef1b8ea78376179f523f6912b9)), refs [#11006](https://github.com/googleapis/google-cloud-go/issues/11006) [#11190](https://github.com/googleapis/google-cloud-go/issues/11190) [#11189](https://github.com/googleapis/google-cloud-go/issues/11189) [#11188](https://github.com/googleapis/google-cloud-go/issues/11188) - -## [0.11.0](https://github.com/googleapis/google-cloud-go/compare/auth/v0.10.2...auth/v0.11.0) (2024-11-21) - - -### Features - -* **auth:** Add universe domain support to mTLS ([#11159](https://github.com/googleapis/google-cloud-go/issues/11159)) ([117748b](https://github.com/googleapis/google-cloud-go/commit/117748ba1cfd4ae62a6a4feb7e30951cb2bc9344)) - -## [0.10.2](https://github.com/googleapis/google-cloud-go/compare/auth/v0.10.1...auth/v0.10.2) (2024-11-12) - - -### Bug Fixes - -* **auth:** Restore use of grpc.Dial ([#11118](https://github.com/googleapis/google-cloud-go/issues/11118)) ([2456b94](https://github.com/googleapis/google-cloud-go/commit/2456b943b7b8aaabd4d8bfb7572c0f477ae0db45)), refs [#7556](https://github.com/googleapis/google-cloud-go/issues/7556) - -## [0.10.1](https://github.com/googleapis/google-cloud-go/compare/auth/v0.10.0...auth/v0.10.1) (2024-11-06) - - -### Bug Fixes - -* **auth:** Restore Application Default Credentials support to idtoken ([#11083](https://github.com/googleapis/google-cloud-go/issues/11083)) ([8771f2e](https://github.com/googleapis/google-cloud-go/commit/8771f2ea9807ab822083808e0678392edff3b4f2)) -* **auth:** Skip impersonate universe domain check if empty ([#11086](https://github.com/googleapis/google-cloud-go/issues/11086)) ([87159c1](https://github.com/googleapis/google-cloud-go/commit/87159c1059d4a18d1367ce62746a838a94964ab6)) - -## [0.10.0](https://github.com/googleapis/google-cloud-go/compare/auth/v0.9.9...auth/v0.10.0) (2024-10-30) - - -### Features - -* **auth:** Add universe domain support to credentials/impersonate ([#10953](https://github.com/googleapis/google-cloud-go/issues/10953)) ([e06cb64](https://github.com/googleapis/google-cloud-go/commit/e06cb6499f7eda3aef08ab18ff197016f667684b)) - -## [0.9.9](https://github.com/googleapis/google-cloud-go/compare/auth/v0.9.8...auth/v0.9.9) (2024-10-22) - - -### Bug Fixes - -* **auth:** Fallback cert lookups for missing files ([#11013](https://github.com/googleapis/google-cloud-go/issues/11013)) ([bd76695](https://github.com/googleapis/google-cloud-go/commit/bd766957ec238b7c40ddbabb369e612dc9b07313)), refs [#10844](https://github.com/googleapis/google-cloud-go/issues/10844) -* **auth:** Replace MDS endpoint universe_domain with universe-domain ([#11000](https://github.com/googleapis/google-cloud-go/issues/11000)) ([6a1586f](https://github.com/googleapis/google-cloud-go/commit/6a1586f2ce9974684affaea84e7b629313b4d114)) - -## [0.9.8](https://github.com/googleapis/google-cloud-go/compare/auth/v0.9.7...auth/v0.9.8) (2024-10-09) - - -### Bug Fixes - -* **auth:** Restore OpenTelemetry handling in transports ([#10968](https://github.com/googleapis/google-cloud-go/issues/10968)) ([08c6d04](https://github.com/googleapis/google-cloud-go/commit/08c6d04901c1a20e219b2d86df41dbaa6d7d7b55)), refs [#10962](https://github.com/googleapis/google-cloud-go/issues/10962) -* **auth:** Try talk to plaintext S2A if credentials can not be found for mTLS-S2A ([#10941](https://github.com/googleapis/google-cloud-go/issues/10941)) ([0f0bf2d](https://github.com/googleapis/google-cloud-go/commit/0f0bf2d18c97dd8b65bcf0099f0802b5631c6287)) - -## [0.9.7](https://github.com/googleapis/google-cloud-go/compare/auth/v0.9.6...auth/v0.9.7) (2024-10-01) - - -### Bug Fixes - -* **auth:** Restore support for non-default service accounts for DirectPath ([#10937](https://github.com/googleapis/google-cloud-go/issues/10937)) ([a38650e](https://github.com/googleapis/google-cloud-go/commit/a38650edbf420223077498cafa537aec74b37aad)), refs [#10907](https://github.com/googleapis/google-cloud-go/issues/10907) - -## [0.9.6](https://github.com/googleapis/google-cloud-go/compare/auth/v0.9.5...auth/v0.9.6) (2024-09-30) - - -### Bug Fixes - -* **auth:** Make aws credentials provider retrieve fresh credentials ([#10920](https://github.com/googleapis/google-cloud-go/issues/10920)) ([250fbf8](https://github.com/googleapis/google-cloud-go/commit/250fbf87d858d865e399a241b7e537c4ff0c3dd8)) - -## [0.9.5](https://github.com/googleapis/google-cloud-go/compare/auth/v0.9.4...auth/v0.9.5) (2024-09-25) - - -### Bug Fixes - -* **auth:** Restore support for GOOGLE_CLOUD_UNIVERSE_DOMAIN env ([#10915](https://github.com/googleapis/google-cloud-go/issues/10915)) ([94caaaa](https://github.com/googleapis/google-cloud-go/commit/94caaaa061362d0e00ef6214afcc8a0a3e7ebfb2)) -* **auth:** Skip directpath credentials overwrite when it's not on GCE ([#10833](https://github.com/googleapis/google-cloud-go/issues/10833)) ([7e5e8d1](https://github.com/googleapis/google-cloud-go/commit/7e5e8d10b761b0a6e43e19a028528db361bc07b1)) -* **auth:** Use new context for non-blocking token refresh ([#10919](https://github.com/googleapis/google-cloud-go/issues/10919)) ([cf7102d](https://github.com/googleapis/google-cloud-go/commit/cf7102d33a21be1e5a9d47a49456b3a57c43b350)) - -## [0.9.4](https://github.com/googleapis/google-cloud-go/compare/auth/v0.9.3...auth/v0.9.4) (2024-09-11) - - -### Bug Fixes - -* **auth:** Enable self-signed JWT for non-GDU universe domain ([#10831](https://github.com/googleapis/google-cloud-go/issues/10831)) ([f9869f7](https://github.com/googleapis/google-cloud-go/commit/f9869f7903cfd34d1b97c25d0dc5669d2c5138e6)) - -## [0.9.3](https://github.com/googleapis/google-cloud-go/compare/auth/v0.9.2...auth/v0.9.3) (2024-09-03) - - -### Bug Fixes - -* **auth:** Choose quota project envvar over file when both present ([#10807](https://github.com/googleapis/google-cloud-go/issues/10807)) ([2d8dd77](https://github.com/googleapis/google-cloud-go/commit/2d8dd7700eff92d4b95027be55e26e1e7aa79181)), refs [#10804](https://github.com/googleapis/google-cloud-go/issues/10804) - -## [0.9.2](https://github.com/googleapis/google-cloud-go/compare/auth/v0.9.1...auth/v0.9.2) (2024-08-30) - - -### Bug Fixes - -* **auth:** Handle non-Transport DefaultTransport ([#10733](https://github.com/googleapis/google-cloud-go/issues/10733)) ([98d91dc](https://github.com/googleapis/google-cloud-go/commit/98d91dc8316b247498fab41ab35e57a0446fe556)), refs [#10742](https://github.com/googleapis/google-cloud-go/issues/10742) -* **auth:** Make sure quota option takes precedence over env/file ([#10797](https://github.com/googleapis/google-cloud-go/issues/10797)) ([f1b050d](https://github.com/googleapis/google-cloud-go/commit/f1b050d56d804b245cab048c2980d32b0eaceb4e)), refs [#10795](https://github.com/googleapis/google-cloud-go/issues/10795) - - -### Documentation - -* **auth:** Fix Go doc comment link ([#10751](https://github.com/googleapis/google-cloud-go/issues/10751)) ([015acfa](https://github.com/googleapis/google-cloud-go/commit/015acfab4d172650928bb1119bc2cd6307b9a437)) - -## [0.9.1](https://github.com/googleapis/google-cloud-go/compare/auth/v0.9.0...auth/v0.9.1) (2024-08-22) - - -### Bug Fixes - -* **auth:** Setting expireEarly to default when the value is 0 ([#10732](https://github.com/googleapis/google-cloud-go/issues/10732)) ([5e67869](https://github.com/googleapis/google-cloud-go/commit/5e67869a31e9e8ecb4eeebd2cfa11a761c3b1948)) - -## [0.9.0](https://github.com/googleapis/google-cloud-go/compare/auth/v0.8.1...auth/v0.9.0) (2024-08-16) - - -### Features - -* **auth:** Auth library can talk to S2A over mTLS ([#10634](https://github.com/googleapis/google-cloud-go/issues/10634)) ([5250a13](https://github.com/googleapis/google-cloud-go/commit/5250a13ec95b8d4eefbe0158f82857ff2189cb45)) - -## [0.8.1](https://github.com/googleapis/google-cloud-go/compare/auth/v0.8.0...auth/v0.8.1) (2024-08-13) - - -### Bug Fixes - -* **auth:** Make default client creation more lenient ([#10669](https://github.com/googleapis/google-cloud-go/issues/10669)) ([1afb9ee](https://github.com/googleapis/google-cloud-go/commit/1afb9ee1ee9de9810722800018133304a0ca34d1)), refs [#10638](https://github.com/googleapis/google-cloud-go/issues/10638) - -## [0.8.0](https://github.com/googleapis/google-cloud-go/compare/auth/v0.7.3...auth/v0.8.0) (2024-08-07) - - -### Features - -* **auth:** Adds support for X509 workload identity federation ([#10373](https://github.com/googleapis/google-cloud-go/issues/10373)) ([5d07505](https://github.com/googleapis/google-cloud-go/commit/5d075056cbe27bb1da4072a26070c41f8999eb9b)) - -## [0.7.3](https://github.com/googleapis/google-cloud-go/compare/auth/v0.7.2...auth/v0.7.3) (2024-08-01) - - -### Bug Fixes - -* **auth/oauth2adapt:** Update dependencies ([257c40b](https://github.com/googleapis/google-cloud-go/commit/257c40bd6d7e59730017cf32bda8823d7a232758)) -* **auth:** Disable automatic universe domain check for MDS ([#10620](https://github.com/googleapis/google-cloud-go/issues/10620)) ([7cea5ed](https://github.com/googleapis/google-cloud-go/commit/7cea5edd5a0c1e6bca558696f5607879141910e8)) -* **auth:** Update dependencies ([257c40b](https://github.com/googleapis/google-cloud-go/commit/257c40bd6d7e59730017cf32bda8823d7a232758)) - -## [0.7.2](https://github.com/googleapis/google-cloud-go/compare/auth/v0.7.1...auth/v0.7.2) (2024-07-22) - - -### Bug Fixes - -* **auth:** Use default client for universe metadata lookup ([#10551](https://github.com/googleapis/google-cloud-go/issues/10551)) ([d9046fd](https://github.com/googleapis/google-cloud-go/commit/d9046fdd1435d1ce48f374806c1def4cb5ac6cd3)), refs [#10544](https://github.com/googleapis/google-cloud-go/issues/10544) - -## [0.7.1](https://github.com/googleapis/google-cloud-go/compare/auth/v0.7.0...auth/v0.7.1) (2024-07-10) - - -### Bug Fixes - -* **auth:** Bump google.golang.org/grpc@v1.64.1 ([8ecc4e9](https://github.com/googleapis/google-cloud-go/commit/8ecc4e9622e5bbe9b90384d5848ab816027226c5)) - -## [0.7.0](https://github.com/googleapis/google-cloud-go/compare/auth/v0.6.1...auth/v0.7.0) (2024-07-09) - - -### Features - -* **auth:** Add workload X509 cert provider as a default cert provider ([#10479](https://github.com/googleapis/google-cloud-go/issues/10479)) ([c51ee6c](https://github.com/googleapis/google-cloud-go/commit/c51ee6cf65ce05b4d501083e49d468c75ac1ea63)) - - -### Bug Fixes - -* **auth/oauth2adapt:** Bump google.golang.org/api@v0.187.0 ([8fa9e39](https://github.com/googleapis/google-cloud-go/commit/8fa9e398e512fd8533fd49060371e61b5725a85b)) -* **auth:** Bump google.golang.org/api@v0.187.0 ([8fa9e39](https://github.com/googleapis/google-cloud-go/commit/8fa9e398e512fd8533fd49060371e61b5725a85b)) -* **auth:** Check len of slices, not non-nil ([#10483](https://github.com/googleapis/google-cloud-go/issues/10483)) ([0a966a1](https://github.com/googleapis/google-cloud-go/commit/0a966a183e5f0e811977216d736d875b7233e942)) - -## [0.6.1](https://github.com/googleapis/google-cloud-go/compare/auth/v0.6.0...auth/v0.6.1) (2024-07-01) - - -### Bug Fixes - -* **auth:** Support gRPC API keys ([#10460](https://github.com/googleapis/google-cloud-go/issues/10460)) ([daa6646](https://github.com/googleapis/google-cloud-go/commit/daa6646d2af5d7fb5b30489f4934c7db89868c7c)) -* **auth:** Update http and grpc transports to support token exchange over mTLS ([#10397](https://github.com/googleapis/google-cloud-go/issues/10397)) ([c6dfdcf](https://github.com/googleapis/google-cloud-go/commit/c6dfdcf893c3f971eba15026c12db0a960ae81f2)) - -## [0.6.0](https://github.com/googleapis/google-cloud-go/compare/auth/v0.5.2...auth/v0.6.0) (2024-06-25) - - -### Features - -* **auth:** Add non-blocking token refresh for compute MDS ([#10263](https://github.com/googleapis/google-cloud-go/issues/10263)) ([9ac350d](https://github.com/googleapis/google-cloud-go/commit/9ac350da11a49b8e2174d3fc5b1a5070fec78b4e)) - - -### Bug Fixes - -* **auth:** Return error if envvar detected file returns an error ([#10431](https://github.com/googleapis/google-cloud-go/issues/10431)) ([e52b9a7](https://github.com/googleapis/google-cloud-go/commit/e52b9a7c45468827f5d220ab00965191faeb9d05)) - -## [0.5.2](https://github.com/googleapis/google-cloud-go/compare/auth/v0.5.1...auth/v0.5.2) (2024-06-24) - - -### Bug Fixes - -* **auth:** Fetch initial token when CachedTokenProviderOptions.DisableAutoRefresh is true ([#10415](https://github.com/googleapis/google-cloud-go/issues/10415)) ([3266763](https://github.com/googleapis/google-cloud-go/commit/32667635ca2efad05cd8c087c004ca07d7406913)), refs [#10414](https://github.com/googleapis/google-cloud-go/issues/10414) - -## [0.5.1](https://github.com/googleapis/google-cloud-go/compare/auth/v0.5.0...auth/v0.5.1) (2024-05-31) - - -### Bug Fixes - -* **auth:** Pass through client to 2LO and 3LO flows ([#10290](https://github.com/googleapis/google-cloud-go/issues/10290)) ([685784e](https://github.com/googleapis/google-cloud-go/commit/685784ea84358c15e9214bdecb307d37aa3b6d2f)) - -## [0.5.0](https://github.com/googleapis/google-cloud-go/compare/auth/v0.4.2...auth/v0.5.0) (2024-05-28) - - -### Features - -* **auth:** Adds X509 workload certificate provider ([#10233](https://github.com/googleapis/google-cloud-go/issues/10233)) ([17a9db7](https://github.com/googleapis/google-cloud-go/commit/17a9db73af35e3d1a7a25ac4fd1377a103de6150)) - -## [0.4.2](https://github.com/googleapis/google-cloud-go/compare/auth/v0.4.1...auth/v0.4.2) (2024-05-16) - - -### Bug Fixes - -* **auth:** Enable client certificates by default only for GDU ([#10151](https://github.com/googleapis/google-cloud-go/issues/10151)) ([7c52978](https://github.com/googleapis/google-cloud-go/commit/7c529786275a39b7e00525f7d5e7be0d963e9e15)) -* **auth:** Handle non-Transport DefaultTransport ([#10162](https://github.com/googleapis/google-cloud-go/issues/10162)) ([fa3bfdb](https://github.com/googleapis/google-cloud-go/commit/fa3bfdb23aaa45b34394a8b61e753b3587506782)), refs [#10159](https://github.com/googleapis/google-cloud-go/issues/10159) -* **auth:** Have refresh time match docs ([#10147](https://github.com/googleapis/google-cloud-go/issues/10147)) ([bcb5568](https://github.com/googleapis/google-cloud-go/commit/bcb5568c07a54dd3d2e869d15f502b0741a609e8)) -* **auth:** Update compute token fetching error with named prefix ([#10180](https://github.com/googleapis/google-cloud-go/issues/10180)) ([4573504](https://github.com/googleapis/google-cloud-go/commit/4573504828d2928bebedc875d87650ba227829ea)) - -## [0.4.1](https://github.com/googleapis/google-cloud-go/compare/auth/v0.4.0...auth/v0.4.1) (2024-05-09) - - -### Bug Fixes - -* **auth:** Don't try to detect default creds it opt configured ([#10143](https://github.com/googleapis/google-cloud-go/issues/10143)) ([804632e](https://github.com/googleapis/google-cloud-go/commit/804632e7c5b0b85ff522f7951114485e256eb5bc)) - -## [0.4.0](https://github.com/googleapis/google-cloud-go/compare/auth/v0.3.0...auth/v0.4.0) (2024-05-07) - - -### Features - -* **auth:** Enable client certificates by default ([#10102](https://github.com/googleapis/google-cloud-go/issues/10102)) ([9013e52](https://github.com/googleapis/google-cloud-go/commit/9013e5200a6ec0f178ed91acb255481ffb073a2c)) - - -### Bug Fixes - -* **auth:** Get s2a logic up to date ([#10093](https://github.com/googleapis/google-cloud-go/issues/10093)) ([4fe9ae4](https://github.com/googleapis/google-cloud-go/commit/4fe9ae4b7101af2a5221d6d6b2e77b479305bb06)) - -## [0.3.0](https://github.com/googleapis/google-cloud-go/compare/auth/v0.2.2...auth/v0.3.0) (2024-04-23) - - -### Features - -* **auth/httptransport:** Add ability to customize transport ([#10023](https://github.com/googleapis/google-cloud-go/issues/10023)) ([72c7f6b](https://github.com/googleapis/google-cloud-go/commit/72c7f6bbec3136cc7a62788fc7186bc33ef6c3b3)), refs [#9812](https://github.com/googleapis/google-cloud-go/issues/9812) [#9814](https://github.com/googleapis/google-cloud-go/issues/9814) - - -### Bug Fixes - -* **auth/credentials:** Error on bad file name if explicitly set ([#10018](https://github.com/googleapis/google-cloud-go/issues/10018)) ([55beaa9](https://github.com/googleapis/google-cloud-go/commit/55beaa993aaf052d8be39766afc6777c3c2a0bdd)), refs [#9809](https://github.com/googleapis/google-cloud-go/issues/9809) - -## [0.2.2](https://github.com/googleapis/google-cloud-go/compare/auth/v0.2.1...auth/v0.2.2) (2024-04-19) - - -### Bug Fixes - -* **auth:** Add internal opt to skip validation on transports ([#9999](https://github.com/googleapis/google-cloud-go/issues/9999)) ([9e20ef8](https://github.com/googleapis/google-cloud-go/commit/9e20ef89f6287d6bd03b8697d5898dc43b4a77cf)), refs [#9823](https://github.com/googleapis/google-cloud-go/issues/9823) -* **auth:** Set secure flag for gRPC conn pools ([#10002](https://github.com/googleapis/google-cloud-go/issues/10002)) ([14e3956](https://github.com/googleapis/google-cloud-go/commit/14e3956dfd736399731b5ee8d9b178ae085cf7ba)), refs [#9833](https://github.com/googleapis/google-cloud-go/issues/9833) - -## [0.2.1](https://github.com/googleapis/google-cloud-go/compare/auth/v0.2.0...auth/v0.2.1) (2024-04-18) - - -### Bug Fixes - -* **auth:** Default gRPC token type to Bearer if not set ([#9800](https://github.com/googleapis/google-cloud-go/issues/9800)) ([5284066](https://github.com/googleapis/google-cloud-go/commit/5284066670b6fe65d79089cfe0199c9660f87fc7)) - -## [0.2.0](https://github.com/googleapis/google-cloud-go/compare/auth/v0.1.1...auth/v0.2.0) (2024-04-15) - -### Breaking Changes - -In the below mentioned commits there were a few large breaking changes since the -last release of the module. - -1. The `Credentials` type has been moved to the root of the module as it is - becoming the core abstraction for the whole module. -2. Because of the above mentioned change many functions that previously - returned a `TokenProvider` now return `Credentials`. Similarly, these - functions have been renamed to be more specific. -3. Most places that used to take an optional `TokenProvider` now accept - `Credentials`. You can make a `Credentials` from a `TokenProvider` using the - constructor found in the `auth` package. -4. The `detect` package has been renamed to `credentials`. With this change some - function signatures were also updated for better readability. -5. Derivative auth flows like `impersonate` and `downscope` have been moved to - be under the new `credentials` package. - -Although these changes are disruptive we think that they are for the best of the -long-term health of the module. We do not expect any more large breaking changes -like these in future revisions, even before 1.0.0. This version will be the -first version of the auth library that our client libraries start to use and -depend on. - -### Features - -* **auth/credentials/externalaccount:** Add default TokenURL ([#9700](https://github.com/googleapis/google-cloud-go/issues/9700)) ([81830e6](https://github.com/googleapis/google-cloud-go/commit/81830e6848ceefd055aa4d08f933d1154455a0f6)) -* **auth:** Add downscope.Options.UniverseDomain ([#9634](https://github.com/googleapis/google-cloud-go/issues/9634)) ([52cf7d7](https://github.com/googleapis/google-cloud-go/commit/52cf7d780853594291c4e34302d618299d1f5a1d)) -* **auth:** Add universe domain to grpctransport and httptransport ([#9663](https://github.com/googleapis/google-cloud-go/issues/9663)) ([67d353b](https://github.com/googleapis/google-cloud-go/commit/67d353beefe3b607c08c891876fbd95ab89e5fe3)), refs [#9670](https://github.com/googleapis/google-cloud-go/issues/9670) -* **auth:** Add UniverseDomain to DetectOptions ([#9536](https://github.com/googleapis/google-cloud-go/issues/9536)) ([3618d3f](https://github.com/googleapis/google-cloud-go/commit/3618d3f7061615c0e189f376c75abc201203b501)) -* **auth:** Make package externalaccount public ([#9633](https://github.com/googleapis/google-cloud-go/issues/9633)) ([a0978d8](https://github.com/googleapis/google-cloud-go/commit/a0978d8e96968399940ebd7d092539772bf9caac)) -* **auth:** Move credentials to base auth package ([#9590](https://github.com/googleapis/google-cloud-go/issues/9590)) ([1a04baf](https://github.com/googleapis/google-cloud-go/commit/1a04bafa83c27342b9308d785645e1e5423ea10d)) -* **auth:** Refactor public sigs to use Credentials ([#9603](https://github.com/googleapis/google-cloud-go/issues/9603)) ([69cb240](https://github.com/googleapis/google-cloud-go/commit/69cb240c530b1f7173a9af2555c19e9a1beb56c5)) - - -### Bug Fixes - -* **auth/oauth2adapt:** Update protobuf dep to v1.33.0 ([30b038d](https://github.com/googleapis/google-cloud-go/commit/30b038d8cac0b8cd5dd4761c87f3f298760dd33a)) -* **auth:** Fix uint32 conversion ([9221c7f](https://github.com/googleapis/google-cloud-go/commit/9221c7fa12cef9d5fb7ddc92f41f1d6204971c7b)) -* **auth:** Port sts expires fix ([#9618](https://github.com/googleapis/google-cloud-go/issues/9618)) ([7bec97b](https://github.com/googleapis/google-cloud-go/commit/7bec97b2f51ed3ac4f9b88bf100d301da3f5d1bd)) -* **auth:** Read universe_domain from all credentials files ([#9632](https://github.com/googleapis/google-cloud-go/issues/9632)) ([16efbb5](https://github.com/googleapis/google-cloud-go/commit/16efbb52e39ea4a319e5ee1e95c0e0305b6d9824)) -* **auth:** Remove content-type header from idms get requests ([#9508](https://github.com/googleapis/google-cloud-go/issues/9508)) ([8589f41](https://github.com/googleapis/google-cloud-go/commit/8589f41599d265d7c3d46a3d86c9fab2329cbdd9)) -* **auth:** Update protobuf dep to v1.33.0 ([30b038d](https://github.com/googleapis/google-cloud-go/commit/30b038d8cac0b8cd5dd4761c87f3f298760dd33a)) - -## [0.1.1](https://github.com/googleapis/google-cloud-go/compare/auth/v0.1.0...auth/v0.1.1) (2024-03-10) - - -### Bug Fixes - -* **auth/impersonate:** Properly send default detect params ([#9529](https://github.com/googleapis/google-cloud-go/issues/9529)) ([5b6b8be](https://github.com/googleapis/google-cloud-go/commit/5b6b8bef577f82707e51f5cc5d258d5bdf90218f)), refs [#9136](https://github.com/googleapis/google-cloud-go/issues/9136) -* **auth:** Update grpc-go to v1.56.3 ([343cea8](https://github.com/googleapis/google-cloud-go/commit/343cea8c43b1e31ae21ad50ad31d3b0b60143f8c)) -* **auth:** Update grpc-go to v1.59.0 ([81a97b0](https://github.com/googleapis/google-cloud-go/commit/81a97b06cb28b25432e4ece595c55a9857e960b7)) - -## 0.1.0 (2023-10-18) - - -### Features - -* **auth:** Add base auth package ([#8465](https://github.com/googleapis/google-cloud-go/issues/8465)) ([6a45f26](https://github.com/googleapis/google-cloud-go/commit/6a45f26b809b64edae21f312c18d4205f96b180e)) -* **auth:** Add cert support to httptransport ([#8569](https://github.com/googleapis/google-cloud-go/issues/8569)) ([37e3435](https://github.com/googleapis/google-cloud-go/commit/37e3435f8e98595eafab481bdfcb31a4c56fa993)) -* **auth:** Add Credentials.UniverseDomain() ([#8654](https://github.com/googleapis/google-cloud-go/issues/8654)) ([af0aa1e](https://github.com/googleapis/google-cloud-go/commit/af0aa1ed8015bc8fe0dd87a7549ae029107cbdb8)) -* **auth:** Add detect package ([#8491](https://github.com/googleapis/google-cloud-go/issues/8491)) ([d977419](https://github.com/googleapis/google-cloud-go/commit/d977419a3269f6acc193df77a2136a6eb4b4add7)) -* **auth:** Add downscope package ([#8532](https://github.com/googleapis/google-cloud-go/issues/8532)) ([dda9bff](https://github.com/googleapis/google-cloud-go/commit/dda9bff8ec70e6d104901b4105d13dcaa4e2404c)) -* **auth:** Add grpctransport package ([#8625](https://github.com/googleapis/google-cloud-go/issues/8625)) ([69a8347](https://github.com/googleapis/google-cloud-go/commit/69a83470bdcc7ed10c6c36d1abc3b7cfdb8a0ee5)) -* **auth:** Add httptransport package ([#8567](https://github.com/googleapis/google-cloud-go/issues/8567)) ([6898597](https://github.com/googleapis/google-cloud-go/commit/6898597d2ea95d630fcd00fd15c58c75ea843bff)) -* **auth:** Add idtoken package ([#8580](https://github.com/googleapis/google-cloud-go/issues/8580)) ([a79e693](https://github.com/googleapis/google-cloud-go/commit/a79e693e97e4e3e1c6742099af3dbc58866d88fe)) -* **auth:** Add impersonate package ([#8578](https://github.com/googleapis/google-cloud-go/issues/8578)) ([e29ba0c](https://github.com/googleapis/google-cloud-go/commit/e29ba0cb7bd3888ab9e808087027dc5a32474c04)) -* **auth:** Add support for external accounts in detect ([#8508](https://github.com/googleapis/google-cloud-go/issues/8508)) ([62210d5](https://github.com/googleapis/google-cloud-go/commit/62210d5d3e56e8e9f35db8e6ac0defec19582507)) -* **auth:** Port external account changes ([#8697](https://github.com/googleapis/google-cloud-go/issues/8697)) ([5823db5](https://github.com/googleapis/google-cloud-go/commit/5823db5d633069999b58b9131a7f9cd77e82c899)) - - -### Bug Fixes - -* **auth/oauth2adapt:** Update golang.org/x/net to v0.17.0 ([174da47](https://github.com/googleapis/google-cloud-go/commit/174da47254fefb12921bbfc65b7829a453af6f5d)) -* **auth:** Update golang.org/x/net to v0.17.0 ([174da47](https://github.com/googleapis/google-cloud-go/commit/174da47254fefb12921bbfc65b7829a453af6f5d)) diff --git a/vendor/cloud.google.com/go/auth/LICENSE b/vendor/cloud.google.com/go/auth/LICENSE deleted file mode 100644 index d6456956..00000000 --- a/vendor/cloud.google.com/go/auth/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/cloud.google.com/go/auth/README.md b/vendor/cloud.google.com/go/auth/README.md deleted file mode 100644 index 6fe4f076..00000000 --- a/vendor/cloud.google.com/go/auth/README.md +++ /dev/null @@ -1,40 +0,0 @@ -# Google Auth Library for Go - -[![Go Reference](https://pkg.go.dev/badge/cloud.google.com/go/auth.svg)](https://pkg.go.dev/cloud.google.com/go/auth) - -## Install - -``` bash -go get cloud.google.com/go/auth@latest -``` - -## Usage - -The most common way this library is used is transitively, by default, from any -of our Go client libraries. - -### Notable use-cases - -- To create a credential directly please see examples in the - [credentials](https://pkg.go.dev/cloud.google.com/go/auth/credentials) - package. -- To create a authenticated HTTP client please see examples in the - [httptransport](https://pkg.go.dev/cloud.google.com/go/auth/httptransport) - package. -- To create a authenticated gRPC connection please see examples in the - [grpctransport](https://pkg.go.dev/cloud.google.com/go/auth/grpctransport) - package. -- To create an ID token please see examples in the - [idtoken](https://pkg.go.dev/cloud.google.com/go/auth/credentials/idtoken) - package. - -## Contributing - -Contributions are welcome. Please, see the -[CONTRIBUTING](https://github.com/GoogleCloudPlatform/google-cloud-go/blob/main/CONTRIBUTING.md) -document for details. - -Please note that this project is released with a Contributor Code of Conduct. -By participating in this project you agree to abide by its terms. -See [Contributor Code of Conduct](https://github.com/GoogleCloudPlatform/google-cloud-go/blob/main/CONTRIBUTING.md#contributor-code-of-conduct) -for more information. diff --git a/vendor/cloud.google.com/go/auth/auth.go b/vendor/cloud.google.com/go/auth/auth.go deleted file mode 100644 index cd5e9886..00000000 --- a/vendor/cloud.google.com/go/auth/auth.go +++ /dev/null @@ -1,618 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package auth provides utilities for managing Google Cloud credentials, -// including functionality for creating, caching, and refreshing OAuth2 tokens. -// It offers customizable options for different OAuth2 flows, such as 2-legged -// (2LO) and 3-legged (3LO) OAuth, along with support for PKCE and automatic -// token management. -package auth - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "log/slog" - "net/http" - "net/url" - "strings" - "sync" - "time" - - "cloud.google.com/go/auth/internal" - "cloud.google.com/go/auth/internal/jwt" - "github.com/googleapis/gax-go/v2/internallog" -) - -const ( - // Parameter keys for AuthCodeURL method to support PKCE. - codeChallengeKey = "code_challenge" - codeChallengeMethodKey = "code_challenge_method" - - // Parameter key for Exchange method to support PKCE. - codeVerifierKey = "code_verifier" - - // 3 minutes and 45 seconds before expiration. The shortest MDS cache is 4 minutes, - // so we give it 15 seconds to refresh it's cache before attempting to refresh a token. - defaultExpiryDelta = 225 * time.Second - - universeDomainDefault = "googleapis.com" -) - -// tokenState represents different states for a [Token]. -type tokenState int - -const ( - // fresh indicates that the [Token] is valid. It is not expired or close to - // expired, or the token has no expiry. - fresh tokenState = iota - // stale indicates that the [Token] is close to expired, and should be - // refreshed. The token can be used normally. - stale - // invalid indicates that the [Token] is expired or invalid. The token - // cannot be used for a normal operation. - invalid -) - -var ( - defaultGrantType = "urn:ietf:params:oauth:grant-type:jwt-bearer" - defaultHeader = &jwt.Header{Algorithm: jwt.HeaderAlgRSA256, Type: jwt.HeaderType} - - // for testing - timeNow = time.Now -) - -// TokenProvider specifies an interface for anything that can return a token. -type TokenProvider interface { - // Token returns a Token or an error. - // The Token returned must be safe to use - // concurrently. - // The returned Token must not be modified. - // The context provided must be sent along to any requests that are made in - // the implementing code. - Token(context.Context) (*Token, error) -} - -// Token holds the credential token used to authorized requests. All fields are -// considered read-only. -type Token struct { - // Value is the token used to authorize requests. It is usually an access - // token but may be other types of tokens such as ID tokens in some flows. - Value string - // Type is the type of token Value is. If uninitialized, it should be - // assumed to be a "Bearer" token. - Type string - // Expiry is the time the token is set to expire. - Expiry time.Time - // Metadata may include, but is not limited to, the body of the token - // response returned by the server. - Metadata map[string]interface{} // TODO(codyoss): maybe make a method to flatten metadata to avoid []string for url.Values -} - -// IsValid reports that a [Token] is non-nil, has a [Token.Value], and has not -// expired. A token is considered expired if [Token.Expiry] has passed or will -// pass in the next 225 seconds. -func (t *Token) IsValid() bool { - return t.isValidWithEarlyExpiry(defaultExpiryDelta) -} - -// MetadataString is a convenience method for accessing string values in the -// token's metadata. Returns an empty string if the metadata is nil or the value -// for the given key cannot be cast to a string. -func (t *Token) MetadataString(k string) string { - if t.Metadata == nil { - return "" - } - s, ok := t.Metadata[k].(string) - if !ok { - return "" - } - return s -} - -func (t *Token) isValidWithEarlyExpiry(earlyExpiry time.Duration) bool { - if t.isEmpty() { - return false - } - if t.Expiry.IsZero() { - return true - } - return !t.Expiry.Round(0).Add(-earlyExpiry).Before(timeNow()) -} - -func (t *Token) isEmpty() bool { - return t == nil || t.Value == "" -} - -// Credentials holds Google credentials, including -// [Application Default Credentials]. -// -// [Application Default Credentials]: https://developers.google.com/accounts/docs/application-default-credentials -type Credentials struct { - json []byte - projectID CredentialsPropertyProvider - quotaProjectID CredentialsPropertyProvider - // universeDomain is the default service domain for a given Cloud universe. - universeDomain CredentialsPropertyProvider - - TokenProvider -} - -// JSON returns the bytes associated with the the file used to source -// credentials if one was used. -func (c *Credentials) JSON() []byte { - return c.json -} - -// ProjectID returns the associated project ID from the underlying file or -// environment. -func (c *Credentials) ProjectID(ctx context.Context) (string, error) { - if c.projectID == nil { - return internal.GetProjectID(c.json, ""), nil - } - v, err := c.projectID.GetProperty(ctx) - if err != nil { - return "", err - } - return internal.GetProjectID(c.json, v), nil -} - -// QuotaProjectID returns the associated quota project ID from the underlying -// file or environment. -func (c *Credentials) QuotaProjectID(ctx context.Context) (string, error) { - if c.quotaProjectID == nil { - return internal.GetQuotaProject(c.json, ""), nil - } - v, err := c.quotaProjectID.GetProperty(ctx) - if err != nil { - return "", err - } - return internal.GetQuotaProject(c.json, v), nil -} - -// UniverseDomain returns the default service domain for a given Cloud universe. -// The default value is "googleapis.com". -func (c *Credentials) UniverseDomain(ctx context.Context) (string, error) { - if c.universeDomain == nil { - return universeDomainDefault, nil - } - v, err := c.universeDomain.GetProperty(ctx) - if err != nil { - return "", err - } - if v == "" { - return universeDomainDefault, nil - } - return v, err -} - -// CredentialsPropertyProvider provides an implementation to fetch a property -// value for [Credentials]. -type CredentialsPropertyProvider interface { - GetProperty(context.Context) (string, error) -} - -// CredentialsPropertyFunc is a type adapter to allow the use of ordinary -// functions as a [CredentialsPropertyProvider]. -type CredentialsPropertyFunc func(context.Context) (string, error) - -// GetProperty loads the properly value provided the given context. -func (p CredentialsPropertyFunc) GetProperty(ctx context.Context) (string, error) { - return p(ctx) -} - -// CredentialsOptions are used to configure [Credentials]. -type CredentialsOptions struct { - // TokenProvider is a means of sourcing a token for the credentials. Required. - TokenProvider TokenProvider - // JSON is the raw contents of the credentials file if sourced from a file. - JSON []byte - // ProjectIDProvider resolves the project ID associated with the - // credentials. - ProjectIDProvider CredentialsPropertyProvider - // QuotaProjectIDProvider resolves the quota project ID associated with the - // credentials. - QuotaProjectIDProvider CredentialsPropertyProvider - // UniverseDomainProvider resolves the universe domain with the credentials. - UniverseDomainProvider CredentialsPropertyProvider -} - -// NewCredentials returns new [Credentials] from the provided options. -func NewCredentials(opts *CredentialsOptions) *Credentials { - creds := &Credentials{ - TokenProvider: opts.TokenProvider, - json: opts.JSON, - projectID: opts.ProjectIDProvider, - quotaProjectID: opts.QuotaProjectIDProvider, - universeDomain: opts.UniverseDomainProvider, - } - - return creds -} - -// CachedTokenProviderOptions provides options for configuring a cached -// [TokenProvider]. -type CachedTokenProviderOptions struct { - // DisableAutoRefresh makes the TokenProvider always return the same token, - // even if it is expired. The default is false. Optional. - DisableAutoRefresh bool - // ExpireEarly configures the amount of time before a token expires, that it - // should be refreshed. If unset, the default value is 3 minutes and 45 - // seconds. Optional. - ExpireEarly time.Duration - // DisableAsyncRefresh configures a synchronous workflow that refreshes - // tokens in a blocking manner. The default is false. Optional. - DisableAsyncRefresh bool -} - -func (ctpo *CachedTokenProviderOptions) autoRefresh() bool { - if ctpo == nil { - return true - } - return !ctpo.DisableAutoRefresh -} - -func (ctpo *CachedTokenProviderOptions) expireEarly() time.Duration { - if ctpo == nil || ctpo.ExpireEarly == 0 { - return defaultExpiryDelta - } - return ctpo.ExpireEarly -} - -func (ctpo *CachedTokenProviderOptions) blockingRefresh() bool { - if ctpo == nil { - return false - } - return ctpo.DisableAsyncRefresh -} - -// NewCachedTokenProvider wraps a [TokenProvider] to cache the tokens returned -// by the underlying provider. By default it will refresh tokens asynchronously -// a few minutes before they expire. -func NewCachedTokenProvider(tp TokenProvider, opts *CachedTokenProviderOptions) TokenProvider { - if ctp, ok := tp.(*cachedTokenProvider); ok { - return ctp - } - return &cachedTokenProvider{ - tp: tp, - autoRefresh: opts.autoRefresh(), - expireEarly: opts.expireEarly(), - blockingRefresh: opts.blockingRefresh(), - } -} - -type cachedTokenProvider struct { - tp TokenProvider - autoRefresh bool - expireEarly time.Duration - blockingRefresh bool - - mu sync.Mutex - cachedToken *Token - // isRefreshRunning ensures that the non-blocking refresh will only be - // attempted once, even if multiple callers enter the Token method. - isRefreshRunning bool - // isRefreshErr ensures that the non-blocking refresh will only be attempted - // once per refresh window if an error is encountered. - isRefreshErr bool -} - -func (c *cachedTokenProvider) Token(ctx context.Context) (*Token, error) { - if c.blockingRefresh { - return c.tokenBlocking(ctx) - } - return c.tokenNonBlocking(ctx) -} - -func (c *cachedTokenProvider) tokenNonBlocking(ctx context.Context) (*Token, error) { - switch c.tokenState() { - case fresh: - c.mu.Lock() - defer c.mu.Unlock() - return c.cachedToken, nil - case stale: - // Call tokenAsync with a new Context because the user-provided context - // may have a short timeout incompatible with async token refresh. - c.tokenAsync(context.Background()) - // Return the stale token immediately to not block customer requests to Cloud services. - c.mu.Lock() - defer c.mu.Unlock() - return c.cachedToken, nil - default: // invalid - return c.tokenBlocking(ctx) - } -} - -// tokenState reports the token's validity. -func (c *cachedTokenProvider) tokenState() tokenState { - c.mu.Lock() - defer c.mu.Unlock() - t := c.cachedToken - now := timeNow() - if t == nil || t.Value == "" { - return invalid - } else if t.Expiry.IsZero() { - return fresh - } else if now.After(t.Expiry.Round(0)) { - return invalid - } else if now.After(t.Expiry.Round(0).Add(-c.expireEarly)) { - return stale - } - return fresh -} - -// tokenAsync uses a bool to ensure that only one non-blocking token refresh -// happens at a time, even if multiple callers have entered this function -// concurrently. This avoids creating an arbitrary number of concurrent -// goroutines. Retries should be attempted and managed within the Token method. -// If the refresh attempt fails, no further attempts are made until the refresh -// window expires and the token enters the invalid state, at which point the -// blocking call to Token should likely return the same error on the main goroutine. -func (c *cachedTokenProvider) tokenAsync(ctx context.Context) { - fn := func() { - c.mu.Lock() - c.isRefreshRunning = true - c.mu.Unlock() - t, err := c.tp.Token(ctx) - c.mu.Lock() - defer c.mu.Unlock() - c.isRefreshRunning = false - if err != nil { - // Discard errors from the non-blocking refresh, but prevent further - // attempts. - c.isRefreshErr = true - return - } - c.cachedToken = t - } - c.mu.Lock() - defer c.mu.Unlock() - if !c.isRefreshRunning && !c.isRefreshErr { - go fn() - } -} - -func (c *cachedTokenProvider) tokenBlocking(ctx context.Context) (*Token, error) { - c.mu.Lock() - defer c.mu.Unlock() - c.isRefreshErr = false - if c.cachedToken.IsValid() || (!c.autoRefresh && !c.cachedToken.isEmpty()) { - return c.cachedToken, nil - } - t, err := c.tp.Token(ctx) - if err != nil { - return nil, err - } - c.cachedToken = t - return t, nil -} - -// Error is a error associated with retrieving a [Token]. It can hold useful -// additional details for debugging. -type Error struct { - // Response is the HTTP response associated with error. The body will always - // be already closed and consumed. - Response *http.Response - // Body is the HTTP response body. - Body []byte - // Err is the underlying wrapped error. - Err error - - // code returned in the token response - code string - // description returned in the token response - description string - // uri returned in the token response - uri string -} - -func (e *Error) Error() string { - if e.code != "" { - s := fmt.Sprintf("auth: %q", e.code) - if e.description != "" { - s += fmt.Sprintf(" %q", e.description) - } - if e.uri != "" { - s += fmt.Sprintf(" %q", e.uri) - } - return s - } - return fmt.Sprintf("auth: cannot fetch token: %v\nResponse: %s", e.Response.StatusCode, e.Body) -} - -// Temporary returns true if the error is considered temporary and may be able -// to be retried. -func (e *Error) Temporary() bool { - if e.Response == nil { - return false - } - sc := e.Response.StatusCode - return sc == http.StatusInternalServerError || sc == http.StatusServiceUnavailable || sc == http.StatusRequestTimeout || sc == http.StatusTooManyRequests -} - -func (e *Error) Unwrap() error { - return e.Err -} - -// Style describes how the token endpoint wants to receive the ClientID and -// ClientSecret. -type Style int - -const ( - // StyleUnknown means the value has not been initiated. Sending this in - // a request will cause the token exchange to fail. - StyleUnknown Style = iota - // StyleInParams sends client info in the body of a POST request. - StyleInParams - // StyleInHeader sends client info using Basic Authorization header. - StyleInHeader -) - -// Options2LO is the configuration settings for doing a 2-legged JWT OAuth2 flow. -type Options2LO struct { - // Email is the OAuth2 client ID. This value is set as the "iss" in the - // JWT. - Email string - // PrivateKey contains the contents of an RSA private key or the - // contents of a PEM file that contains a private key. It is used to sign - // the JWT created. - PrivateKey []byte - // TokenURL is th URL the JWT is sent to. Required. - TokenURL string - // PrivateKeyID is the ID of the key used to sign the JWT. It is used as the - // "kid" in the JWT header. Optional. - PrivateKeyID string - // Subject is the used for to impersonate a user. It is used as the "sub" in - // the JWT.m Optional. - Subject string - // Scopes specifies requested permissions for the token. Optional. - Scopes []string - // Expires specifies the lifetime of the token. Optional. - Expires time.Duration - // Audience specifies the "aud" in the JWT. Optional. - Audience string - // PrivateClaims allows specifying any custom claims for the JWT. Optional. - PrivateClaims map[string]interface{} - - // Client is the client to be used to make the underlying token requests. - // Optional. - Client *http.Client - // UseIDToken requests that the token returned be an ID token if one is - // returned from the server. Optional. - UseIDToken bool - // Logger is used for debug logging. If provided, logging will be enabled - // at the loggers configured level. By default logging is disabled unless - // enabled by setting GOOGLE_SDK_GO_LOGGING_LEVEL in which case a default - // logger will be used. Optional. - Logger *slog.Logger -} - -func (o *Options2LO) client() *http.Client { - if o.Client != nil { - return o.Client - } - return internal.DefaultClient() -} - -func (o *Options2LO) validate() error { - if o == nil { - return errors.New("auth: options must be provided") - } - if o.Email == "" { - return errors.New("auth: email must be provided") - } - if len(o.PrivateKey) == 0 { - return errors.New("auth: private key must be provided") - } - if o.TokenURL == "" { - return errors.New("auth: token URL must be provided") - } - return nil -} - -// New2LOTokenProvider returns a [TokenProvider] from the provided options. -func New2LOTokenProvider(opts *Options2LO) (TokenProvider, error) { - if err := opts.validate(); err != nil { - return nil, err - } - return tokenProvider2LO{opts: opts, Client: opts.client(), logger: internallog.New(opts.Logger)}, nil -} - -type tokenProvider2LO struct { - opts *Options2LO - Client *http.Client - logger *slog.Logger -} - -func (tp tokenProvider2LO) Token(ctx context.Context) (*Token, error) { - pk, err := internal.ParseKey(tp.opts.PrivateKey) - if err != nil { - return nil, err - } - claimSet := &jwt.Claims{ - Iss: tp.opts.Email, - Scope: strings.Join(tp.opts.Scopes, " "), - Aud: tp.opts.TokenURL, - AdditionalClaims: tp.opts.PrivateClaims, - Sub: tp.opts.Subject, - } - if t := tp.opts.Expires; t > 0 { - claimSet.Exp = time.Now().Add(t).Unix() - } - if aud := tp.opts.Audience; aud != "" { - claimSet.Aud = aud - } - h := *defaultHeader - h.KeyID = tp.opts.PrivateKeyID - payload, err := jwt.EncodeJWS(&h, claimSet, pk) - if err != nil { - return nil, err - } - v := url.Values{} - v.Set("grant_type", defaultGrantType) - v.Set("assertion", payload) - req, err := http.NewRequestWithContext(ctx, "POST", tp.opts.TokenURL, strings.NewReader(v.Encode())) - if err != nil { - return nil, err - } - req.Header.Set("Content-Type", "application/x-www-form-urlencoded") - tp.logger.DebugContext(ctx, "2LO token request", "request", internallog.HTTPRequest(req, []byte(v.Encode()))) - resp, body, err := internal.DoRequest(tp.Client, req) - if err != nil { - return nil, fmt.Errorf("auth: cannot fetch token: %w", err) - } - tp.logger.DebugContext(ctx, "2LO token response", "response", internallog.HTTPResponse(resp, body)) - if c := resp.StatusCode; c < http.StatusOK || c >= http.StatusMultipleChoices { - return nil, &Error{ - Response: resp, - Body: body, - } - } - // tokenRes is the JSON response body. - var tokenRes struct { - AccessToken string `json:"access_token"` - TokenType string `json:"token_type"` - IDToken string `json:"id_token"` - ExpiresIn int64 `json:"expires_in"` - } - if err := json.Unmarshal(body, &tokenRes); err != nil { - return nil, fmt.Errorf("auth: cannot fetch token: %w", err) - } - token := &Token{ - Value: tokenRes.AccessToken, - Type: tokenRes.TokenType, - } - token.Metadata = make(map[string]interface{}) - json.Unmarshal(body, &token.Metadata) // no error checks for optional fields - - if secs := tokenRes.ExpiresIn; secs > 0 { - token.Expiry = time.Now().Add(time.Duration(secs) * time.Second) - } - if v := tokenRes.IDToken; v != "" { - // decode returned id token to get expiry - claimSet, err := jwt.DecodeJWS(v) - if err != nil { - return nil, fmt.Errorf("auth: error decoding JWT token: %w", err) - } - token.Expiry = time.Unix(claimSet.Exp, 0) - } - if tp.opts.UseIDToken { - if tokenRes.IDToken == "" { - return nil, fmt.Errorf("auth: response doesn't have JWT token") - } - token.Value = tokenRes.IDToken - } - return token, nil -} diff --git a/vendor/cloud.google.com/go/auth/credentials/compute.go b/vendor/cloud.google.com/go/auth/credentials/compute.go deleted file mode 100644 index e4a8078f..00000000 --- a/vendor/cloud.google.com/go/auth/credentials/compute.go +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package credentials - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "net/url" - "strings" - "time" - - "cloud.google.com/go/auth" - "cloud.google.com/go/compute/metadata" -) - -var ( - computeTokenMetadata = map[string]interface{}{ - "auth.google.tokenSource": "compute-metadata", - "auth.google.serviceAccount": "default", - } - computeTokenURI = "instance/service-accounts/default/token" -) - -// computeTokenProvider creates a [cloud.google.com/go/auth.TokenProvider] that -// uses the metadata service to retrieve tokens. -func computeTokenProvider(opts *DetectOptions, client *metadata.Client) auth.TokenProvider { - return auth.NewCachedTokenProvider(&computeProvider{ - scopes: opts.Scopes, - client: client, - tokenBindingType: opts.TokenBindingType, - }, &auth.CachedTokenProviderOptions{ - ExpireEarly: opts.EarlyTokenRefresh, - DisableAsyncRefresh: opts.DisableAsyncRefresh, - }) -} - -// computeProvider fetches tokens from the google cloud metadata service. -type computeProvider struct { - scopes []string - client *metadata.Client - tokenBindingType TokenBindingType -} - -type metadataTokenResp struct { - AccessToken string `json:"access_token"` - ExpiresInSec int `json:"expires_in"` - TokenType string `json:"token_type"` -} - -func (cs *computeProvider) Token(ctx context.Context) (*auth.Token, error) { - tokenURI, err := url.Parse(computeTokenURI) - if err != nil { - return nil, err - } - hasScopes := len(cs.scopes) > 0 - if hasScopes || cs.tokenBindingType != NoBinding { - v := url.Values{} - if hasScopes { - v.Set("scopes", strings.Join(cs.scopes, ",")) - } - switch cs.tokenBindingType { - case MTLSHardBinding: - v.Set("transport", "mtls") - v.Set("binding-enforcement", "on") - case ALTSHardBinding: - v.Set("transport", "alts") - } - tokenURI.RawQuery = v.Encode() - } - tokenJSON, err := cs.client.GetWithContext(ctx, tokenURI.String()) - if err != nil { - return nil, fmt.Errorf("credentials: cannot fetch token: %w", err) - } - var res metadataTokenResp - if err := json.NewDecoder(strings.NewReader(tokenJSON)).Decode(&res); err != nil { - return nil, fmt.Errorf("credentials: invalid token JSON from metadata: %w", err) - } - if res.ExpiresInSec == 0 || res.AccessToken == "" { - return nil, errors.New("credentials: incomplete token received from metadata") - } - return &auth.Token{ - Value: res.AccessToken, - Type: res.TokenType, - Expiry: time.Now().Add(time.Duration(res.ExpiresInSec) * time.Second), - Metadata: computeTokenMetadata, - }, nil - -} diff --git a/vendor/cloud.google.com/go/auth/credentials/detect.go b/vendor/cloud.google.com/go/auth/credentials/detect.go deleted file mode 100644 index d8f7d961..00000000 --- a/vendor/cloud.google.com/go/auth/credentials/detect.go +++ /dev/null @@ -1,316 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package credentials - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "log/slog" - "net/http" - "os" - "time" - - "cloud.google.com/go/auth" - "cloud.google.com/go/auth/internal" - "cloud.google.com/go/auth/internal/credsfile" - "cloud.google.com/go/compute/metadata" - "github.com/googleapis/gax-go/v2/internallog" -) - -const ( - // jwtTokenURL is Google's OAuth 2.0 token URL to use with the JWT(2LO) flow. - jwtTokenURL = "https://oauth2.googleapis.com/token" - - // Google's OAuth 2.0 default endpoints. - googleAuthURL = "https://accounts.google.com/o/oauth2/auth" - googleTokenURL = "https://oauth2.googleapis.com/token" - - // GoogleMTLSTokenURL is Google's default OAuth2.0 mTLS endpoint. - GoogleMTLSTokenURL = "https://oauth2.mtls.googleapis.com/token" - - // Help on default credentials - adcSetupURL = "https://cloud.google.com/docs/authentication/external/set-up-adc" -) - -var ( - // for testing - allowOnGCECheck = true -) - -// TokenBindingType specifies the type of binding used when requesting a token -// whether to request a hard-bound token using mTLS or an instance identity -// bound token using ALTS. -type TokenBindingType int - -const ( - // NoBinding specifies that requested tokens are not required to have a - // binding. This is the default option. - NoBinding TokenBindingType = iota - // MTLSHardBinding specifies that a hard-bound token should be requested - // using an mTLS with S2A channel. - MTLSHardBinding - // ALTSHardBinding specifies that an instance identity bound token should - // be requested using an ALTS channel. - ALTSHardBinding -) - -// OnGCE reports whether this process is running in Google Cloud. -func OnGCE() bool { - // TODO(codyoss): once all libs use this auth lib move metadata check here - return allowOnGCECheck && metadata.OnGCE() -} - -// DetectDefault searches for "Application Default Credentials" and returns -// a credential based on the [DetectOptions] provided. -// -// It looks for credentials in the following places, preferring the first -// location found: -// -// - A JSON file whose path is specified by the GOOGLE_APPLICATION_CREDENTIALS -// environment variable. For workload identity federation, refer to -// https://cloud.google.com/iam/docs/how-to#using-workload-identity-federation -// on how to generate the JSON configuration file for on-prem/non-Google -// cloud platforms. -// - A JSON file in a location known to the gcloud command-line tool. On -// Windows, this is %APPDATA%/gcloud/application_default_credentials.json. On -// other systems, $HOME/.config/gcloud/application_default_credentials.json. -// - On Google Compute Engine, Google App Engine standard second generation -// runtimes, and Google App Engine flexible environment, it fetches -// credentials from the metadata server. -func DetectDefault(opts *DetectOptions) (*auth.Credentials, error) { - if err := opts.validate(); err != nil { - return nil, err - } - if len(opts.CredentialsJSON) > 0 { - return readCredentialsFileJSON(opts.CredentialsJSON, opts) - } - if opts.CredentialsFile != "" { - return readCredentialsFile(opts.CredentialsFile, opts) - } - if filename := os.Getenv(credsfile.GoogleAppCredsEnvVar); filename != "" { - creds, err := readCredentialsFile(filename, opts) - if err != nil { - return nil, err - } - return creds, nil - } - - fileName := credsfile.GetWellKnownFileName() - if b, err := os.ReadFile(fileName); err == nil { - return readCredentialsFileJSON(b, opts) - } - - if OnGCE() { - metadataClient := metadata.NewWithOptions(&metadata.Options{ - Logger: opts.logger(), - }) - return auth.NewCredentials(&auth.CredentialsOptions{ - TokenProvider: computeTokenProvider(opts, metadataClient), - ProjectIDProvider: auth.CredentialsPropertyFunc(func(ctx context.Context) (string, error) { - return metadataClient.ProjectIDWithContext(ctx) - }), - UniverseDomainProvider: &internal.ComputeUniverseDomainProvider{ - MetadataClient: metadataClient, - }, - }), nil - } - - return nil, fmt.Errorf("credentials: could not find default credentials. See %v for more information", adcSetupURL) -} - -// DetectOptions provides configuration for [DetectDefault]. -type DetectOptions struct { - // Scopes that credentials tokens should have. Example: - // https://www.googleapis.com/auth/cloud-platform. Required if Audience is - // not provided. - Scopes []string - // TokenBindingType specifies the type of binding used when requesting a - // token whether to request a hard-bound token using mTLS or an instance - // identity bound token using ALTS. Optional. - TokenBindingType TokenBindingType - // Audience that credentials tokens should have. Only applicable for 2LO - // flows with service accounts. If specified, scopes should not be provided. - Audience string - // Subject is the user email used for [domain wide delegation](https://developers.google.com/identity/protocols/oauth2/service-account#delegatingauthority). - // Optional. - Subject string - // EarlyTokenRefresh configures how early before a token expires that it - // should be refreshed. Once the token’s time until expiration has entered - // this refresh window the token is considered valid but stale. If unset, - // the default value is 3 minutes and 45 seconds. Optional. - EarlyTokenRefresh time.Duration - // DisableAsyncRefresh configures a synchronous workflow that refreshes - // stale tokens while blocking. The default is false. Optional. - DisableAsyncRefresh bool - // AuthHandlerOptions configures an authorization handler and other options - // for 3LO flows. It is required, and only used, for client credential - // flows. - AuthHandlerOptions *auth.AuthorizationHandlerOptions - // TokenURL allows to set the token endpoint for user credential flows. If - // unset the default value is: https://oauth2.googleapis.com/token. - // Optional. - TokenURL string - // STSAudience is the audience sent to when retrieving an STS token. - // Currently this only used for GDCH auth flow, for which it is required. - STSAudience string - // CredentialsFile overrides detection logic and sources a credential file - // from the provided filepath. If provided, CredentialsJSON must not be. - // Optional. - // - // Important: If you accept a credential configuration (credential - // JSON/File/Stream) from an external source for authentication to Google - // Cloud Platform, you must validate it before providing it to any Google - // API or library. Providing an unvalidated credential configuration to - // Google APIs can compromise the security of your systems and data. For - // more information, refer to [Validate credential configurations from - // external sources](https://cloud.google.com/docs/authentication/external/externally-sourced-credentials). - CredentialsFile string - // CredentialsJSON overrides detection logic and uses the JSON bytes as the - // source for the credential. If provided, CredentialsFile must not be. - // Optional. - // - // Important: If you accept a credential configuration (credential - // JSON/File/Stream) from an external source for authentication to Google - // Cloud Platform, you must validate it before providing it to any Google - // API or library. Providing an unvalidated credential configuration to - // Google APIs can compromise the security of your systems and data. For - // more information, refer to [Validate credential configurations from - // external sources](https://cloud.google.com/docs/authentication/external/externally-sourced-credentials). - CredentialsJSON []byte - // UseSelfSignedJWT directs service account based credentials to create a - // self-signed JWT with the private key found in the file, skipping any - // network requests that would normally be made. Optional. - UseSelfSignedJWT bool - // Client configures the underlying client used to make network requests - // when fetching tokens. Optional. - Client *http.Client - // UniverseDomain is the default service domain for a given Cloud universe. - // The default value is "googleapis.com". This option is ignored for - // authentication flows that do not support universe domain. Optional. - UniverseDomain string - // Logger is used for debug logging. If provided, logging will be enabled - // at the loggers configured level. By default logging is disabled unless - // enabled by setting GOOGLE_SDK_GO_LOGGING_LEVEL in which case a default - // logger will be used. Optional. - Logger *slog.Logger -} - -func (o *DetectOptions) validate() error { - if o == nil { - return errors.New("credentials: options must be provided") - } - if len(o.Scopes) > 0 && o.Audience != "" { - return errors.New("credentials: both scopes and audience were provided") - } - if len(o.CredentialsJSON) > 0 && o.CredentialsFile != "" { - return errors.New("credentials: both credentials file and JSON were provided") - } - return nil -} - -func (o *DetectOptions) tokenURL() string { - if o.TokenURL != "" { - return o.TokenURL - } - return googleTokenURL -} - -func (o *DetectOptions) scopes() []string { - scopes := make([]string, len(o.Scopes)) - copy(scopes, o.Scopes) - return scopes -} - -func (o *DetectOptions) client() *http.Client { - if o.Client != nil { - return o.Client - } - return internal.DefaultClient() -} - -func (o *DetectOptions) logger() *slog.Logger { - return internallog.New(o.Logger) -} - -func readCredentialsFile(filename string, opts *DetectOptions) (*auth.Credentials, error) { - b, err := os.ReadFile(filename) - if err != nil { - return nil, err - } - return readCredentialsFileJSON(b, opts) -} - -func readCredentialsFileJSON(b []byte, opts *DetectOptions) (*auth.Credentials, error) { - // attempt to parse jsonData as a Google Developers Console client_credentials.json. - config := clientCredConfigFromJSON(b, opts) - if config != nil { - if config.AuthHandlerOpts == nil { - return nil, errors.New("credentials: auth handler must be specified for this credential filetype") - } - tp, err := auth.New3LOTokenProvider(config) - if err != nil { - return nil, err - } - return auth.NewCredentials(&auth.CredentialsOptions{ - TokenProvider: tp, - JSON: b, - }), nil - } - return fileCredentials(b, opts) -} - -func clientCredConfigFromJSON(b []byte, opts *DetectOptions) *auth.Options3LO { - var creds credsfile.ClientCredentialsFile - var c *credsfile.Config3LO - if err := json.Unmarshal(b, &creds); err != nil { - return nil - } - switch { - case creds.Web != nil: - c = creds.Web - case creds.Installed != nil: - c = creds.Installed - default: - return nil - } - if len(c.RedirectURIs) < 1 { - return nil - } - var handleOpts *auth.AuthorizationHandlerOptions - if opts.AuthHandlerOptions != nil { - handleOpts = &auth.AuthorizationHandlerOptions{ - Handler: opts.AuthHandlerOptions.Handler, - State: opts.AuthHandlerOptions.State, - PKCEOpts: opts.AuthHandlerOptions.PKCEOpts, - } - } - return &auth.Options3LO{ - ClientID: c.ClientID, - ClientSecret: c.ClientSecret, - RedirectURL: c.RedirectURIs[0], - Scopes: opts.scopes(), - AuthURL: c.AuthURI, - TokenURL: c.TokenURI, - Client: opts.client(), - Logger: opts.logger(), - EarlyTokenExpiry: opts.EarlyTokenRefresh, - AuthHandlerOpts: handleOpts, - // TODO(codyoss): refactor this out. We need to add in auto-detection - // for this use case. - AuthStyle: auth.StyleInParams, - } -} diff --git a/vendor/cloud.google.com/go/auth/credentials/doc.go b/vendor/cloud.google.com/go/auth/credentials/doc.go deleted file mode 100644 index 1dbb2866..00000000 --- a/vendor/cloud.google.com/go/auth/credentials/doc.go +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package credentials provides support for making OAuth2 authorized and -// authenticated HTTP requests to Google APIs. It supports the Web server flow, -// client-side credentials, service accounts, Google Compute Engine service -// accounts, Google App Engine service accounts and workload identity federation -// from non-Google cloud platforms. -// -// A brief overview of the package follows. For more information, please read -// https://developers.google.com/accounts/docs/OAuth2 -// and -// https://developers.google.com/accounts/docs/application-default-credentials. -// For more information on using workload identity federation, refer to -// https://cloud.google.com/iam/docs/how-to#using-workload-identity-federation. -// -// # Credentials -// -// The [cloud.google.com/go/auth.Credentials] type represents Google -// credentials, including Application Default Credentials. -// -// Use [DetectDefault] to obtain Application Default Credentials. -// -// Application Default Credentials support workload identity federation to -// access Google Cloud resources from non-Google Cloud platforms including Amazon -// Web Services (AWS), Microsoft Azure or any identity provider that supports -// OpenID Connect (OIDC). Workload identity federation is recommended for -// non-Google Cloud environments as it avoids the need to download, manage, and -// store service account private keys locally. -// -// # Workforce Identity Federation -// -// For more information on this feature see [cloud.google.com/go/auth/credentials/externalaccount]. -package credentials diff --git a/vendor/cloud.google.com/go/auth/credentials/filetypes.go b/vendor/cloud.google.com/go/auth/credentials/filetypes.go deleted file mode 100644 index e5243e6c..00000000 --- a/vendor/cloud.google.com/go/auth/credentials/filetypes.go +++ /dev/null @@ -1,231 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package credentials - -import ( - "errors" - "fmt" - - "cloud.google.com/go/auth" - "cloud.google.com/go/auth/credentials/internal/externalaccount" - "cloud.google.com/go/auth/credentials/internal/externalaccountuser" - "cloud.google.com/go/auth/credentials/internal/gdch" - "cloud.google.com/go/auth/credentials/internal/impersonate" - internalauth "cloud.google.com/go/auth/internal" - "cloud.google.com/go/auth/internal/credsfile" -) - -func fileCredentials(b []byte, opts *DetectOptions) (*auth.Credentials, error) { - fileType, err := credsfile.ParseFileType(b) - if err != nil { - return nil, err - } - - var projectID, universeDomain string - var tp auth.TokenProvider - switch fileType { - case credsfile.ServiceAccountKey: - f, err := credsfile.ParseServiceAccount(b) - if err != nil { - return nil, err - } - tp, err = handleServiceAccount(f, opts) - if err != nil { - return nil, err - } - projectID = f.ProjectID - universeDomain = resolveUniverseDomain(opts.UniverseDomain, f.UniverseDomain) - case credsfile.UserCredentialsKey: - f, err := credsfile.ParseUserCredentials(b) - if err != nil { - return nil, err - } - tp, err = handleUserCredential(f, opts) - if err != nil { - return nil, err - } - universeDomain = f.UniverseDomain - case credsfile.ExternalAccountKey: - f, err := credsfile.ParseExternalAccount(b) - if err != nil { - return nil, err - } - tp, err = handleExternalAccount(f, opts) - if err != nil { - return nil, err - } - universeDomain = resolveUniverseDomain(opts.UniverseDomain, f.UniverseDomain) - case credsfile.ExternalAccountAuthorizedUserKey: - f, err := credsfile.ParseExternalAccountAuthorizedUser(b) - if err != nil { - return nil, err - } - tp, err = handleExternalAccountAuthorizedUser(f, opts) - if err != nil { - return nil, err - } - universeDomain = f.UniverseDomain - case credsfile.ImpersonatedServiceAccountKey: - f, err := credsfile.ParseImpersonatedServiceAccount(b) - if err != nil { - return nil, err - } - tp, err = handleImpersonatedServiceAccount(f, opts) - if err != nil { - return nil, err - } - universeDomain = resolveUniverseDomain(opts.UniverseDomain, f.UniverseDomain) - case credsfile.GDCHServiceAccountKey: - f, err := credsfile.ParseGDCHServiceAccount(b) - if err != nil { - return nil, err - } - tp, err = handleGDCHServiceAccount(f, opts) - if err != nil { - return nil, err - } - projectID = f.Project - universeDomain = f.UniverseDomain - default: - return nil, fmt.Errorf("credentials: unsupported filetype %q", fileType) - } - return auth.NewCredentials(&auth.CredentialsOptions{ - TokenProvider: auth.NewCachedTokenProvider(tp, &auth.CachedTokenProviderOptions{ - ExpireEarly: opts.EarlyTokenRefresh, - }), - JSON: b, - ProjectIDProvider: internalauth.StaticCredentialsProperty(projectID), - // TODO(codyoss): only set quota project here if there was a user override - UniverseDomainProvider: internalauth.StaticCredentialsProperty(universeDomain), - }), nil -} - -// resolveUniverseDomain returns optsUniverseDomain if non-empty, in order to -// support configuring universe-specific credentials in code. Auth flows -// unsupported for universe domain should not use this func, but should instead -// simply set the file universe domain on the credentials. -func resolveUniverseDomain(optsUniverseDomain, fileUniverseDomain string) string { - if optsUniverseDomain != "" { - return optsUniverseDomain - } - return fileUniverseDomain -} - -func handleServiceAccount(f *credsfile.ServiceAccountFile, opts *DetectOptions) (auth.TokenProvider, error) { - ud := resolveUniverseDomain(opts.UniverseDomain, f.UniverseDomain) - if opts.UseSelfSignedJWT { - return configureSelfSignedJWT(f, opts) - } else if ud != "" && ud != internalauth.DefaultUniverseDomain { - // For non-GDU universe domains, token exchange is impossible and services - // must support self-signed JWTs. - opts.UseSelfSignedJWT = true - return configureSelfSignedJWT(f, opts) - } - opts2LO := &auth.Options2LO{ - Email: f.ClientEmail, - PrivateKey: []byte(f.PrivateKey), - PrivateKeyID: f.PrivateKeyID, - Scopes: opts.scopes(), - TokenURL: f.TokenURL, - Subject: opts.Subject, - Client: opts.client(), - Logger: opts.logger(), - } - if opts2LO.TokenURL == "" { - opts2LO.TokenURL = jwtTokenURL - } - return auth.New2LOTokenProvider(opts2LO) -} - -func handleUserCredential(f *credsfile.UserCredentialsFile, opts *DetectOptions) (auth.TokenProvider, error) { - opts3LO := &auth.Options3LO{ - ClientID: f.ClientID, - ClientSecret: f.ClientSecret, - Scopes: opts.scopes(), - AuthURL: googleAuthURL, - TokenURL: opts.tokenURL(), - AuthStyle: auth.StyleInParams, - EarlyTokenExpiry: opts.EarlyTokenRefresh, - RefreshToken: f.RefreshToken, - Client: opts.client(), - Logger: opts.logger(), - } - return auth.New3LOTokenProvider(opts3LO) -} - -func handleExternalAccount(f *credsfile.ExternalAccountFile, opts *DetectOptions) (auth.TokenProvider, error) { - externalOpts := &externalaccount.Options{ - Audience: f.Audience, - SubjectTokenType: f.SubjectTokenType, - TokenURL: f.TokenURL, - TokenInfoURL: f.TokenInfoURL, - ServiceAccountImpersonationURL: f.ServiceAccountImpersonationURL, - ClientSecret: f.ClientSecret, - ClientID: f.ClientID, - CredentialSource: f.CredentialSource, - QuotaProjectID: f.QuotaProjectID, - Scopes: opts.scopes(), - WorkforcePoolUserProject: f.WorkforcePoolUserProject, - Client: opts.client(), - Logger: opts.logger(), - IsDefaultClient: opts.Client == nil, - } - if f.ServiceAccountImpersonation != nil { - externalOpts.ServiceAccountImpersonationLifetimeSeconds = f.ServiceAccountImpersonation.TokenLifetimeSeconds - } - return externalaccount.NewTokenProvider(externalOpts) -} - -func handleExternalAccountAuthorizedUser(f *credsfile.ExternalAccountAuthorizedUserFile, opts *DetectOptions) (auth.TokenProvider, error) { - externalOpts := &externalaccountuser.Options{ - Audience: f.Audience, - RefreshToken: f.RefreshToken, - TokenURL: f.TokenURL, - TokenInfoURL: f.TokenInfoURL, - ClientID: f.ClientID, - ClientSecret: f.ClientSecret, - Scopes: opts.scopes(), - Client: opts.client(), - Logger: opts.logger(), - } - return externalaccountuser.NewTokenProvider(externalOpts) -} - -func handleImpersonatedServiceAccount(f *credsfile.ImpersonatedServiceAccountFile, opts *DetectOptions) (auth.TokenProvider, error) { - if f.ServiceAccountImpersonationURL == "" || f.CredSource == nil { - return nil, errors.New("missing 'source_credentials' field or 'service_account_impersonation_url' in credentials") - } - - tp, err := fileCredentials(f.CredSource, opts) - if err != nil { - return nil, err - } - return impersonate.NewTokenProvider(&impersonate.Options{ - URL: f.ServiceAccountImpersonationURL, - Scopes: opts.scopes(), - Tp: tp, - Delegates: f.Delegates, - Client: opts.client(), - Logger: opts.logger(), - }) -} - -func handleGDCHServiceAccount(f *credsfile.GDCHServiceAccountFile, opts *DetectOptions) (auth.TokenProvider, error) { - return gdch.NewTokenProvider(f, &gdch.Options{ - STSAudience: opts.STSAudience, - Client: opts.client(), - Logger: opts.logger(), - }) -} diff --git a/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/aws_provider.go b/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/aws_provider.go deleted file mode 100644 index 9ecd1f64..00000000 --- a/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/aws_provider.go +++ /dev/null @@ -1,531 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package externalaccount - -import ( - "bytes" - "context" - "crypto/hmac" - "crypto/sha256" - "encoding/hex" - "encoding/json" - "errors" - "fmt" - "log/slog" - "net/http" - "net/url" - "os" - "path" - "sort" - "strings" - "time" - - "cloud.google.com/go/auth/internal" - "github.com/googleapis/gax-go/v2/internallog" -) - -var ( - // getenv aliases os.Getenv for testing - getenv = os.Getenv -) - -const ( - // AWS Signature Version 4 signing algorithm identifier. - awsAlgorithm = "AWS4-HMAC-SHA256" - - // The termination string for the AWS credential scope value as defined in - // https://docs.aws.amazon.com/general/latest/gr/sigv4-create-string-to-sign.html - awsRequestType = "aws4_request" - - // The AWS authorization header name for the security session token if available. - awsSecurityTokenHeader = "x-amz-security-token" - - // The name of the header containing the session token for metadata endpoint calls - awsIMDSv2SessionTokenHeader = "X-aws-ec2-metadata-token" - - awsIMDSv2SessionTTLHeader = "X-aws-ec2-metadata-token-ttl-seconds" - - awsIMDSv2SessionTTL = "300" - - // The AWS authorization header name for the auto-generated date. - awsDateHeader = "x-amz-date" - - defaultRegionalCredentialVerificationURL = "https://sts.{region}.amazonaws.com?Action=GetCallerIdentity&Version=2011-06-15" - - // Supported AWS configuration environment variables. - awsAccessKeyIDEnvVar = "AWS_ACCESS_KEY_ID" - awsDefaultRegionEnvVar = "AWS_DEFAULT_REGION" - awsRegionEnvVar = "AWS_REGION" - awsSecretAccessKeyEnvVar = "AWS_SECRET_ACCESS_KEY" - awsSessionTokenEnvVar = "AWS_SESSION_TOKEN" - - awsTimeFormatLong = "20060102T150405Z" - awsTimeFormatShort = "20060102" - awsProviderType = "aws" -) - -type awsSubjectProvider struct { - EnvironmentID string - RegionURL string - RegionalCredVerificationURL string - CredVerificationURL string - IMDSv2SessionTokenURL string - TargetResource string - requestSigner *awsRequestSigner - region string - securityCredentialsProvider AwsSecurityCredentialsProvider - reqOpts *RequestOptions - - Client *http.Client - logger *slog.Logger -} - -func (sp *awsSubjectProvider) subjectToken(ctx context.Context) (string, error) { - // Set Defaults - if sp.RegionalCredVerificationURL == "" { - sp.RegionalCredVerificationURL = defaultRegionalCredentialVerificationURL - } - headers := make(map[string]string) - if sp.shouldUseMetadataServer() { - awsSessionToken, err := sp.getAWSSessionToken(ctx) - if err != nil { - return "", err - } - - if awsSessionToken != "" { - headers[awsIMDSv2SessionTokenHeader] = awsSessionToken - } - } - - awsSecurityCredentials, err := sp.getSecurityCredentials(ctx, headers) - if err != nil { - return "", err - } - if sp.region, err = sp.getRegion(ctx, headers); err != nil { - return "", err - } - sp.requestSigner = &awsRequestSigner{ - RegionName: sp.region, - AwsSecurityCredentials: awsSecurityCredentials, - } - - // Generate the signed request to AWS STS GetCallerIdentity API. - // Use the required regional endpoint. Otherwise, the request will fail. - req, err := http.NewRequestWithContext(ctx, "POST", strings.Replace(sp.RegionalCredVerificationURL, "{region}", sp.region, 1), nil) - if err != nil { - return "", err - } - // The full, canonical resource name of the workload identity pool - // provider, with or without the HTTPS prefix. - // Including this header as part of the signature is recommended to - // ensure data integrity. - if sp.TargetResource != "" { - req.Header.Set("x-goog-cloud-target-resource", sp.TargetResource) - } - sp.requestSigner.signRequest(req) - - /* - The GCP STS endpoint expects the headers to be formatted as: - # [ - # {key: 'x-amz-date', value: '...'}, - # {key: 'Authorization', value: '...'}, - # ... - # ] - # And then serialized as: - # quote(json.dumps({ - # url: '...', - # method: 'POST', - # headers: [{key: 'x-amz-date', value: '...'}, ...] - # })) - */ - - awsSignedReq := awsRequest{ - URL: req.URL.String(), - Method: "POST", - } - for headerKey, headerList := range req.Header { - for _, headerValue := range headerList { - awsSignedReq.Headers = append(awsSignedReq.Headers, awsRequestHeader{ - Key: headerKey, - Value: headerValue, - }) - } - } - sort.Slice(awsSignedReq.Headers, func(i, j int) bool { - headerCompare := strings.Compare(awsSignedReq.Headers[i].Key, awsSignedReq.Headers[j].Key) - if headerCompare == 0 { - return strings.Compare(awsSignedReq.Headers[i].Value, awsSignedReq.Headers[j].Value) < 0 - } - return headerCompare < 0 - }) - - result, err := json.Marshal(awsSignedReq) - if err != nil { - return "", err - } - return url.QueryEscape(string(result)), nil -} - -func (sp *awsSubjectProvider) providerType() string { - if sp.securityCredentialsProvider != nil { - return programmaticProviderType - } - return awsProviderType -} - -func (sp *awsSubjectProvider) getAWSSessionToken(ctx context.Context) (string, error) { - if sp.IMDSv2SessionTokenURL == "" { - return "", nil - } - req, err := http.NewRequestWithContext(ctx, "PUT", sp.IMDSv2SessionTokenURL, nil) - if err != nil { - return "", err - } - req.Header.Set(awsIMDSv2SessionTTLHeader, awsIMDSv2SessionTTL) - - sp.logger.DebugContext(ctx, "aws session token request", "request", internallog.HTTPRequest(req, nil)) - resp, body, err := internal.DoRequest(sp.Client, req) - if err != nil { - return "", err - } - sp.logger.DebugContext(ctx, "aws session token response", "response", internallog.HTTPResponse(resp, body)) - if resp.StatusCode != http.StatusOK { - return "", fmt.Errorf("credentials: unable to retrieve AWS session token: %s", body) - } - return string(body), nil -} - -func (sp *awsSubjectProvider) getRegion(ctx context.Context, headers map[string]string) (string, error) { - if sp.securityCredentialsProvider != nil { - return sp.securityCredentialsProvider.AwsRegion(ctx, sp.reqOpts) - } - if canRetrieveRegionFromEnvironment() { - if envAwsRegion := getenv(awsRegionEnvVar); envAwsRegion != "" { - return envAwsRegion, nil - } - return getenv(awsDefaultRegionEnvVar), nil - } - - if sp.RegionURL == "" { - return "", errors.New("credentials: unable to determine AWS region") - } - - req, err := http.NewRequestWithContext(ctx, "GET", sp.RegionURL, nil) - if err != nil { - return "", err - } - - for name, value := range headers { - req.Header.Add(name, value) - } - sp.logger.DebugContext(ctx, "aws region request", "request", internallog.HTTPRequest(req, nil)) - resp, body, err := internal.DoRequest(sp.Client, req) - if err != nil { - return "", err - } - sp.logger.DebugContext(ctx, "aws region response", "response", internallog.HTTPResponse(resp, body)) - if resp.StatusCode != http.StatusOK { - return "", fmt.Errorf("credentials: unable to retrieve AWS region - %s", body) - } - - // This endpoint will return the region in format: us-east-2b. - // Only the us-east-2 part should be used. - bodyLen := len(body) - if bodyLen == 0 { - return "", nil - } - return string(body[:bodyLen-1]), nil -} - -func (sp *awsSubjectProvider) getSecurityCredentials(ctx context.Context, headers map[string]string) (result *AwsSecurityCredentials, err error) { - if sp.securityCredentialsProvider != nil { - return sp.securityCredentialsProvider.AwsSecurityCredentials(ctx, sp.reqOpts) - } - if canRetrieveSecurityCredentialFromEnvironment() { - return &AwsSecurityCredentials{ - AccessKeyID: getenv(awsAccessKeyIDEnvVar), - SecretAccessKey: getenv(awsSecretAccessKeyEnvVar), - SessionToken: getenv(awsSessionTokenEnvVar), - }, nil - } - - roleName, err := sp.getMetadataRoleName(ctx, headers) - if err != nil { - return - } - credentials, err := sp.getMetadataSecurityCredentials(ctx, roleName, headers) - if err != nil { - return - } - - if credentials.AccessKeyID == "" { - return result, errors.New("credentials: missing AccessKeyId credential") - } - if credentials.SecretAccessKey == "" { - return result, errors.New("credentials: missing SecretAccessKey credential") - } - - return credentials, nil -} - -func (sp *awsSubjectProvider) getMetadataSecurityCredentials(ctx context.Context, roleName string, headers map[string]string) (*AwsSecurityCredentials, error) { - var result *AwsSecurityCredentials - - req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("%s/%s", sp.CredVerificationURL, roleName), nil) - if err != nil { - return result, err - } - for name, value := range headers { - req.Header.Add(name, value) - } - sp.logger.DebugContext(ctx, "aws security credential request", "request", internallog.HTTPRequest(req, nil)) - resp, body, err := internal.DoRequest(sp.Client, req) - if err != nil { - return result, err - } - sp.logger.DebugContext(ctx, "aws security credential response", "response", internallog.HTTPResponse(resp, body)) - if resp.StatusCode != http.StatusOK { - return result, fmt.Errorf("credentials: unable to retrieve AWS security credentials - %s", body) - } - if err := json.Unmarshal(body, &result); err != nil { - return nil, err - } - return result, nil -} - -func (sp *awsSubjectProvider) getMetadataRoleName(ctx context.Context, headers map[string]string) (string, error) { - if sp.CredVerificationURL == "" { - return "", errors.New("credentials: unable to determine the AWS metadata server security credentials endpoint") - } - req, err := http.NewRequestWithContext(ctx, "GET", sp.CredVerificationURL, nil) - if err != nil { - return "", err - } - for name, value := range headers { - req.Header.Add(name, value) - } - - sp.logger.DebugContext(ctx, "aws metadata role request", "request", internallog.HTTPRequest(req, nil)) - resp, body, err := internal.DoRequest(sp.Client, req) - if err != nil { - return "", err - } - sp.logger.DebugContext(ctx, "aws metadata role response", "response", internallog.HTTPResponse(resp, body)) - if resp.StatusCode != http.StatusOK { - return "", fmt.Errorf("credentials: unable to retrieve AWS role name - %s", body) - } - return string(body), nil -} - -// awsRequestSigner is a utility class to sign http requests using a AWS V4 signature. -type awsRequestSigner struct { - RegionName string - AwsSecurityCredentials *AwsSecurityCredentials -} - -// signRequest adds the appropriate headers to an http.Request -// or returns an error if something prevented this. -func (rs *awsRequestSigner) signRequest(req *http.Request) error { - // req is assumed non-nil - signedRequest := cloneRequest(req) - timestamp := Now() - signedRequest.Header.Set("host", requestHost(req)) - if rs.AwsSecurityCredentials.SessionToken != "" { - signedRequest.Header.Set(awsSecurityTokenHeader, rs.AwsSecurityCredentials.SessionToken) - } - if signedRequest.Header.Get("date") == "" { - signedRequest.Header.Set(awsDateHeader, timestamp.Format(awsTimeFormatLong)) - } - authorizationCode, err := rs.generateAuthentication(signedRequest, timestamp) - if err != nil { - return err - } - signedRequest.Header.Set("Authorization", authorizationCode) - req.Header = signedRequest.Header - return nil -} - -func (rs *awsRequestSigner) generateAuthentication(req *http.Request, timestamp time.Time) (string, error) { - canonicalHeaderColumns, canonicalHeaderData := canonicalHeaders(req) - dateStamp := timestamp.Format(awsTimeFormatShort) - serviceName := "" - - if splitHost := strings.Split(requestHost(req), "."); len(splitHost) > 0 { - serviceName = splitHost[0] - } - credentialScope := strings.Join([]string{dateStamp, rs.RegionName, serviceName, awsRequestType}, "/") - requestString, err := canonicalRequest(req, canonicalHeaderColumns, canonicalHeaderData) - if err != nil { - return "", err - } - requestHash, err := getSha256([]byte(requestString)) - if err != nil { - return "", err - } - - stringToSign := strings.Join([]string{awsAlgorithm, timestamp.Format(awsTimeFormatLong), credentialScope, requestHash}, "\n") - signingKey := []byte("AWS4" + rs.AwsSecurityCredentials.SecretAccessKey) - for _, signingInput := range []string{ - dateStamp, rs.RegionName, serviceName, awsRequestType, stringToSign, - } { - signingKey, err = getHmacSha256(signingKey, []byte(signingInput)) - if err != nil { - return "", err - } - } - - return fmt.Sprintf("%s Credential=%s/%s, SignedHeaders=%s, Signature=%s", awsAlgorithm, rs.AwsSecurityCredentials.AccessKeyID, credentialScope, canonicalHeaderColumns, hex.EncodeToString(signingKey)), nil -} - -func getSha256(input []byte) (string, error) { - hash := sha256.New() - if _, err := hash.Write(input); err != nil { - return "", err - } - return hex.EncodeToString(hash.Sum(nil)), nil -} - -func getHmacSha256(key, input []byte) ([]byte, error) { - hash := hmac.New(sha256.New, key) - if _, err := hash.Write(input); err != nil { - return nil, err - } - return hash.Sum(nil), nil -} - -func cloneRequest(r *http.Request) *http.Request { - r2 := new(http.Request) - *r2 = *r - if r.Header != nil { - r2.Header = make(http.Header, len(r.Header)) - - // Find total number of values. - headerCount := 0 - for _, headerValues := range r.Header { - headerCount += len(headerValues) - } - copiedHeaders := make([]string, headerCount) // shared backing array for headers' values - - for headerKey, headerValues := range r.Header { - headerCount = copy(copiedHeaders, headerValues) - r2.Header[headerKey] = copiedHeaders[:headerCount:headerCount] - copiedHeaders = copiedHeaders[headerCount:] - } - } - return r2 -} - -func canonicalPath(req *http.Request) string { - result := req.URL.EscapedPath() - if result == "" { - return "/" - } - return path.Clean(result) -} - -func canonicalQuery(req *http.Request) string { - queryValues := req.URL.Query() - for queryKey := range queryValues { - sort.Strings(queryValues[queryKey]) - } - return queryValues.Encode() -} - -func canonicalHeaders(req *http.Request) (string, string) { - // Header keys need to be sorted alphabetically. - var headers []string - lowerCaseHeaders := make(http.Header) - for k, v := range req.Header { - k := strings.ToLower(k) - if _, ok := lowerCaseHeaders[k]; ok { - // include additional values - lowerCaseHeaders[k] = append(lowerCaseHeaders[k], v...) - } else { - headers = append(headers, k) - lowerCaseHeaders[k] = v - } - } - sort.Strings(headers) - - var fullHeaders bytes.Buffer - for _, header := range headers { - headerValue := strings.Join(lowerCaseHeaders[header], ",") - fullHeaders.WriteString(header) - fullHeaders.WriteRune(':') - fullHeaders.WriteString(headerValue) - fullHeaders.WriteRune('\n') - } - - return strings.Join(headers, ";"), fullHeaders.String() -} - -func requestDataHash(req *http.Request) (string, error) { - var requestData []byte - if req.Body != nil { - requestBody, err := req.GetBody() - if err != nil { - return "", err - } - defer requestBody.Close() - - requestData, err = internal.ReadAll(requestBody) - if err != nil { - return "", err - } - } - - return getSha256(requestData) -} - -func requestHost(req *http.Request) string { - if req.Host != "" { - return req.Host - } - return req.URL.Host -} - -func canonicalRequest(req *http.Request, canonicalHeaderColumns, canonicalHeaderData string) (string, error) { - dataHash, err := requestDataHash(req) - if err != nil { - return "", err - } - return fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n%s", req.Method, canonicalPath(req), canonicalQuery(req), canonicalHeaderData, canonicalHeaderColumns, dataHash), nil -} - -type awsRequestHeader struct { - Key string `json:"key"` - Value string `json:"value"` -} - -type awsRequest struct { - URL string `json:"url"` - Method string `json:"method"` - Headers []awsRequestHeader `json:"headers"` -} - -// The AWS region can be provided through AWS_REGION or AWS_DEFAULT_REGION. Only one is -// required. -func canRetrieveRegionFromEnvironment() bool { - return getenv(awsRegionEnvVar) != "" || getenv(awsDefaultRegionEnvVar) != "" -} - -// Check if both AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are available. -func canRetrieveSecurityCredentialFromEnvironment() bool { - return getenv(awsAccessKeyIDEnvVar) != "" && getenv(awsSecretAccessKeyEnvVar) != "" -} - -func (sp *awsSubjectProvider) shouldUseMetadataServer() bool { - return sp.securityCredentialsProvider == nil && (!canRetrieveRegionFromEnvironment() || !canRetrieveSecurityCredentialFromEnvironment()) -} diff --git a/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/executable_provider.go b/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/executable_provider.go deleted file mode 100644 index d5765c47..00000000 --- a/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/executable_provider.go +++ /dev/null @@ -1,284 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package externalaccount - -import ( - "bytes" - "context" - "encoding/json" - "errors" - "fmt" - "net/http" - "os" - "os/exec" - "regexp" - "strings" - "time" - - "cloud.google.com/go/auth/internal" -) - -const ( - executableSupportedMaxVersion = 1 - executableDefaultTimeout = 30 * time.Second - executableSource = "response" - executableProviderType = "executable" - outputFileSource = "output file" - - allowExecutablesEnvVar = "GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES" - - jwtTokenType = "urn:ietf:params:oauth:token-type:jwt" - idTokenType = "urn:ietf:params:oauth:token-type:id_token" - saml2TokenType = "urn:ietf:params:oauth:token-type:saml2" -) - -var ( - serviceAccountImpersonationRE = regexp.MustCompile(`https://iamcredentials..+/v1/projects/-/serviceAccounts/(.*@.*):generateAccessToken`) -) - -type nonCacheableError struct { - message string -} - -func (nce nonCacheableError) Error() string { - return nce.message -} - -// environment is a contract for testing -type environment interface { - existingEnv() []string - getenv(string) string - run(ctx context.Context, command string, env []string) ([]byte, error) - now() time.Time -} - -type runtimeEnvironment struct{} - -func (r runtimeEnvironment) existingEnv() []string { - return os.Environ() -} -func (r runtimeEnvironment) getenv(key string) string { - return os.Getenv(key) -} -func (r runtimeEnvironment) now() time.Time { - return time.Now().UTC() -} - -func (r runtimeEnvironment) run(ctx context.Context, command string, env []string) ([]byte, error) { - splitCommand := strings.Fields(command) - cmd := exec.CommandContext(ctx, splitCommand[0], splitCommand[1:]...) - cmd.Env = env - - var stdout, stderr bytes.Buffer - cmd.Stdout = &stdout - cmd.Stderr = &stderr - - if err := cmd.Run(); err != nil { - if ctx.Err() == context.DeadlineExceeded { - return nil, context.DeadlineExceeded - } - if exitError, ok := err.(*exec.ExitError); ok { - return nil, exitCodeError(exitError) - } - return nil, executableError(err) - } - - bytesStdout := bytes.TrimSpace(stdout.Bytes()) - if len(bytesStdout) > 0 { - return bytesStdout, nil - } - return bytes.TrimSpace(stderr.Bytes()), nil -} - -type executableSubjectProvider struct { - Command string - Timeout time.Duration - OutputFile string - client *http.Client - opts *Options - env environment -} - -type executableResponse struct { - Version int `json:"version,omitempty"` - Success *bool `json:"success,omitempty"` - TokenType string `json:"token_type,omitempty"` - ExpirationTime int64 `json:"expiration_time,omitempty"` - IDToken string `json:"id_token,omitempty"` - SamlResponse string `json:"saml_response,omitempty"` - Code string `json:"code,omitempty"` - Message string `json:"message,omitempty"` -} - -func (sp *executableSubjectProvider) parseSubjectTokenFromSource(response []byte, source string, now int64) (string, error) { - var result executableResponse - if err := json.Unmarshal(response, &result); err != nil { - return "", jsonParsingError(source, string(response)) - } - // Validate - if result.Version == 0 { - return "", missingFieldError(source, "version") - } - if result.Success == nil { - return "", missingFieldError(source, "success") - } - if !*result.Success { - if result.Code == "" || result.Message == "" { - return "", malformedFailureError() - } - return "", userDefinedError(result.Code, result.Message) - } - if result.Version > executableSupportedMaxVersion || result.Version < 0 { - return "", unsupportedVersionError(source, result.Version) - } - if result.ExpirationTime == 0 && sp.OutputFile != "" { - return "", missingFieldError(source, "expiration_time") - } - if result.TokenType == "" { - return "", missingFieldError(source, "token_type") - } - if result.ExpirationTime != 0 && result.ExpirationTime < now { - return "", tokenExpiredError() - } - - switch result.TokenType { - case jwtTokenType, idTokenType: - if result.IDToken == "" { - return "", missingFieldError(source, "id_token") - } - return result.IDToken, nil - case saml2TokenType: - if result.SamlResponse == "" { - return "", missingFieldError(source, "saml_response") - } - return result.SamlResponse, nil - default: - return "", tokenTypeError(source) - } -} - -func (sp *executableSubjectProvider) subjectToken(ctx context.Context) (string, error) { - if token, err := sp.getTokenFromOutputFile(); token != "" || err != nil { - return token, err - } - return sp.getTokenFromExecutableCommand(ctx) -} - -func (sp *executableSubjectProvider) providerType() string { - return executableProviderType -} - -func (sp *executableSubjectProvider) getTokenFromOutputFile() (token string, err error) { - if sp.OutputFile == "" { - // This ExecutableCredentialSource doesn't use an OutputFile. - return "", nil - } - - file, err := os.Open(sp.OutputFile) - if err != nil { - // No OutputFile found. Hasn't been created yet, so skip it. - return "", nil - } - defer file.Close() - - data, err := internal.ReadAll(file) - if err != nil || len(data) == 0 { - // Cachefile exists, but no data found. Get new credential. - return "", nil - } - - token, err = sp.parseSubjectTokenFromSource(data, outputFileSource, sp.env.now().Unix()) - if err != nil { - if _, ok := err.(nonCacheableError); ok { - // If the cached token is expired we need a new token, - // and if the cache contains a failure, we need to try again. - return "", nil - } - - // There was an error in the cached token, and the developer should be aware of it. - return "", err - } - // Token parsing succeeded. Use found token. - return token, nil -} - -func (sp *executableSubjectProvider) executableEnvironment() []string { - result := sp.env.existingEnv() - result = append(result, fmt.Sprintf("GOOGLE_EXTERNAL_ACCOUNT_AUDIENCE=%v", sp.opts.Audience)) - result = append(result, fmt.Sprintf("GOOGLE_EXTERNAL_ACCOUNT_TOKEN_TYPE=%v", sp.opts.SubjectTokenType)) - result = append(result, "GOOGLE_EXTERNAL_ACCOUNT_INTERACTIVE=0") - if sp.opts.ServiceAccountImpersonationURL != "" { - matches := serviceAccountImpersonationRE.FindStringSubmatch(sp.opts.ServiceAccountImpersonationURL) - if matches != nil { - result = append(result, fmt.Sprintf("GOOGLE_EXTERNAL_ACCOUNT_IMPERSONATED_EMAIL=%v", matches[1])) - } - } - if sp.OutputFile != "" { - result = append(result, fmt.Sprintf("GOOGLE_EXTERNAL_ACCOUNT_OUTPUT_FILE=%v", sp.OutputFile)) - } - return result -} - -func (sp *executableSubjectProvider) getTokenFromExecutableCommand(ctx context.Context) (string, error) { - // For security reasons, we need our consumers to set this environment variable to allow executables to be run. - if sp.env.getenv(allowExecutablesEnvVar) != "1" { - return "", errors.New("credentials: executables need to be explicitly allowed (set GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES to '1') to run") - } - - ctx, cancel := context.WithDeadline(ctx, sp.env.now().Add(sp.Timeout)) - defer cancel() - - output, err := sp.env.run(ctx, sp.Command, sp.executableEnvironment()) - if err != nil { - return "", err - } - return sp.parseSubjectTokenFromSource(output, executableSource, sp.env.now().Unix()) -} - -func missingFieldError(source, field string) error { - return fmt.Errorf("credentials: %q missing %q field", source, field) -} - -func jsonParsingError(source, data string) error { - return fmt.Errorf("credentials: unable to parse %q: %v", source, data) -} - -func malformedFailureError() error { - return nonCacheableError{"credentials: response must include `error` and `message` fields when unsuccessful"} -} - -func userDefinedError(code, message string) error { - return nonCacheableError{fmt.Sprintf("credentials: response contains unsuccessful response: (%v) %v", code, message)} -} - -func unsupportedVersionError(source string, version int) error { - return fmt.Errorf("credentials: %v contains unsupported version: %v", source, version) -} - -func tokenExpiredError() error { - return nonCacheableError{"credentials: the token returned by the executable is expired"} -} - -func tokenTypeError(source string) error { - return fmt.Errorf("credentials: %v contains unsupported token type", source) -} - -func exitCodeError(err *exec.ExitError) error { - return fmt.Errorf("credentials: executable command failed with exit code %v: %w", err.ExitCode(), err) -} - -func executableError(err error) error { - return fmt.Errorf("credentials: executable command failed: %w", err) -} diff --git a/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/externalaccount.go b/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/externalaccount.go deleted file mode 100644 index a8220642..00000000 --- a/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/externalaccount.go +++ /dev/null @@ -1,428 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package externalaccount - -import ( - "context" - "errors" - "fmt" - "log/slog" - "net/http" - "regexp" - "strconv" - "strings" - "time" - - "cloud.google.com/go/auth" - "cloud.google.com/go/auth/credentials/internal/impersonate" - "cloud.google.com/go/auth/credentials/internal/stsexchange" - "cloud.google.com/go/auth/internal/credsfile" - "github.com/googleapis/gax-go/v2/internallog" -) - -const ( - timeoutMinimum = 5 * time.Second - timeoutMaximum = 120 * time.Second - - universeDomainPlaceholder = "UNIVERSE_DOMAIN" - defaultTokenURL = "https://sts.UNIVERSE_DOMAIN/v1/token" - defaultUniverseDomain = "googleapis.com" -) - -var ( - // Now aliases time.Now for testing - Now = func() time.Time { - return time.Now().UTC() - } - validWorkforceAudiencePattern *regexp.Regexp = regexp.MustCompile(`//iam\.googleapis\.com/locations/[^/]+/workforcePools/`) -) - -// Options stores the configuration for fetching tokens with external credentials. -type Options struct { - // Audience is the Secure Token Service (STS) audience which contains the resource name for the workload - // identity pool or the workforce pool and the provider identifier in that pool. - Audience string - // SubjectTokenType is the STS token type based on the Oauth2.0 token exchange spec - // e.g. `urn:ietf:params:oauth:token-type:jwt`. - SubjectTokenType string - // TokenURL is the STS token exchange endpoint. - TokenURL string - // TokenInfoURL is the token_info endpoint used to retrieve the account related information ( - // user attributes like account identifier, eg. email, username, uid, etc). This is - // needed for gCloud session account identification. - TokenInfoURL string - // ServiceAccountImpersonationURL is the URL for the service account impersonation request. This is only - // required for workload identity pools when APIs to be accessed have not integrated with UberMint. - ServiceAccountImpersonationURL string - // ServiceAccountImpersonationLifetimeSeconds is the number of seconds the service account impersonation - // token will be valid for. - ServiceAccountImpersonationLifetimeSeconds int - // ClientSecret is currently only required if token_info endpoint also - // needs to be called with the generated GCP access token. When provided, STS will be - // called with additional basic authentication using client_id as username and client_secret as password. - ClientSecret string - // ClientID is only required in conjunction with ClientSecret, as described above. - ClientID string - // CredentialSource contains the necessary information to retrieve the token itself, as well - // as some environmental information. - CredentialSource *credsfile.CredentialSource - // QuotaProjectID is injected by gCloud. If the value is non-empty, the Auth libraries - // will set the x-goog-user-project which overrides the project associated with the credentials. - QuotaProjectID string - // Scopes contains the desired scopes for the returned access token. - Scopes []string - // WorkforcePoolUserProject should be set when it is a workforce pool and - // not a workload identity pool. The underlying principal must still have - // serviceusage.services.use IAM permission to use the project for - // billing/quota. Optional. - WorkforcePoolUserProject string - // UniverseDomain is the default service domain for a given Cloud universe. - // This value will be used in the default STS token URL. The default value - // is "googleapis.com". It will not be used if TokenURL is set. Optional. - UniverseDomain string - // SubjectTokenProvider is an optional token provider for OIDC/SAML - // credentials. One of SubjectTokenProvider, AWSSecurityCredentialProvider - // or CredentialSource must be provided. Optional. - SubjectTokenProvider SubjectTokenProvider - // AwsSecurityCredentialsProvider is an AWS Security Credential provider - // for AWS credentials. One of SubjectTokenProvider, - // AWSSecurityCredentialProvider or CredentialSource must be provided. Optional. - AwsSecurityCredentialsProvider AwsSecurityCredentialsProvider - // Client for token request. - Client *http.Client - // IsDefaultClient marks whether the client passed in is a default client that can be overriden. - // This is important for X509 credentials which should create a new client if the default was used - // but should respect a client explicitly passed in by the user. - IsDefaultClient bool - // Logger is used for debug logging. If provided, logging will be enabled - // at the loggers configured level. By default logging is disabled unless - // enabled by setting GOOGLE_SDK_GO_LOGGING_LEVEL in which case a default - // logger will be used. Optional. - Logger *slog.Logger -} - -// SubjectTokenProvider can be used to supply a subject token to exchange for a -// GCP access token. -type SubjectTokenProvider interface { - // SubjectToken should return a valid subject token or an error. - // The external account token provider does not cache the returned subject - // token, so caching logic should be implemented in the provider to prevent - // multiple requests for the same subject token. - SubjectToken(ctx context.Context, opts *RequestOptions) (string, error) -} - -// RequestOptions contains information about the requested subject token or AWS -// security credentials from the Google external account credential. -type RequestOptions struct { - // Audience is the requested audience for the external account credential. - Audience string - // Subject token type is the requested subject token type for the external - // account credential. Expected values include: - // “urn:ietf:params:oauth:token-type:jwt” - // “urn:ietf:params:oauth:token-type:id-token” - // “urn:ietf:params:oauth:token-type:saml2” - // “urn:ietf:params:aws:token-type:aws4_request” - SubjectTokenType string -} - -// AwsSecurityCredentialsProvider can be used to supply AwsSecurityCredentials -// and an AWS Region to exchange for a GCP access token. -type AwsSecurityCredentialsProvider interface { - // AwsRegion should return the AWS region or an error. - AwsRegion(ctx context.Context, opts *RequestOptions) (string, error) - // GetAwsSecurityCredentials should return a valid set of - // AwsSecurityCredentials or an error. The external account token provider - // does not cache the returned security credentials, so caching logic should - // be implemented in the provider to prevent multiple requests for the - // same security credentials. - AwsSecurityCredentials(ctx context.Context, opts *RequestOptions) (*AwsSecurityCredentials, error) -} - -// AwsSecurityCredentials models AWS security credentials. -type AwsSecurityCredentials struct { - // AccessKeyId is the AWS Access Key ID - Required. - AccessKeyID string `json:"AccessKeyID"` - // SecretAccessKey is the AWS Secret Access Key - Required. - SecretAccessKey string `json:"SecretAccessKey"` - // SessionToken is the AWS Session token. This should be provided for - // temporary AWS security credentials - Optional. - SessionToken string `json:"Token"` -} - -func (o *Options) validate() error { - if o.Audience == "" { - return fmt.Errorf("externalaccount: Audience must be set") - } - if o.SubjectTokenType == "" { - return fmt.Errorf("externalaccount: Subject token type must be set") - } - if o.WorkforcePoolUserProject != "" { - if valid := validWorkforceAudiencePattern.MatchString(o.Audience); !valid { - return fmt.Errorf("externalaccount: workforce_pool_user_project should not be set for non-workforce pool credentials") - } - } - count := 0 - if o.CredentialSource != nil { - count++ - } - if o.SubjectTokenProvider != nil { - count++ - } - if o.AwsSecurityCredentialsProvider != nil { - count++ - } - if count == 0 { - return fmt.Errorf("externalaccount: one of CredentialSource, SubjectTokenProvider, or AwsSecurityCredentialsProvider must be set") - } - if count > 1 { - return fmt.Errorf("externalaccount: only one of CredentialSource, SubjectTokenProvider, or AwsSecurityCredentialsProvider must be set") - } - return nil -} - -// client returns the http client that should be used for the token exchange. If a non-default client -// is provided, then the client configured in the options will always be returned. If a default client -// is provided and the options are configured for X509 credentials, a new client will be created. -func (o *Options) client() (*http.Client, error) { - // If a client was provided and no override certificate config location was provided, use the provided client. - if o.CredentialSource == nil || o.CredentialSource.Certificate == nil || (!o.IsDefaultClient && o.CredentialSource.Certificate.CertificateConfigLocation == "") { - return o.Client, nil - } - - // If a new client should be created, validate and use the certificate source to create a new mTLS client. - cert := o.CredentialSource.Certificate - if !cert.UseDefaultCertificateConfig && cert.CertificateConfigLocation == "" { - return nil, errors.New("credentials: \"certificate\" object must either specify a certificate_config_location or use_default_certificate_config should be true") - } - if cert.UseDefaultCertificateConfig && cert.CertificateConfigLocation != "" { - return nil, errors.New("credentials: \"certificate\" object cannot specify both a certificate_config_location and use_default_certificate_config=true") - } - return createX509Client(cert.CertificateConfigLocation) -} - -// resolveTokenURL sets the default STS token endpoint with the configured -// universe domain. -func (o *Options) resolveTokenURL() { - if o.TokenURL != "" { - return - } else if o.UniverseDomain != "" { - o.TokenURL = strings.Replace(defaultTokenURL, universeDomainPlaceholder, o.UniverseDomain, 1) - } else { - o.TokenURL = strings.Replace(defaultTokenURL, universeDomainPlaceholder, defaultUniverseDomain, 1) - } -} - -// NewTokenProvider returns a [cloud.google.com/go/auth.TokenProvider] -// configured with the provided options. -func NewTokenProvider(opts *Options) (auth.TokenProvider, error) { - if err := opts.validate(); err != nil { - return nil, err - } - opts.resolveTokenURL() - logger := internallog.New(opts.Logger) - stp, err := newSubjectTokenProvider(opts) - if err != nil { - return nil, err - } - - client, err := opts.client() - if err != nil { - return nil, err - } - - tp := &tokenProvider{ - client: client, - opts: opts, - stp: stp, - logger: logger, - } - - if opts.ServiceAccountImpersonationURL == "" { - return auth.NewCachedTokenProvider(tp, nil), nil - } - - scopes := make([]string, len(opts.Scopes)) - copy(scopes, opts.Scopes) - // needed for impersonation - tp.opts.Scopes = []string{"https://www.googleapis.com/auth/cloud-platform"} - imp, err := impersonate.NewTokenProvider(&impersonate.Options{ - Client: client, - URL: opts.ServiceAccountImpersonationURL, - Scopes: scopes, - Tp: auth.NewCachedTokenProvider(tp, nil), - TokenLifetimeSeconds: opts.ServiceAccountImpersonationLifetimeSeconds, - Logger: logger, - }) - if err != nil { - return nil, err - } - return auth.NewCachedTokenProvider(imp, nil), nil -} - -type subjectTokenProvider interface { - subjectToken(ctx context.Context) (string, error) - providerType() string -} - -// tokenProvider is the provider that handles external credentials. It is used to retrieve Tokens. -type tokenProvider struct { - client *http.Client - logger *slog.Logger - opts *Options - stp subjectTokenProvider -} - -func (tp *tokenProvider) Token(ctx context.Context) (*auth.Token, error) { - subjectToken, err := tp.stp.subjectToken(ctx) - if err != nil { - return nil, err - } - - stsRequest := &stsexchange.TokenRequest{ - GrantType: stsexchange.GrantType, - Audience: tp.opts.Audience, - Scope: tp.opts.Scopes, - RequestedTokenType: stsexchange.TokenType, - SubjectToken: subjectToken, - SubjectTokenType: tp.opts.SubjectTokenType, - } - header := make(http.Header) - header.Set("Content-Type", "application/x-www-form-urlencoded") - header.Add("x-goog-api-client", getGoogHeaderValue(tp.opts, tp.stp)) - clientAuth := stsexchange.ClientAuthentication{ - AuthStyle: auth.StyleInHeader, - ClientID: tp.opts.ClientID, - ClientSecret: tp.opts.ClientSecret, - } - var options map[string]interface{} - // Do not pass workforce_pool_user_project when client authentication is used. - // The client ID is sufficient for determining the user project. - if tp.opts.WorkforcePoolUserProject != "" && tp.opts.ClientID == "" { - options = map[string]interface{}{ - "userProject": tp.opts.WorkforcePoolUserProject, - } - } - stsResp, err := stsexchange.ExchangeToken(ctx, &stsexchange.Options{ - Client: tp.client, - Endpoint: tp.opts.TokenURL, - Request: stsRequest, - Authentication: clientAuth, - Headers: header, - ExtraOpts: options, - Logger: tp.logger, - }) - if err != nil { - return nil, err - } - - tok := &auth.Token{ - Value: stsResp.AccessToken, - Type: stsResp.TokenType, - } - // The RFC8693 doesn't define the explicit 0 of "expires_in" field behavior. - if stsResp.ExpiresIn <= 0 { - return nil, fmt.Errorf("credentials: got invalid expiry from security token service") - } - tok.Expiry = Now().Add(time.Duration(stsResp.ExpiresIn) * time.Second) - return tok, nil -} - -// newSubjectTokenProvider determines the type of credsfile.CredentialSource needed to create a -// subjectTokenProvider -func newSubjectTokenProvider(o *Options) (subjectTokenProvider, error) { - logger := internallog.New(o.Logger) - reqOpts := &RequestOptions{Audience: o.Audience, SubjectTokenType: o.SubjectTokenType} - if o.AwsSecurityCredentialsProvider != nil { - return &awsSubjectProvider{ - securityCredentialsProvider: o.AwsSecurityCredentialsProvider, - TargetResource: o.Audience, - reqOpts: reqOpts, - logger: logger, - }, nil - } else if o.SubjectTokenProvider != nil { - return &programmaticProvider{stp: o.SubjectTokenProvider, opts: reqOpts}, nil - } else if len(o.CredentialSource.EnvironmentID) > 3 && o.CredentialSource.EnvironmentID[:3] == "aws" { - if awsVersion, err := strconv.Atoi(o.CredentialSource.EnvironmentID[3:]); err == nil { - if awsVersion != 1 { - return nil, fmt.Errorf("credentials: aws version '%d' is not supported in the current build", awsVersion) - } - - awsProvider := &awsSubjectProvider{ - EnvironmentID: o.CredentialSource.EnvironmentID, - RegionURL: o.CredentialSource.RegionURL, - RegionalCredVerificationURL: o.CredentialSource.RegionalCredVerificationURL, - CredVerificationURL: o.CredentialSource.URL, - TargetResource: o.Audience, - Client: o.Client, - logger: logger, - } - if o.CredentialSource.IMDSv2SessionTokenURL != "" { - awsProvider.IMDSv2SessionTokenURL = o.CredentialSource.IMDSv2SessionTokenURL - } - - return awsProvider, nil - } - } else if o.CredentialSource.File != "" { - return &fileSubjectProvider{File: o.CredentialSource.File, Format: o.CredentialSource.Format}, nil - } else if o.CredentialSource.URL != "" { - return &urlSubjectProvider{ - URL: o.CredentialSource.URL, - Headers: o.CredentialSource.Headers, - Format: o.CredentialSource.Format, - Client: o.Client, - Logger: logger, - }, nil - } else if o.CredentialSource.Executable != nil { - ec := o.CredentialSource.Executable - if ec.Command == "" { - return nil, errors.New("credentials: missing `command` field — executable command must be provided") - } - - execProvider := &executableSubjectProvider{} - execProvider.Command = ec.Command - if ec.TimeoutMillis == 0 { - execProvider.Timeout = executableDefaultTimeout - } else { - execProvider.Timeout = time.Duration(ec.TimeoutMillis) * time.Millisecond - if execProvider.Timeout < timeoutMinimum || execProvider.Timeout > timeoutMaximum { - return nil, fmt.Errorf("credentials: invalid `timeout_millis` field — executable timeout must be between %v and %v seconds", timeoutMinimum.Seconds(), timeoutMaximum.Seconds()) - } - } - execProvider.OutputFile = ec.OutputFile - execProvider.client = o.Client - execProvider.opts = o - execProvider.env = runtimeEnvironment{} - return execProvider, nil - } else if o.CredentialSource.Certificate != nil { - cert := o.CredentialSource.Certificate - if !cert.UseDefaultCertificateConfig && cert.CertificateConfigLocation == "" { - return nil, errors.New("credentials: \"certificate\" object must either specify a certificate_config_location or use_default_certificate_config should be true") - } - if cert.UseDefaultCertificateConfig && cert.CertificateConfigLocation != "" { - return nil, errors.New("credentials: \"certificate\" object cannot specify both a certificate_config_location and use_default_certificate_config=true") - } - return &x509Provider{}, nil - } - return nil, errors.New("credentials: unable to parse credential source") -} - -func getGoogHeaderValue(conf *Options, p subjectTokenProvider) string { - return fmt.Sprintf("gl-go/%s auth/%s google-byoid-sdk source/%s sa-impersonation/%t config-lifetime/%t", - goVersion(), - "unknown", - p.providerType(), - conf.ServiceAccountImpersonationURL != "", - conf.ServiceAccountImpersonationLifetimeSeconds != 0) -} diff --git a/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/file_provider.go b/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/file_provider.go deleted file mode 100644 index 8186939f..00000000 --- a/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/file_provider.go +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package externalaccount - -import ( - "bytes" - "context" - "encoding/json" - "errors" - "fmt" - "os" - - "cloud.google.com/go/auth/internal" - "cloud.google.com/go/auth/internal/credsfile" -) - -const ( - fileProviderType = "file" -) - -type fileSubjectProvider struct { - File string - Format *credsfile.Format -} - -func (sp *fileSubjectProvider) subjectToken(context.Context) (string, error) { - tokenFile, err := os.Open(sp.File) - if err != nil { - return "", fmt.Errorf("credentials: failed to open credential file %q: %w", sp.File, err) - } - defer tokenFile.Close() - tokenBytes, err := internal.ReadAll(tokenFile) - if err != nil { - return "", fmt.Errorf("credentials: failed to read credential file: %w", err) - } - tokenBytes = bytes.TrimSpace(tokenBytes) - - if sp.Format == nil { - return string(tokenBytes), nil - } - switch sp.Format.Type { - case fileTypeJSON: - jsonData := make(map[string]interface{}) - err = json.Unmarshal(tokenBytes, &jsonData) - if err != nil { - return "", fmt.Errorf("credentials: failed to unmarshal subject token file: %w", err) - } - val, ok := jsonData[sp.Format.SubjectTokenFieldName] - if !ok { - return "", errors.New("credentials: provided subject_token_field_name not found in credentials") - } - token, ok := val.(string) - if !ok { - return "", errors.New("credentials: improperly formatted subject token") - } - return token, nil - case fileTypeText: - return string(tokenBytes), nil - default: - return "", errors.New("credentials: invalid credential_source file format type: " + sp.Format.Type) - } -} - -func (sp *fileSubjectProvider) providerType() string { - return fileProviderType -} diff --git a/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/info.go b/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/info.go deleted file mode 100644 index 8e4b4379..00000000 --- a/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/info.go +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package externalaccount - -import ( - "runtime" - "strings" - "unicode" -) - -var ( - // version is a package internal global variable for testing purposes. - version = runtime.Version -) - -// versionUnknown is only used when the runtime version cannot be determined. -const versionUnknown = "UNKNOWN" - -// goVersion returns a Go runtime version derived from the runtime environment -// that is modified to be suitable for reporting in a header, meaning it has no -// whitespace. If it is unable to determine the Go runtime version, it returns -// versionUnknown. -func goVersion() string { - const develPrefix = "devel +" - - s := version() - if strings.HasPrefix(s, develPrefix) { - s = s[len(develPrefix):] - if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { - s = s[:p] - } - return s - } else if p := strings.IndexFunc(s, unicode.IsSpace); p >= 0 { - s = s[:p] - } - - notSemverRune := func(r rune) bool { - return !strings.ContainsRune("0123456789.", r) - } - - if strings.HasPrefix(s, "go1") { - s = s[2:] - var prerelease string - if p := strings.IndexFunc(s, notSemverRune); p >= 0 { - s, prerelease = s[:p], s[p:] - } - if strings.HasSuffix(s, ".") { - s += "0" - } else if strings.Count(s, ".") < 2 { - s += ".0" - } - if prerelease != "" { - // Some release candidates already have a dash in them. - if !strings.HasPrefix(prerelease, "-") { - prerelease = "-" + prerelease - } - s += prerelease - } - return s - } - return versionUnknown -} diff --git a/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/programmatic_provider.go b/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/programmatic_provider.go deleted file mode 100644 index be3c8735..00000000 --- a/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/programmatic_provider.go +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2024 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package externalaccount - -import "context" - -type programmaticProvider struct { - opts *RequestOptions - stp SubjectTokenProvider -} - -func (pp *programmaticProvider) providerType() string { - return programmaticProviderType -} - -func (pp *programmaticProvider) subjectToken(ctx context.Context) (string, error) { - return pp.stp.SubjectToken(ctx, pp.opts) -} diff --git a/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/url_provider.go b/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/url_provider.go deleted file mode 100644 index 754ecf4f..00000000 --- a/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/url_provider.go +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package externalaccount - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "log/slog" - "net/http" - - "cloud.google.com/go/auth/internal" - "cloud.google.com/go/auth/internal/credsfile" - "github.com/googleapis/gax-go/v2/internallog" -) - -const ( - fileTypeText = "text" - fileTypeJSON = "json" - urlProviderType = "url" - programmaticProviderType = "programmatic" - x509ProviderType = "x509" -) - -type urlSubjectProvider struct { - URL string - Headers map[string]string - Format *credsfile.Format - Client *http.Client - Logger *slog.Logger -} - -func (sp *urlSubjectProvider) subjectToken(ctx context.Context) (string, error) { - req, err := http.NewRequestWithContext(ctx, "GET", sp.URL, nil) - if err != nil { - return "", fmt.Errorf("credentials: HTTP request for URL-sourced credential failed: %w", err) - } - - for key, val := range sp.Headers { - req.Header.Add(key, val) - } - sp.Logger.DebugContext(ctx, "url subject token request", "request", internallog.HTTPRequest(req, nil)) - resp, body, err := internal.DoRequest(sp.Client, req) - if err != nil { - return "", fmt.Errorf("credentials: invalid response when retrieving subject token: %w", err) - } - sp.Logger.DebugContext(ctx, "url subject token response", "response", internallog.HTTPResponse(resp, body)) - if c := resp.StatusCode; c < http.StatusOK || c >= http.StatusMultipleChoices { - return "", fmt.Errorf("credentials: status code %d: %s", c, body) - } - - if sp.Format == nil { - return string(body), nil - } - switch sp.Format.Type { - case "json": - jsonData := make(map[string]interface{}) - err = json.Unmarshal(body, &jsonData) - if err != nil { - return "", fmt.Errorf("credentials: failed to unmarshal subject token file: %w", err) - } - val, ok := jsonData[sp.Format.SubjectTokenFieldName] - if !ok { - return "", errors.New("credentials: provided subject_token_field_name not found in credentials") - } - token, ok := val.(string) - if !ok { - return "", errors.New("credentials: improperly formatted subject token") - } - return token, nil - case fileTypeText: - return string(body), nil - default: - return "", errors.New("credentials: invalid credential_source file format type: " + sp.Format.Type) - } -} - -func (sp *urlSubjectProvider) providerType() string { - return urlProviderType -} diff --git a/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/x509_provider.go b/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/x509_provider.go deleted file mode 100644 index 115df588..00000000 --- a/vendor/cloud.google.com/go/auth/credentials/internal/externalaccount/x509_provider.go +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2024 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package externalaccount - -import ( - "context" - "crypto/tls" - "net/http" - "time" - - "cloud.google.com/go/auth/internal/transport/cert" -) - -// x509Provider implements the subjectTokenProvider type for -// x509 workload identity credentials. Because x509 credentials -// rely on an mTLS connection to represent the 3rd party identity -// rather than a subject token, this provider will always return -// an empty string when a subject token is requested by the external account -// token provider. -type x509Provider struct { -} - -func (xp *x509Provider) providerType() string { - return x509ProviderType -} - -func (xp *x509Provider) subjectToken(ctx context.Context) (string, error) { - return "", nil -} - -// createX509Client creates a new client that is configured with mTLS, using the -// certificate configuration specified in the credential source. -func createX509Client(certificateConfigLocation string) (*http.Client, error) { - certProvider, err := cert.NewWorkloadX509CertProvider(certificateConfigLocation) - if err != nil { - return nil, err - } - trans := http.DefaultTransport.(*http.Transport).Clone() - - trans.TLSClientConfig = &tls.Config{ - GetClientCertificate: certProvider, - } - - // Create a client with default settings plus the X509 workload cert and key. - client := &http.Client{ - Transport: trans, - Timeout: 30 * time.Second, - } - - return client, nil -} diff --git a/vendor/cloud.google.com/go/auth/credentials/internal/externalaccountuser/externalaccountuser.go b/vendor/cloud.google.com/go/auth/credentials/internal/externalaccountuser/externalaccountuser.go deleted file mode 100644 index ae39206e..00000000 --- a/vendor/cloud.google.com/go/auth/credentials/internal/externalaccountuser/externalaccountuser.go +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package externalaccountuser - -import ( - "context" - "errors" - "log/slog" - "net/http" - "time" - - "cloud.google.com/go/auth" - "cloud.google.com/go/auth/credentials/internal/stsexchange" - "cloud.google.com/go/auth/internal" - "github.com/googleapis/gax-go/v2/internallog" -) - -// Options stores the configuration for fetching tokens with external authorized -// user credentials. -type Options struct { - // Audience is the Secure Token Service (STS) audience which contains the - // resource name for the workforce pool and the provider identifier in that - // pool. - Audience string - // RefreshToken is the OAuth 2.0 refresh token. - RefreshToken string - // TokenURL is the STS token exchange endpoint for refresh. - TokenURL string - // TokenInfoURL is the STS endpoint URL for token introspection. Optional. - TokenInfoURL string - // ClientID is only required in conjunction with ClientSecret, as described - // below. - ClientID string - // ClientSecret is currently only required if token_info endpoint also needs - // to be called with the generated a cloud access token. When provided, STS - // will be called with additional basic authentication using client_id as - // username and client_secret as password. - ClientSecret string - // Scopes contains the desired scopes for the returned access token. - Scopes []string - - // Client for token request. - Client *http.Client - // Logger for logging. - Logger *slog.Logger -} - -func (c *Options) validate() bool { - return c.ClientID != "" && c.ClientSecret != "" && c.RefreshToken != "" && c.TokenURL != "" -} - -// NewTokenProvider returns a [cloud.google.com/go/auth.TokenProvider] -// configured with the provided options. -func NewTokenProvider(opts *Options) (auth.TokenProvider, error) { - if !opts.validate() { - return nil, errors.New("credentials: invalid external_account_authorized_user configuration") - } - - tp := &tokenProvider{ - o: opts, - } - return auth.NewCachedTokenProvider(tp, nil), nil -} - -type tokenProvider struct { - o *Options -} - -func (tp *tokenProvider) Token(ctx context.Context) (*auth.Token, error) { - opts := tp.o - - clientAuth := stsexchange.ClientAuthentication{ - AuthStyle: auth.StyleInHeader, - ClientID: opts.ClientID, - ClientSecret: opts.ClientSecret, - } - headers := make(http.Header) - headers.Set("Content-Type", "application/x-www-form-urlencoded") - stsResponse, err := stsexchange.RefreshAccessToken(ctx, &stsexchange.Options{ - Client: opts.Client, - Endpoint: opts.TokenURL, - RefreshToken: opts.RefreshToken, - Authentication: clientAuth, - Headers: headers, - Logger: internallog.New(tp.o.Logger), - }) - if err != nil { - return nil, err - } - if stsResponse.ExpiresIn < 0 { - return nil, errors.New("credentials: invalid expiry from security token service") - } - - // guarded by the wrapping with CachedTokenProvider - if stsResponse.RefreshToken != "" { - opts.RefreshToken = stsResponse.RefreshToken - } - return &auth.Token{ - Value: stsResponse.AccessToken, - Expiry: time.Now().UTC().Add(time.Duration(stsResponse.ExpiresIn) * time.Second), - Type: internal.TokenTypeBearer, - }, nil -} diff --git a/vendor/cloud.google.com/go/auth/credentials/internal/gdch/gdch.go b/vendor/cloud.google.com/go/auth/credentials/internal/gdch/gdch.go deleted file mode 100644 index c2d320fd..00000000 --- a/vendor/cloud.google.com/go/auth/credentials/internal/gdch/gdch.go +++ /dev/null @@ -1,191 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package gdch - -import ( - "context" - "crypto" - "crypto/tls" - "crypto/x509" - "encoding/json" - "errors" - "fmt" - "log/slog" - "net/http" - "net/url" - "os" - "strings" - "time" - - "cloud.google.com/go/auth" - "cloud.google.com/go/auth/internal" - "cloud.google.com/go/auth/internal/credsfile" - "cloud.google.com/go/auth/internal/jwt" - "github.com/googleapis/gax-go/v2/internallog" -) - -const ( - // GrantType is the grant type for the token request. - GrantType = "urn:ietf:params:oauth:token-type:token-exchange" - requestTokenType = "urn:ietf:params:oauth:token-type:access_token" - subjectTokenType = "urn:k8s:params:oauth:token-type:serviceaccount" -) - -var ( - gdchSupportFormatVersions map[string]bool = map[string]bool{ - "1": true, - } -) - -// Options for [NewTokenProvider]. -type Options struct { - STSAudience string - Client *http.Client - Logger *slog.Logger -} - -// NewTokenProvider returns a [cloud.google.com/go/auth.TokenProvider] from a -// GDCH cred file. -func NewTokenProvider(f *credsfile.GDCHServiceAccountFile, o *Options) (auth.TokenProvider, error) { - if !gdchSupportFormatVersions[f.FormatVersion] { - return nil, fmt.Errorf("credentials: unsupported gdch_service_account format %q", f.FormatVersion) - } - if o.STSAudience == "" { - return nil, errors.New("credentials: STSAudience must be set for the GDCH auth flows") - } - signer, err := internal.ParseKey([]byte(f.PrivateKey)) - if err != nil { - return nil, err - } - certPool, err := loadCertPool(f.CertPath) - if err != nil { - return nil, err - } - - tp := gdchProvider{ - serviceIdentity: fmt.Sprintf("system:serviceaccount:%s:%s", f.Project, f.Name), - tokenURL: f.TokenURL, - aud: o.STSAudience, - signer: signer, - pkID: f.PrivateKeyID, - certPool: certPool, - client: o.Client, - logger: internallog.New(o.Logger), - } - return tp, nil -} - -func loadCertPool(path string) (*x509.CertPool, error) { - pool := x509.NewCertPool() - pem, err := os.ReadFile(path) - if err != nil { - return nil, fmt.Errorf("credentials: failed to read certificate: %w", err) - } - pool.AppendCertsFromPEM(pem) - return pool, nil -} - -type gdchProvider struct { - serviceIdentity string - tokenURL string - aud string - signer crypto.Signer - pkID string - certPool *x509.CertPool - - client *http.Client - logger *slog.Logger -} - -func (g gdchProvider) Token(ctx context.Context) (*auth.Token, error) { - addCertToTransport(g.client, g.certPool) - iat := time.Now() - exp := iat.Add(time.Hour) - claims := jwt.Claims{ - Iss: g.serviceIdentity, - Sub: g.serviceIdentity, - Aud: g.tokenURL, - Iat: iat.Unix(), - Exp: exp.Unix(), - } - h := jwt.Header{ - Algorithm: jwt.HeaderAlgRSA256, - Type: jwt.HeaderType, - KeyID: string(g.pkID), - } - payload, err := jwt.EncodeJWS(&h, &claims, g.signer) - if err != nil { - return nil, err - } - v := url.Values{} - v.Set("grant_type", GrantType) - v.Set("audience", g.aud) - v.Set("requested_token_type", requestTokenType) - v.Set("subject_token", payload) - v.Set("subject_token_type", subjectTokenType) - - req, err := http.NewRequestWithContext(ctx, "POST", g.tokenURL, strings.NewReader(v.Encode())) - if err != nil { - return nil, err - } - req.Header.Set("Content-Type", "application/x-www-form-urlencoded") - g.logger.DebugContext(ctx, "gdch token request", "request", internallog.HTTPRequest(req, []byte(v.Encode()))) - resp, body, err := internal.DoRequest(g.client, req) - if err != nil { - return nil, fmt.Errorf("credentials: cannot fetch token: %w", err) - } - g.logger.DebugContext(ctx, "gdch token response", "response", internallog.HTTPResponse(resp, body)) - if c := resp.StatusCode; c < http.StatusOK || c > http.StatusMultipleChoices { - return nil, &auth.Error{ - Response: resp, - Body: body, - } - } - - var tokenRes struct { - AccessToken string `json:"access_token"` - TokenType string `json:"token_type"` - ExpiresIn int64 `json:"expires_in"` // relative seconds from now - } - if err := json.Unmarshal(body, &tokenRes); err != nil { - return nil, fmt.Errorf("credentials: cannot fetch token: %w", err) - } - token := &auth.Token{ - Value: tokenRes.AccessToken, - Type: tokenRes.TokenType, - } - raw := make(map[string]interface{}) - json.Unmarshal(body, &raw) // no error checks for optional fields - token.Metadata = raw - - if secs := tokenRes.ExpiresIn; secs > 0 { - token.Expiry = time.Now().Add(time.Duration(secs) * time.Second) - } - return token, nil -} - -// addCertToTransport makes a best effort attempt at adding in the cert info to -// the client. It tries to keep all configured transport settings if the -// underlying transport is an http.Transport. Or else it overwrites the -// transport with defaults adding in the certs. -func addCertToTransport(hc *http.Client, certPool *x509.CertPool) { - trans, ok := hc.Transport.(*http.Transport) - if !ok { - trans = http.DefaultTransport.(*http.Transport).Clone() - } - trans.TLSClientConfig = &tls.Config{ - RootCAs: certPool, - } -} diff --git a/vendor/cloud.google.com/go/auth/credentials/internal/impersonate/idtoken.go b/vendor/cloud.google.com/go/auth/credentials/internal/impersonate/idtoken.go deleted file mode 100644 index 705462c1..00000000 --- a/vendor/cloud.google.com/go/auth/credentials/internal/impersonate/idtoken.go +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright 2025 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package impersonate - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "log/slog" - "net/http" - "strings" - "time" - - "cloud.google.com/go/auth" - "cloud.google.com/go/auth/internal" - "github.com/googleapis/gax-go/v2/internallog" -) - -var ( - universeDomainPlaceholder = "UNIVERSE_DOMAIN" - iamCredentialsUniverseDomainEndpoint = "https://iamcredentials.UNIVERSE_DOMAIN" -) - -// IDTokenIAMOptions provides configuration for [IDTokenIAMOptions.Token]. -type IDTokenIAMOptions struct { - // Client is required. - Client *http.Client - // Logger is required. - Logger *slog.Logger - UniverseDomain auth.CredentialsPropertyProvider - ServiceAccountEmail string - GenerateIDTokenRequest -} - -// GenerateIDTokenRequest holds the request to the IAM generateIdToken RPC. -type GenerateIDTokenRequest struct { - Audience string `json:"audience"` - IncludeEmail bool `json:"includeEmail"` - // Delegates are the ordered, fully-qualified resource name for service - // accounts in a delegation chain. Each service account must be granted - // roles/iam.serviceAccountTokenCreator on the next service account in the - // chain. The delegates must have the following format: - // projects/-/serviceAccounts/{ACCOUNT_EMAIL_OR_UNIQUEID}. The - wildcard - // character is required; replacing it with a project ID is invalid. - // Optional. - Delegates []string `json:"delegates,omitempty"` -} - -// GenerateIDTokenResponse holds the response from the IAM generateIdToken RPC. -type GenerateIDTokenResponse struct { - Token string `json:"token"` -} - -// Token call IAM generateIdToken with the configuration provided in [IDTokenIAMOptions]. -func (o IDTokenIAMOptions) Token(ctx context.Context) (*auth.Token, error) { - universeDomain, err := o.UniverseDomain.GetProperty(ctx) - if err != nil { - return nil, err - } - endpoint := strings.Replace(iamCredentialsUniverseDomainEndpoint, universeDomainPlaceholder, universeDomain, 1) - url := fmt.Sprintf("%s/v1/%s:generateIdToken", endpoint, internal.FormatIAMServiceAccountResource(o.ServiceAccountEmail)) - - bodyBytes, err := json.Marshal(o.GenerateIDTokenRequest) - if err != nil { - return nil, fmt.Errorf("impersonate: unable to marshal request: %w", err) - } - - req, err := http.NewRequestWithContext(ctx, "POST", url, bytes.NewReader(bodyBytes)) - if err != nil { - return nil, fmt.Errorf("impersonate: unable to create request: %w", err) - } - req.Header.Set("Content-Type", "application/json") - o.Logger.DebugContext(ctx, "impersonated idtoken request", "request", internallog.HTTPRequest(req, bodyBytes)) - resp, body, err := internal.DoRequest(o.Client, req) - if err != nil { - return nil, fmt.Errorf("impersonate: unable to generate ID token: %w", err) - } - o.Logger.DebugContext(ctx, "impersonated idtoken response", "response", internallog.HTTPResponse(resp, body)) - if c := resp.StatusCode; c < 200 || c > 299 { - return nil, fmt.Errorf("impersonate: status code %d: %s", c, body) - } - - var tokenResp GenerateIDTokenResponse - if err := json.Unmarshal(body, &tokenResp); err != nil { - return nil, fmt.Errorf("impersonate: unable to parse response: %w", err) - } - return &auth.Token{ - Value: tokenResp.Token, - // Generated ID tokens are good for one hour. - Expiry: time.Now().Add(1 * time.Hour), - }, nil -} diff --git a/vendor/cloud.google.com/go/auth/credentials/internal/impersonate/impersonate.go b/vendor/cloud.google.com/go/auth/credentials/internal/impersonate/impersonate.go deleted file mode 100644 index b3a99261..00000000 --- a/vendor/cloud.google.com/go/auth/credentials/internal/impersonate/impersonate.go +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package impersonate - -import ( - "bytes" - "context" - "encoding/json" - "errors" - "fmt" - "log/slog" - "net/http" - "time" - - "cloud.google.com/go/auth" - "cloud.google.com/go/auth/internal" - "github.com/googleapis/gax-go/v2/internallog" -) - -const ( - defaultTokenLifetime = "3600s" - authHeaderKey = "Authorization" -) - -// generateAccesstokenReq is used for service account impersonation -type generateAccessTokenReq struct { - Delegates []string `json:"delegates,omitempty"` - Lifetime string `json:"lifetime,omitempty"` - Scope []string `json:"scope,omitempty"` -} - -type impersonateTokenResponse struct { - AccessToken string `json:"accessToken"` - ExpireTime string `json:"expireTime"` -} - -// NewTokenProvider uses a source credential, stored in Ts, to request an access token to the provided URL. -// Scopes can be defined when the access token is requested. -func NewTokenProvider(opts *Options) (auth.TokenProvider, error) { - if err := opts.validate(); err != nil { - return nil, err - } - return opts, nil -} - -// Options for [NewTokenProvider]. -type Options struct { - // Tp is the source credential used to generate a token on the - // impersonated service account. Required. - Tp auth.TokenProvider - - // URL is the endpoint to call to generate a token - // on behalf of the service account. Required. - URL string - // Scopes that the impersonated credential should have. Required. - Scopes []string - // Delegates are the service account email addresses in a delegation chain. - // Each service account must be granted roles/iam.serviceAccountTokenCreator - // on the next service account in the chain. Optional. - Delegates []string - // TokenLifetimeSeconds is the number of seconds the impersonation token will - // be valid for. Defaults to 1 hour if unset. Optional. - TokenLifetimeSeconds int - // Client configures the underlying client used to make network requests - // when fetching tokens. Required. - Client *http.Client - // Logger is used for debug logging. If provided, logging will be enabled - // at the loggers configured level. By default logging is disabled unless - // enabled by setting GOOGLE_SDK_GO_LOGGING_LEVEL in which case a default - // logger will be used. Optional. - Logger *slog.Logger -} - -func (o *Options) validate() error { - if o.Tp == nil { - return errors.New("credentials: missing required 'source_credentials' field in impersonated credentials") - } - if o.URL == "" { - return errors.New("credentials: missing required 'service_account_impersonation_url' field in impersonated credentials") - } - return nil -} - -// Token performs the exchange to get a temporary service account token to allow access to GCP. -func (o *Options) Token(ctx context.Context) (*auth.Token, error) { - logger := internallog.New(o.Logger) - lifetime := defaultTokenLifetime - if o.TokenLifetimeSeconds != 0 { - lifetime = fmt.Sprintf("%ds", o.TokenLifetimeSeconds) - } - reqBody := generateAccessTokenReq{ - Lifetime: lifetime, - Scope: o.Scopes, - Delegates: o.Delegates, - } - b, err := json.Marshal(reqBody) - if err != nil { - return nil, fmt.Errorf("credentials: unable to marshal request: %w", err) - } - req, err := http.NewRequestWithContext(ctx, "POST", o.URL, bytes.NewReader(b)) - if err != nil { - return nil, fmt.Errorf("credentials: unable to create impersonation request: %w", err) - } - req.Header.Set("Content-Type", "application/json") - if err := setAuthHeader(ctx, o.Tp, req); err != nil { - return nil, err - } - logger.DebugContext(ctx, "impersonated token request", "request", internallog.HTTPRequest(req, b)) - resp, body, err := internal.DoRequest(o.Client, req) - if err != nil { - return nil, fmt.Errorf("credentials: unable to generate access token: %w", err) - } - logger.DebugContext(ctx, "impersonated token response", "response", internallog.HTTPResponse(resp, body)) - if c := resp.StatusCode; c < http.StatusOK || c >= http.StatusMultipleChoices { - return nil, fmt.Errorf("credentials: status code %d: %s", c, body) - } - - var accessTokenResp impersonateTokenResponse - if err := json.Unmarshal(body, &accessTokenResp); err != nil { - return nil, fmt.Errorf("credentials: unable to parse response: %w", err) - } - expiry, err := time.Parse(time.RFC3339, accessTokenResp.ExpireTime) - if err != nil { - return nil, fmt.Errorf("credentials: unable to parse expiry: %w", err) - } - return &auth.Token{ - Value: accessTokenResp.AccessToken, - Expiry: expiry, - Type: internal.TokenTypeBearer, - }, nil -} - -func setAuthHeader(ctx context.Context, tp auth.TokenProvider, r *http.Request) error { - t, err := tp.Token(ctx) - if err != nil { - return err - } - typ := t.Type - if typ == "" { - typ = internal.TokenTypeBearer - } - r.Header.Set(authHeaderKey, typ+" "+t.Value) - return nil -} diff --git a/vendor/cloud.google.com/go/auth/credentials/internal/stsexchange/sts_exchange.go b/vendor/cloud.google.com/go/auth/credentials/internal/stsexchange/sts_exchange.go deleted file mode 100644 index e1d2b150..00000000 --- a/vendor/cloud.google.com/go/auth/credentials/internal/stsexchange/sts_exchange.go +++ /dev/null @@ -1,167 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package stsexchange - -import ( - "context" - "encoding/base64" - "encoding/json" - "fmt" - "log/slog" - "net/http" - "net/url" - "strconv" - "strings" - - "cloud.google.com/go/auth" - "cloud.google.com/go/auth/internal" - "github.com/googleapis/gax-go/v2/internallog" -) - -const ( - // GrantType for a sts exchange. - GrantType = "urn:ietf:params:oauth:grant-type:token-exchange" - // TokenType for a sts exchange. - TokenType = "urn:ietf:params:oauth:token-type:access_token" - - jwtTokenType = "urn:ietf:params:oauth:token-type:jwt" -) - -// Options stores the configuration for making an sts exchange request. -type Options struct { - Client *http.Client - Logger *slog.Logger - Endpoint string - Request *TokenRequest - Authentication ClientAuthentication - Headers http.Header - // ExtraOpts are optional fields marshalled into the `options` field of the - // request body. - ExtraOpts map[string]interface{} - RefreshToken string -} - -// RefreshAccessToken performs the token exchange using a refresh token flow. -func RefreshAccessToken(ctx context.Context, opts *Options) (*TokenResponse, error) { - data := url.Values{} - data.Set("grant_type", "refresh_token") - data.Set("refresh_token", opts.RefreshToken) - return doRequest(ctx, opts, data) -} - -// ExchangeToken performs an oauth2 token exchange with the provided endpoint. -func ExchangeToken(ctx context.Context, opts *Options) (*TokenResponse, error) { - data := url.Values{} - data.Set("audience", opts.Request.Audience) - data.Set("grant_type", GrantType) - data.Set("requested_token_type", TokenType) - data.Set("subject_token_type", opts.Request.SubjectTokenType) - data.Set("subject_token", opts.Request.SubjectToken) - data.Set("scope", strings.Join(opts.Request.Scope, " ")) - if opts.ExtraOpts != nil { - opts, err := json.Marshal(opts.ExtraOpts) - if err != nil { - return nil, fmt.Errorf("credentials: failed to marshal additional options: %w", err) - } - data.Set("options", string(opts)) - } - return doRequest(ctx, opts, data) -} - -func doRequest(ctx context.Context, opts *Options, data url.Values) (*TokenResponse, error) { - opts.Authentication.InjectAuthentication(data, opts.Headers) - encodedData := data.Encode() - logger := internallog.New(opts.Logger) - - req, err := http.NewRequestWithContext(ctx, "POST", opts.Endpoint, strings.NewReader(encodedData)) - if err != nil { - return nil, fmt.Errorf("credentials: failed to properly build http request: %w", err) - - } - for key, list := range opts.Headers { - for _, val := range list { - req.Header.Add(key, val) - } - } - req.Header.Set("Content-Length", strconv.Itoa(len(encodedData))) - - logger.DebugContext(ctx, "sts token request", "request", internallog.HTTPRequest(req, []byte(encodedData))) - resp, body, err := internal.DoRequest(opts.Client, req) - if err != nil { - return nil, fmt.Errorf("credentials: invalid response from Secure Token Server: %w", err) - } - logger.DebugContext(ctx, "sts token response", "response", internallog.HTTPResponse(resp, body)) - if c := resp.StatusCode; c < http.StatusOK || c > http.StatusMultipleChoices { - return nil, fmt.Errorf("credentials: status code %d: %s", c, body) - } - var stsResp TokenResponse - if err := json.Unmarshal(body, &stsResp); err != nil { - return nil, fmt.Errorf("credentials: failed to unmarshal response body from Secure Token Server: %w", err) - } - - return &stsResp, nil -} - -// TokenRequest contains fields necessary to make an oauth2 token -// exchange. -type TokenRequest struct { - ActingParty struct { - ActorToken string - ActorTokenType string - } - GrantType string - Resource string - Audience string - Scope []string - RequestedTokenType string - SubjectToken string - SubjectTokenType string -} - -// TokenResponse is used to decode the remote server response during -// an oauth2 token exchange. -type TokenResponse struct { - AccessToken string `json:"access_token"` - IssuedTokenType string `json:"issued_token_type"` - TokenType string `json:"token_type"` - ExpiresIn int `json:"expires_in"` - Scope string `json:"scope"` - RefreshToken string `json:"refresh_token"` -} - -// ClientAuthentication represents an OAuth client ID and secret and the -// mechanism for passing these credentials as stated in rfc6749#2.3.1. -type ClientAuthentication struct { - AuthStyle auth.Style - ClientID string - ClientSecret string -} - -// InjectAuthentication is used to add authentication to a Secure Token Service -// exchange request. It modifies either the passed url.Values or http.Header -// depending on the desired authentication format. -func (c *ClientAuthentication) InjectAuthentication(values url.Values, headers http.Header) { - if c.ClientID == "" || c.ClientSecret == "" || values == nil || headers == nil { - return - } - switch c.AuthStyle { - case auth.StyleInHeader: - plainHeader := c.ClientID + ":" + c.ClientSecret - headers.Set("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(plainHeader))) - default: - values.Set("client_id", c.ClientID) - values.Set("client_secret", c.ClientSecret) - } -} diff --git a/vendor/cloud.google.com/go/auth/credentials/selfsignedjwt.go b/vendor/cloud.google.com/go/auth/credentials/selfsignedjwt.go deleted file mode 100644 index 8d335cce..00000000 --- a/vendor/cloud.google.com/go/auth/credentials/selfsignedjwt.go +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package credentials - -import ( - "context" - "crypto" - "errors" - "fmt" - "log/slog" - "strings" - "time" - - "cloud.google.com/go/auth" - "cloud.google.com/go/auth/internal" - "cloud.google.com/go/auth/internal/credsfile" - "cloud.google.com/go/auth/internal/jwt" -) - -var ( - // for testing - now func() time.Time = time.Now -) - -// configureSelfSignedJWT uses the private key in the service account to create -// a JWT without making a network call. -func configureSelfSignedJWT(f *credsfile.ServiceAccountFile, opts *DetectOptions) (auth.TokenProvider, error) { - if len(opts.scopes()) == 0 && opts.Audience == "" { - return nil, errors.New("credentials: both scopes and audience are empty") - } - signer, err := internal.ParseKey([]byte(f.PrivateKey)) - if err != nil { - return nil, fmt.Errorf("credentials: could not parse key: %w", err) - } - return &selfSignedTokenProvider{ - email: f.ClientEmail, - audience: opts.Audience, - scopes: opts.scopes(), - signer: signer, - pkID: f.PrivateKeyID, - logger: opts.logger(), - }, nil -} - -type selfSignedTokenProvider struct { - email string - audience string - scopes []string - signer crypto.Signer - pkID string - logger *slog.Logger -} - -func (tp *selfSignedTokenProvider) Token(context.Context) (*auth.Token, error) { - iat := now() - exp := iat.Add(time.Hour) - scope := strings.Join(tp.scopes, " ") - c := &jwt.Claims{ - Iss: tp.email, - Sub: tp.email, - Aud: tp.audience, - Scope: scope, - Iat: iat.Unix(), - Exp: exp.Unix(), - } - h := &jwt.Header{ - Algorithm: jwt.HeaderAlgRSA256, - Type: jwt.HeaderType, - KeyID: string(tp.pkID), - } - tok, err := jwt.EncodeJWS(h, c, tp.signer) - if err != nil { - return nil, fmt.Errorf("credentials: could not encode JWT: %w", err) - } - tp.logger.Debug("created self-signed JWT", "token", tok) - return &auth.Token{Value: tok, Type: internal.TokenTypeBearer, Expiry: exp}, nil -} diff --git a/vendor/cloud.google.com/go/auth/httptransport/httptransport.go b/vendor/cloud.google.com/go/auth/httptransport/httptransport.go deleted file mode 100644 index 5758e85b..00000000 --- a/vendor/cloud.google.com/go/auth/httptransport/httptransport.go +++ /dev/null @@ -1,247 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package httptransport provides functionality for managing HTTP client -// connections to Google Cloud services. -package httptransport - -import ( - "crypto/tls" - "errors" - "fmt" - "log/slog" - "net/http" - - "cloud.google.com/go/auth" - detect "cloud.google.com/go/auth/credentials" - "cloud.google.com/go/auth/internal" - "cloud.google.com/go/auth/internal/transport" - "github.com/googleapis/gax-go/v2/internallog" -) - -// ClientCertProvider is a function that returns a TLS client certificate to be -// used when opening TLS connections. It follows the same semantics as -// [crypto/tls.Config.GetClientCertificate]. -type ClientCertProvider = func(*tls.CertificateRequestInfo) (*tls.Certificate, error) - -// Options used to configure a [net/http.Client] from [NewClient]. -type Options struct { - // DisableTelemetry disables default telemetry (OpenTelemetry). An example - // reason to do so would be to bind custom telemetry that overrides the - // defaults. - DisableTelemetry bool - // DisableAuthentication specifies that no authentication should be used. It - // is suitable only for testing and for accessing public resources, like - // public Google Cloud Storage buckets. - DisableAuthentication bool - // Headers are extra HTTP headers that will be appended to every outgoing - // request. - Headers http.Header - // BaseRoundTripper overrides the base transport used for serving requests. - // If specified ClientCertProvider is ignored. - BaseRoundTripper http.RoundTripper - // Endpoint overrides the default endpoint to be used for a service. - Endpoint string - // APIKey specifies an API key to be used as the basis for authentication. - // If set DetectOpts are ignored. - APIKey string - // Credentials used to add Authorization header to all requests. If set - // DetectOpts are ignored. - Credentials *auth.Credentials - // ClientCertProvider is a function that returns a TLS client certificate to - // be used when opening TLS connections. It follows the same semantics as - // crypto/tls.Config.GetClientCertificate. - ClientCertProvider ClientCertProvider - // DetectOpts configures settings for detect Application Default - // Credentials. - DetectOpts *detect.DetectOptions - // UniverseDomain is the default service domain for a given Cloud universe. - // The default value is "googleapis.com". This is the universe domain - // configured for the client, which will be compared to the universe domain - // that is separately configured for the credentials. - UniverseDomain string - // Logger is used for debug logging. If provided, logging will be enabled - // at the loggers configured level. By default logging is disabled unless - // enabled by setting GOOGLE_SDK_GO_LOGGING_LEVEL in which case a default - // logger will be used. Optional. - Logger *slog.Logger - - // InternalOptions are NOT meant to be set directly by consumers of this - // package, they should only be set by generated client code. - InternalOptions *InternalOptions -} - -func (o *Options) validate() error { - if o == nil { - return errors.New("httptransport: opts required to be non-nil") - } - if o.InternalOptions != nil && o.InternalOptions.SkipValidation { - return nil - } - hasCreds := o.APIKey != "" || - o.Credentials != nil || - (o.DetectOpts != nil && len(o.DetectOpts.CredentialsJSON) > 0) || - (o.DetectOpts != nil && o.DetectOpts.CredentialsFile != "") - if o.DisableAuthentication && hasCreds { - return errors.New("httptransport: DisableAuthentication is incompatible with options that set or detect credentials") - } - return nil -} - -// client returns the client a user set for the detect options or nil if one was -// not set. -func (o *Options) client() *http.Client { - if o.DetectOpts != nil && o.DetectOpts.Client != nil { - return o.DetectOpts.Client - } - return nil -} - -func (o *Options) logger() *slog.Logger { - return internallog.New(o.Logger) -} - -func (o *Options) resolveDetectOptions() *detect.DetectOptions { - io := o.InternalOptions - // soft-clone these so we are not updating a ref the user holds and may reuse - do := transport.CloneDetectOptions(o.DetectOpts) - - // If scoped JWTs are enabled user provided an aud, allow self-signed JWT. - if (io != nil && io.EnableJWTWithScope) || do.Audience != "" { - do.UseSelfSignedJWT = true - } - // Only default scopes if user did not also set an audience. - if len(do.Scopes) == 0 && do.Audience == "" && io != nil && len(io.DefaultScopes) > 0 { - do.Scopes = make([]string, len(io.DefaultScopes)) - copy(do.Scopes, io.DefaultScopes) - } - if len(do.Scopes) == 0 && do.Audience == "" && io != nil { - do.Audience = o.InternalOptions.DefaultAudience - } - if o.ClientCertProvider != nil { - tlsConfig := &tls.Config{ - GetClientCertificate: o.ClientCertProvider, - } - do.Client = transport.DefaultHTTPClientWithTLS(tlsConfig) - do.TokenURL = detect.GoogleMTLSTokenURL - } - if do.Logger == nil { - do.Logger = o.logger() - } - return do -} - -// InternalOptions are only meant to be set by generated client code. These are -// not meant to be set directly by consumers of this package. Configuration in -// this type is considered EXPERIMENTAL and may be removed at any time in the -// future without warning. -type InternalOptions struct { - // EnableJWTWithScope specifies if scope can be used with self-signed JWT. - EnableJWTWithScope bool - // DefaultAudience specifies a default audience to be used as the audience - // field ("aud") for the JWT token authentication. - DefaultAudience string - // DefaultEndpointTemplate combined with UniverseDomain specifies the - // default endpoint. - DefaultEndpointTemplate string - // DefaultMTLSEndpoint specifies the default mTLS endpoint. - DefaultMTLSEndpoint string - // DefaultScopes specifies the default OAuth2 scopes to be used for a - // service. - DefaultScopes []string - // SkipValidation bypasses validation on Options. It should only be used - // internally for clients that need more control over their transport. - SkipValidation bool - // SkipUniverseDomainValidation skips the verification that the universe - // domain configured for the client matches the universe domain configured - // for the credentials. It should only be used internally for clients that - // need more control over their transport. The default is false. - SkipUniverseDomainValidation bool -} - -// AddAuthorizationMiddleware adds a middleware to the provided client's -// transport that sets the Authorization header with the value produced by the -// provided [cloud.google.com/go/auth.Credentials]. An error is returned only -// if client or creds is nil. -// -// This function does not support setting a universe domain value on the client. -func AddAuthorizationMiddleware(client *http.Client, creds *auth.Credentials) error { - if client == nil || creds == nil { - return fmt.Errorf("httptransport: client and tp must not be nil") - } - base := client.Transport - if base == nil { - if dt, ok := http.DefaultTransport.(*http.Transport); ok { - base = dt.Clone() - } else { - // Directly reuse the DefaultTransport if the application has - // replaced it with an implementation of RoundTripper other than - // http.Transport. - base = http.DefaultTransport - } - } - client.Transport = &authTransport{ - creds: creds, - base: base, - } - return nil -} - -// NewClient returns a [net/http.Client] that can be used to communicate with a -// Google cloud service, configured with the provided [Options]. It -// automatically appends Authorization headers to all outgoing requests. -func NewClient(opts *Options) (*http.Client, error) { - if err := opts.validate(); err != nil { - return nil, err - } - - tOpts := &transport.Options{ - Endpoint: opts.Endpoint, - ClientCertProvider: opts.ClientCertProvider, - Client: opts.client(), - UniverseDomain: opts.UniverseDomain, - Logger: opts.logger(), - } - if io := opts.InternalOptions; io != nil { - tOpts.DefaultEndpointTemplate = io.DefaultEndpointTemplate - tOpts.DefaultMTLSEndpoint = io.DefaultMTLSEndpoint - } - clientCertProvider, dialTLSContext, err := transport.GetHTTPTransportConfig(tOpts) - if err != nil { - return nil, err - } - baseRoundTripper := opts.BaseRoundTripper - if baseRoundTripper == nil { - baseRoundTripper = defaultBaseTransport(clientCertProvider, dialTLSContext) - } - // Ensure the token exchange transport uses the same ClientCertProvider as the API transport. - opts.ClientCertProvider = clientCertProvider - trans, err := newTransport(baseRoundTripper, opts) - if err != nil { - return nil, err - } - return &http.Client{ - Transport: trans, - }, nil -} - -// SetAuthHeader uses the provided token to set the Authorization header on a -// request. If the token.Type is empty, the type is assumed to be Bearer. -func SetAuthHeader(token *auth.Token, req *http.Request) { - typ := token.Type - if typ == "" { - typ = internal.TokenTypeBearer - } - req.Header.Set("Authorization", typ+" "+token.Value) -} diff --git a/vendor/cloud.google.com/go/auth/httptransport/transport.go b/vendor/cloud.google.com/go/auth/httptransport/transport.go deleted file mode 100644 index ee215b6d..00000000 --- a/vendor/cloud.google.com/go/auth/httptransport/transport.go +++ /dev/null @@ -1,234 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package httptransport - -import ( - "context" - "crypto/tls" - "net" - "net/http" - "os" - "time" - - "cloud.google.com/go/auth" - "cloud.google.com/go/auth/credentials" - "cloud.google.com/go/auth/internal" - "cloud.google.com/go/auth/internal/transport" - "cloud.google.com/go/auth/internal/transport/cert" - "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" - "golang.org/x/net/http2" -) - -const ( - quotaProjectHeaderKey = "X-goog-user-project" -) - -func newTransport(base http.RoundTripper, opts *Options) (http.RoundTripper, error) { - var headers = opts.Headers - ht := &headerTransport{ - base: base, - headers: headers, - } - var trans http.RoundTripper = ht - trans = addOpenTelemetryTransport(trans, opts) - switch { - case opts.DisableAuthentication: - // Do nothing. - case opts.APIKey != "": - qp := internal.GetQuotaProject(nil, opts.Headers.Get(quotaProjectHeaderKey)) - if qp != "" { - if headers == nil { - headers = make(map[string][]string, 1) - } - headers.Set(quotaProjectHeaderKey, qp) - } - trans = &apiKeyTransport{ - Transport: trans, - Key: opts.APIKey, - } - default: - var creds *auth.Credentials - if opts.Credentials != nil { - creds = opts.Credentials - } else { - var err error - creds, err = credentials.DetectDefault(opts.resolveDetectOptions()) - if err != nil { - return nil, err - } - } - qp, err := creds.QuotaProjectID(context.Background()) - if err != nil { - return nil, err - } - if qp != "" { - if headers == nil { - headers = make(map[string][]string, 1) - } - // Don't overwrite user specified quota - if v := headers.Get(quotaProjectHeaderKey); v == "" { - headers.Set(quotaProjectHeaderKey, qp) - } - } - var skipUD bool - if iOpts := opts.InternalOptions; iOpts != nil { - skipUD = iOpts.SkipUniverseDomainValidation - } - creds.TokenProvider = auth.NewCachedTokenProvider(creds.TokenProvider, nil) - trans = &authTransport{ - base: trans, - creds: creds, - clientUniverseDomain: opts.UniverseDomain, - skipUniverseDomainValidation: skipUD, - } - } - return trans, nil -} - -// defaultBaseTransport returns the base HTTP transport. -// On App Engine, this is urlfetch.Transport. -// Otherwise, use a default transport, taking most defaults from -// http.DefaultTransport. -// If TLSCertificate is available, set TLSClientConfig as well. -func defaultBaseTransport(clientCertSource cert.Provider, dialTLSContext func(context.Context, string, string) (net.Conn, error)) http.RoundTripper { - defaultTransport, ok := http.DefaultTransport.(*http.Transport) - if !ok { - defaultTransport = transport.BaseTransport() - } - trans := defaultTransport.Clone() - trans.MaxIdleConnsPerHost = 100 - - if clientCertSource != nil { - trans.TLSClientConfig = &tls.Config{ - GetClientCertificate: clientCertSource, - } - } - if dialTLSContext != nil { - // If DialTLSContext is set, TLSClientConfig wil be ignored - trans.DialTLSContext = dialTLSContext - } - - // Configures the ReadIdleTimeout HTTP/2 option for the - // transport. This allows broken idle connections to be pruned more quickly, - // preventing the client from attempting to re-use connections that will no - // longer work. - http2Trans, err := http2.ConfigureTransports(trans) - if err == nil { - http2Trans.ReadIdleTimeout = time.Second * 31 - } - - return trans -} - -type apiKeyTransport struct { - // Key is the API Key to set on requests. - Key string - // Transport is the underlying HTTP transport. - // If nil, http.DefaultTransport is used. - Transport http.RoundTripper -} - -func (t *apiKeyTransport) RoundTrip(req *http.Request) (*http.Response, error) { - newReq := *req - args := newReq.URL.Query() - args.Set("key", t.Key) - newReq.URL.RawQuery = args.Encode() - return t.Transport.RoundTrip(&newReq) -} - -type headerTransport struct { - headers http.Header - base http.RoundTripper -} - -func (t *headerTransport) RoundTrip(req *http.Request) (*http.Response, error) { - rt := t.base - newReq := *req - newReq.Header = make(http.Header) - for k, vv := range req.Header { - newReq.Header[k] = vv - } - - for k, v := range t.headers { - newReq.Header[k] = v - } - - return rt.RoundTrip(&newReq) -} - -func addOpenTelemetryTransport(trans http.RoundTripper, opts *Options) http.RoundTripper { - if opts.DisableTelemetry { - return trans - } - return otelhttp.NewTransport(trans) -} - -type authTransport struct { - creds *auth.Credentials - base http.RoundTripper - clientUniverseDomain string - skipUniverseDomainValidation bool -} - -// getClientUniverseDomain returns the default service domain for a given Cloud -// universe, with the following precedence: -// -// 1. A non-empty option.WithUniverseDomain or similar client option. -// 2. A non-empty environment variable GOOGLE_CLOUD_UNIVERSE_DOMAIN. -// 3. The default value "googleapis.com". -// -// This is the universe domain configured for the client, which will be compared -// to the universe domain that is separately configured for the credentials. -func (t *authTransport) getClientUniverseDomain() string { - if t.clientUniverseDomain != "" { - return t.clientUniverseDomain - } - if envUD := os.Getenv(internal.UniverseDomainEnvVar); envUD != "" { - return envUD - } - return internal.DefaultUniverseDomain -} - -// RoundTrip authorizes and authenticates the request with an -// access token from Transport's Source. Per the RoundTripper contract we must -// not modify the initial request, so we clone it, and we must close the body -// on any errors that happens during our token logic. -func (t *authTransport) RoundTrip(req *http.Request) (*http.Response, error) { - reqBodyClosed := false - if req.Body != nil { - defer func() { - if !reqBodyClosed { - req.Body.Close() - } - }() - } - token, err := t.creds.Token(req.Context()) - if err != nil { - return nil, err - } - if !t.skipUniverseDomainValidation && token.MetadataString("auth.google.tokenSource") != "compute-metadata" { - credentialsUniverseDomain, err := t.creds.UniverseDomain(req.Context()) - if err != nil { - return nil, err - } - if err := transport.ValidateUniverseDomain(t.getClientUniverseDomain(), credentialsUniverseDomain); err != nil { - return nil, err - } - } - req2 := req.Clone(req.Context()) - SetAuthHeader(token, req2) - reqBodyClosed = true - return t.base.RoundTrip(req2) -} diff --git a/vendor/cloud.google.com/go/auth/internal/credsfile/credsfile.go b/vendor/cloud.google.com/go/auth/internal/credsfile/credsfile.go deleted file mode 100644 index 9cd4bed6..00000000 --- a/vendor/cloud.google.com/go/auth/internal/credsfile/credsfile.go +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package credsfile is meant to hide implementation details from the pubic -// surface of the detect package. It should not import any other packages in -// this module. It is located under the main internal package so other -// sub-packages can use these parsed types as well. -package credsfile - -import ( - "os" - "os/user" - "path/filepath" - "runtime" -) - -const ( - // GoogleAppCredsEnvVar is the environment variable for setting the - // application default credentials. - GoogleAppCredsEnvVar = "GOOGLE_APPLICATION_CREDENTIALS" - userCredsFilename = "application_default_credentials.json" -) - -// CredentialType represents different credential filetypes Google credentials -// can be. -type CredentialType int - -const ( - // UnknownCredType is an unidentified file type. - UnknownCredType CredentialType = iota - // UserCredentialsKey represents a user creds file type. - UserCredentialsKey - // ServiceAccountKey represents a service account file type. - ServiceAccountKey - // ImpersonatedServiceAccountKey represents a impersonated service account - // file type. - ImpersonatedServiceAccountKey - // ExternalAccountKey represents a external account file type. - ExternalAccountKey - // GDCHServiceAccountKey represents a GDCH file type. - GDCHServiceAccountKey - // ExternalAccountAuthorizedUserKey represents a external account authorized - // user file type. - ExternalAccountAuthorizedUserKey -) - -// parseCredentialType returns the associated filetype based on the parsed -// typeString provided. -func parseCredentialType(typeString string) CredentialType { - switch typeString { - case "service_account": - return ServiceAccountKey - case "authorized_user": - return UserCredentialsKey - case "impersonated_service_account": - return ImpersonatedServiceAccountKey - case "external_account": - return ExternalAccountKey - case "external_account_authorized_user": - return ExternalAccountAuthorizedUserKey - case "gdch_service_account": - return GDCHServiceAccountKey - default: - return UnknownCredType - } -} - -// GetFileNameFromEnv returns the override if provided or detects a filename -// from the environment. -func GetFileNameFromEnv(override string) string { - if override != "" { - return override - } - return os.Getenv(GoogleAppCredsEnvVar) -} - -// GetWellKnownFileName tries to locate the filepath for the user credential -// file based on the environment. -func GetWellKnownFileName() string { - if runtime.GOOS == "windows" { - return filepath.Join(os.Getenv("APPDATA"), "gcloud", userCredsFilename) - } - return filepath.Join(guessUnixHomeDir(), ".config", "gcloud", userCredsFilename) -} - -// guessUnixHomeDir default to checking for HOME, but not all unix systems have -// this set, do have a fallback. -func guessUnixHomeDir() string { - if v := os.Getenv("HOME"); v != "" { - return v - } - if u, err := user.Current(); err == nil { - return u.HomeDir - } - return "" -} diff --git a/vendor/cloud.google.com/go/auth/internal/credsfile/filetype.go b/vendor/cloud.google.com/go/auth/internal/credsfile/filetype.go deleted file mode 100644 index 3be6e5bb..00000000 --- a/vendor/cloud.google.com/go/auth/internal/credsfile/filetype.go +++ /dev/null @@ -1,157 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package credsfile - -import ( - "encoding/json" -) - -// Config3LO is the internals of a client creds file. -type Config3LO struct { - ClientID string `json:"client_id"` - ClientSecret string `json:"client_secret"` - RedirectURIs []string `json:"redirect_uris"` - AuthURI string `json:"auth_uri"` - TokenURI string `json:"token_uri"` -} - -// ClientCredentialsFile representation. -type ClientCredentialsFile struct { - Web *Config3LO `json:"web"` - Installed *Config3LO `json:"installed"` - UniverseDomain string `json:"universe_domain"` -} - -// ServiceAccountFile representation. -type ServiceAccountFile struct { - Type string `json:"type"` - ProjectID string `json:"project_id"` - PrivateKeyID string `json:"private_key_id"` - PrivateKey string `json:"private_key"` - ClientEmail string `json:"client_email"` - ClientID string `json:"client_id"` - AuthURL string `json:"auth_uri"` - TokenURL string `json:"token_uri"` - UniverseDomain string `json:"universe_domain"` -} - -// UserCredentialsFile representation. -type UserCredentialsFile struct { - Type string `json:"type"` - ClientID string `json:"client_id"` - ClientSecret string `json:"client_secret"` - QuotaProjectID string `json:"quota_project_id"` - RefreshToken string `json:"refresh_token"` - UniverseDomain string `json:"universe_domain"` -} - -// ExternalAccountFile representation. -type ExternalAccountFile struct { - Type string `json:"type"` - ClientID string `json:"client_id"` - ClientSecret string `json:"client_secret"` - Audience string `json:"audience"` - SubjectTokenType string `json:"subject_token_type"` - ServiceAccountImpersonationURL string `json:"service_account_impersonation_url"` - TokenURL string `json:"token_url"` - CredentialSource *CredentialSource `json:"credential_source,omitempty"` - TokenInfoURL string `json:"token_info_url"` - ServiceAccountImpersonation *ServiceAccountImpersonationInfo `json:"service_account_impersonation,omitempty"` - QuotaProjectID string `json:"quota_project_id"` - WorkforcePoolUserProject string `json:"workforce_pool_user_project"` - UniverseDomain string `json:"universe_domain"` -} - -// ExternalAccountAuthorizedUserFile representation. -type ExternalAccountAuthorizedUserFile struct { - Type string `json:"type"` - Audience string `json:"audience"` - ClientID string `json:"client_id"` - ClientSecret string `json:"client_secret"` - RefreshToken string `json:"refresh_token"` - TokenURL string `json:"token_url"` - TokenInfoURL string `json:"token_info_url"` - RevokeURL string `json:"revoke_url"` - QuotaProjectID string `json:"quota_project_id"` - UniverseDomain string `json:"universe_domain"` -} - -// CredentialSource stores the information necessary to retrieve the credentials for the STS exchange. -// -// One field amongst File, URL, Certificate, and Executable should be filled, depending on the kind of credential in question. -// The EnvironmentID should start with AWS if being used for an AWS credential. -type CredentialSource struct { - File string `json:"file"` - URL string `json:"url"` - Headers map[string]string `json:"headers"` - Executable *ExecutableConfig `json:"executable,omitempty"` - Certificate *CertificateConfig `json:"certificate"` - EnvironmentID string `json:"environment_id"` // TODO: Make type for this - RegionURL string `json:"region_url"` - RegionalCredVerificationURL string `json:"regional_cred_verification_url"` - CredVerificationURL string `json:"cred_verification_url"` - IMDSv2SessionTokenURL string `json:"imdsv2_session_token_url"` - Format *Format `json:"format,omitempty"` -} - -// Format describes the format of a [CredentialSource]. -type Format struct { - // Type is either "text" or "json". When not provided "text" type is assumed. - Type string `json:"type"` - // SubjectTokenFieldName is only required for JSON format. This would be "access_token" for azure. - SubjectTokenFieldName string `json:"subject_token_field_name"` -} - -// ExecutableConfig represents the command to run for an executable -// [CredentialSource]. -type ExecutableConfig struct { - Command string `json:"command"` - TimeoutMillis int `json:"timeout_millis"` - OutputFile string `json:"output_file"` -} - -// CertificateConfig represents the options used to set up X509 based workload -// [CredentialSource] -type CertificateConfig struct { - UseDefaultCertificateConfig bool `json:"use_default_certificate_config"` - CertificateConfigLocation string `json:"certificate_config_location"` -} - -// ServiceAccountImpersonationInfo has impersonation configuration. -type ServiceAccountImpersonationInfo struct { - TokenLifetimeSeconds int `json:"token_lifetime_seconds"` -} - -// ImpersonatedServiceAccountFile representation. -type ImpersonatedServiceAccountFile struct { - Type string `json:"type"` - ServiceAccountImpersonationURL string `json:"service_account_impersonation_url"` - Delegates []string `json:"delegates"` - CredSource json.RawMessage `json:"source_credentials"` - UniverseDomain string `json:"universe_domain"` -} - -// GDCHServiceAccountFile represents the Google Distributed Cloud Hosted (GDCH) service identity file. -type GDCHServiceAccountFile struct { - Type string `json:"type"` - FormatVersion string `json:"format_version"` - Project string `json:"project"` - Name string `json:"name"` - CertPath string `json:"ca_cert_path"` - PrivateKeyID string `json:"private_key_id"` - PrivateKey string `json:"private_key"` - TokenURL string `json:"token_uri"` - UniverseDomain string `json:"universe_domain"` -} diff --git a/vendor/cloud.google.com/go/auth/internal/credsfile/parse.go b/vendor/cloud.google.com/go/auth/internal/credsfile/parse.go deleted file mode 100644 index a02b9f5d..00000000 --- a/vendor/cloud.google.com/go/auth/internal/credsfile/parse.go +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package credsfile - -import ( - "encoding/json" -) - -// ParseServiceAccount parses bytes into a [ServiceAccountFile]. -func ParseServiceAccount(b []byte) (*ServiceAccountFile, error) { - var f *ServiceAccountFile - if err := json.Unmarshal(b, &f); err != nil { - return nil, err - } - return f, nil -} - -// ParseClientCredentials parses bytes into a -// [credsfile.ClientCredentialsFile]. -func ParseClientCredentials(b []byte) (*ClientCredentialsFile, error) { - var f *ClientCredentialsFile - if err := json.Unmarshal(b, &f); err != nil { - return nil, err - } - return f, nil -} - -// ParseUserCredentials parses bytes into a [UserCredentialsFile]. -func ParseUserCredentials(b []byte) (*UserCredentialsFile, error) { - var f *UserCredentialsFile - if err := json.Unmarshal(b, &f); err != nil { - return nil, err - } - return f, nil -} - -// ParseExternalAccount parses bytes into a [ExternalAccountFile]. -func ParseExternalAccount(b []byte) (*ExternalAccountFile, error) { - var f *ExternalAccountFile - if err := json.Unmarshal(b, &f); err != nil { - return nil, err - } - return f, nil -} - -// ParseExternalAccountAuthorizedUser parses bytes into a -// [ExternalAccountAuthorizedUserFile]. -func ParseExternalAccountAuthorizedUser(b []byte) (*ExternalAccountAuthorizedUserFile, error) { - var f *ExternalAccountAuthorizedUserFile - if err := json.Unmarshal(b, &f); err != nil { - return nil, err - } - return f, nil -} - -// ParseImpersonatedServiceAccount parses bytes into a -// [ImpersonatedServiceAccountFile]. -func ParseImpersonatedServiceAccount(b []byte) (*ImpersonatedServiceAccountFile, error) { - var f *ImpersonatedServiceAccountFile - if err := json.Unmarshal(b, &f); err != nil { - return nil, err - } - return f, nil -} - -// ParseGDCHServiceAccount parses bytes into a [GDCHServiceAccountFile]. -func ParseGDCHServiceAccount(b []byte) (*GDCHServiceAccountFile, error) { - var f *GDCHServiceAccountFile - if err := json.Unmarshal(b, &f); err != nil { - return nil, err - } - return f, nil -} - -type fileTypeChecker struct { - Type string `json:"type"` -} - -// ParseFileType determines the [CredentialType] based on bytes provided. -func ParseFileType(b []byte) (CredentialType, error) { - var f fileTypeChecker - if err := json.Unmarshal(b, &f); err != nil { - return 0, err - } - return parseCredentialType(f.Type), nil -} diff --git a/vendor/cloud.google.com/go/auth/internal/internal.go b/vendor/cloud.google.com/go/auth/internal/internal.go deleted file mode 100644 index 6a8eab6e..00000000 --- a/vendor/cloud.google.com/go/auth/internal/internal.go +++ /dev/null @@ -1,225 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package internal - -import ( - "context" - "crypto" - "crypto/x509" - "encoding/json" - "encoding/pem" - "errors" - "fmt" - "io" - "net/http" - "os" - "sync" - "time" - - "cloud.google.com/go/compute/metadata" -) - -const ( - // TokenTypeBearer is the auth header prefix for bearer tokens. - TokenTypeBearer = "Bearer" - - // QuotaProjectEnvVar is the environment variable for setting the quota - // project. - QuotaProjectEnvVar = "GOOGLE_CLOUD_QUOTA_PROJECT" - // UniverseDomainEnvVar is the environment variable for setting the default - // service domain for a given Cloud universe. - UniverseDomainEnvVar = "GOOGLE_CLOUD_UNIVERSE_DOMAIN" - projectEnvVar = "GOOGLE_CLOUD_PROJECT" - maxBodySize = 1 << 20 - - // DefaultUniverseDomain is the default value for universe domain. - // Universe domain is the default service domain for a given Cloud universe. - DefaultUniverseDomain = "googleapis.com" -) - -type clonableTransport interface { - Clone() *http.Transport -} - -// DefaultClient returns an [http.Client] with some defaults set. If -// the current [http.DefaultTransport] is a [clonableTransport], as -// is the case for an [*http.Transport], the clone will be used. -// Otherwise the [http.DefaultTransport] is used directly. -func DefaultClient() *http.Client { - if transport, ok := http.DefaultTransport.(clonableTransport); ok { - return &http.Client{ - Transport: transport.Clone(), - Timeout: 30 * time.Second, - } - } - - return &http.Client{ - Transport: http.DefaultTransport, - Timeout: 30 * time.Second, - } -} - -// ParseKey converts the binary contents of a private key file -// to an crypto.Signer. It detects whether the private key is in a -// PEM container or not. If so, it extracts the the private key -// from PEM container before conversion. It only supports PEM -// containers with no passphrase. -func ParseKey(key []byte) (crypto.Signer, error) { - block, _ := pem.Decode(key) - if block != nil { - key = block.Bytes - } - var parsedKey crypto.PrivateKey - var err error - parsedKey, err = x509.ParsePKCS8PrivateKey(key) - if err != nil { - parsedKey, err = x509.ParsePKCS1PrivateKey(key) - if err != nil { - return nil, fmt.Errorf("private key should be a PEM or plain PKCS1 or PKCS8: %w", err) - } - } - parsed, ok := parsedKey.(crypto.Signer) - if !ok { - return nil, errors.New("private key is not a signer") - } - return parsed, nil -} - -// GetQuotaProject retrieves quota project with precedence being: override, -// environment variable, creds json file. -func GetQuotaProject(b []byte, override string) string { - if override != "" { - return override - } - if env := os.Getenv(QuotaProjectEnvVar); env != "" { - return env - } - if b == nil { - return "" - } - var v struct { - QuotaProject string `json:"quota_project_id"` - } - if err := json.Unmarshal(b, &v); err != nil { - return "" - } - return v.QuotaProject -} - -// GetProjectID retrieves project with precedence being: override, -// environment variable, creds json file. -func GetProjectID(b []byte, override string) string { - if override != "" { - return override - } - if env := os.Getenv(projectEnvVar); env != "" { - return env - } - if b == nil { - return "" - } - var v struct { - ProjectID string `json:"project_id"` // standard service account key - Project string `json:"project"` // gdch key - } - if err := json.Unmarshal(b, &v); err != nil { - return "" - } - if v.ProjectID != "" { - return v.ProjectID - } - return v.Project -} - -// DoRequest executes the provided req with the client. It reads the response -// body, closes it, and returns it. -func DoRequest(client *http.Client, req *http.Request) (*http.Response, []byte, error) { - resp, err := client.Do(req) - if err != nil { - return nil, nil, err - } - defer resp.Body.Close() - body, err := ReadAll(io.LimitReader(resp.Body, maxBodySize)) - if err != nil { - return nil, nil, err - } - return resp, body, nil -} - -// ReadAll consumes the whole reader and safely reads the content of its body -// with some overflow protection. -func ReadAll(r io.Reader) ([]byte, error) { - return io.ReadAll(io.LimitReader(r, maxBodySize)) -} - -// StaticCredentialsProperty is a helper for creating static credentials -// properties. -func StaticCredentialsProperty(s string) StaticProperty { - return StaticProperty(s) -} - -// StaticProperty always returns that value of the underlying string. -type StaticProperty string - -// GetProperty loads the properly value provided the given context. -func (p StaticProperty) GetProperty(context.Context) (string, error) { - return string(p), nil -} - -// ComputeUniverseDomainProvider fetches the credentials universe domain from -// the google cloud metadata service. -type ComputeUniverseDomainProvider struct { - MetadataClient *metadata.Client - universeDomainOnce sync.Once - universeDomain string - universeDomainErr error -} - -// GetProperty fetches the credentials universe domain from the google cloud -// metadata service. -func (c *ComputeUniverseDomainProvider) GetProperty(ctx context.Context) (string, error) { - c.universeDomainOnce.Do(func() { - c.universeDomain, c.universeDomainErr = getMetadataUniverseDomain(ctx, c.MetadataClient) - }) - if c.universeDomainErr != nil { - return "", c.universeDomainErr - } - return c.universeDomain, nil -} - -// httpGetMetadataUniverseDomain is a package var for unit test substitution. -var httpGetMetadataUniverseDomain = func(ctx context.Context, client *metadata.Client) (string, error) { - ctx, cancel := context.WithTimeout(ctx, 1*time.Second) - defer cancel() - return client.GetWithContext(ctx, "universe/universe-domain") -} - -func getMetadataUniverseDomain(ctx context.Context, client *metadata.Client) (string, error) { - universeDomain, err := httpGetMetadataUniverseDomain(ctx, client) - if err == nil { - return universeDomain, nil - } - if _, ok := err.(metadata.NotDefinedError); ok { - // http.StatusNotFound (404) - return DefaultUniverseDomain, nil - } - return "", err -} - -// FormatIAMServiceAccountResource sets a service account name in an IAM resource -// name. -func FormatIAMServiceAccountResource(name string) string { - return fmt.Sprintf("projects/-/serviceAccounts/%s", name) -} diff --git a/vendor/cloud.google.com/go/auth/internal/jwt/jwt.go b/vendor/cloud.google.com/go/auth/internal/jwt/jwt.go deleted file mode 100644 index 9bd55f51..00000000 --- a/vendor/cloud.google.com/go/auth/internal/jwt/jwt.go +++ /dev/null @@ -1,171 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package jwt - -import ( - "bytes" - "crypto" - "crypto/rand" - "crypto/rsa" - "crypto/sha256" - "encoding/base64" - "encoding/json" - "errors" - "fmt" - "strings" - "time" -) - -const ( - // HeaderAlgRSA256 is the RS256 [Header.Algorithm]. - HeaderAlgRSA256 = "RS256" - // HeaderAlgES256 is the ES256 [Header.Algorithm]. - HeaderAlgES256 = "ES256" - // HeaderType is the standard [Header.Type]. - HeaderType = "JWT" -) - -// Header represents a JWT header. -type Header struct { - Algorithm string `json:"alg"` - Type string `json:"typ"` - KeyID string `json:"kid"` -} - -func (h *Header) encode() (string, error) { - b, err := json.Marshal(h) - if err != nil { - return "", err - } - return base64.RawURLEncoding.EncodeToString(b), nil -} - -// Claims represents the claims set of a JWT. -type Claims struct { - // Iss is the issuer JWT claim. - Iss string `json:"iss"` - // Scope is the scope JWT claim. - Scope string `json:"scope,omitempty"` - // Exp is the expiry JWT claim. If unset, default is in one hour from now. - Exp int64 `json:"exp"` - // Iat is the subject issued at claim. If unset, default is now. - Iat int64 `json:"iat"` - // Aud is the audience JWT claim. Optional. - Aud string `json:"aud"` - // Sub is the subject JWT claim. Optional. - Sub string `json:"sub,omitempty"` - // AdditionalClaims contains any additional non-standard JWT claims. Optional. - AdditionalClaims map[string]interface{} `json:"-"` -} - -func (c *Claims) encode() (string, error) { - // Compensate for skew - now := time.Now().Add(-10 * time.Second) - if c.Iat == 0 { - c.Iat = now.Unix() - } - if c.Exp == 0 { - c.Exp = now.Add(time.Hour).Unix() - } - if c.Exp < c.Iat { - return "", fmt.Errorf("jwt: invalid Exp = %d; must be later than Iat = %d", c.Exp, c.Iat) - } - - b, err := json.Marshal(c) - if err != nil { - return "", err - } - - if len(c.AdditionalClaims) == 0 { - return base64.RawURLEncoding.EncodeToString(b), nil - } - - // Marshal private claim set and then append it to b. - prv, err := json.Marshal(c.AdditionalClaims) - if err != nil { - return "", fmt.Errorf("invalid map of additional claims %v: %w", c.AdditionalClaims, err) - } - - // Concatenate public and private claim JSON objects. - if !bytes.HasSuffix(b, []byte{'}'}) { - return "", fmt.Errorf("invalid JSON %s", b) - } - if !bytes.HasPrefix(prv, []byte{'{'}) { - return "", fmt.Errorf("invalid JSON %s", prv) - } - b[len(b)-1] = ',' // Replace closing curly brace with a comma. - b = append(b, prv[1:]...) // Append private claims. - return base64.RawURLEncoding.EncodeToString(b), nil -} - -// EncodeJWS encodes the data using the provided key as a JSON web signature. -func EncodeJWS(header *Header, c *Claims, signer crypto.Signer) (string, error) { - head, err := header.encode() - if err != nil { - return "", err - } - claims, err := c.encode() - if err != nil { - return "", err - } - ss := fmt.Sprintf("%s.%s", head, claims) - h := sha256.New() - h.Write([]byte(ss)) - sig, err := signer.Sign(rand.Reader, h.Sum(nil), crypto.SHA256) - if err != nil { - return "", err - } - return fmt.Sprintf("%s.%s", ss, base64.RawURLEncoding.EncodeToString(sig)), nil -} - -// DecodeJWS decodes a claim set from a JWS payload. -func DecodeJWS(payload string) (*Claims, error) { - // decode returned id token to get expiry - s := strings.Split(payload, ".") - if len(s) < 2 { - return nil, errors.New("invalid token received") - } - decoded, err := base64.RawURLEncoding.DecodeString(s[1]) - if err != nil { - return nil, err - } - c := &Claims{} - if err := json.NewDecoder(bytes.NewBuffer(decoded)).Decode(c); err != nil { - return nil, err - } - if err := json.NewDecoder(bytes.NewBuffer(decoded)).Decode(&c.AdditionalClaims); err != nil { - return nil, err - } - return c, err -} - -// VerifyJWS tests whether the provided JWT token's signature was produced by -// the private key associated with the provided public key. -func VerifyJWS(token string, key *rsa.PublicKey) error { - parts := strings.Split(token, ".") - if len(parts) != 3 { - return errors.New("jwt: invalid token received, token must have 3 parts") - } - - signedContent := parts[0] + "." + parts[1] - signatureString, err := base64.RawURLEncoding.DecodeString(parts[2]) - if err != nil { - return err - } - - h := sha256.New() - h.Write([]byte(signedContent)) - return rsa.VerifyPKCS1v15(key, crypto.SHA256, h.Sum(nil), signatureString) -} diff --git a/vendor/cloud.google.com/go/auth/internal/transport/cba.go b/vendor/cloud.google.com/go/auth/internal/transport/cba.go deleted file mode 100644 index b1f0fcf9..00000000 --- a/vendor/cloud.google.com/go/auth/internal/transport/cba.go +++ /dev/null @@ -1,385 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package transport - -import ( - "context" - "crypto/tls" - "crypto/x509" - "errors" - "log" - "log/slog" - "net" - "net/http" - "net/url" - "os" - "strconv" - "strings" - - "cloud.google.com/go/auth/internal" - "cloud.google.com/go/auth/internal/transport/cert" - "github.com/google/s2a-go" - "github.com/google/s2a-go/fallback" - "google.golang.org/grpc/credentials" -) - -const ( - mTLSModeAlways = "always" - mTLSModeNever = "never" - mTLSModeAuto = "auto" - - // Experimental: if true, the code will try MTLS with S2A as the default for transport security. Default value is false. - googleAPIUseS2AEnv = "EXPERIMENTAL_GOOGLE_API_USE_S2A" - googleAPIUseCertSource = "GOOGLE_API_USE_CLIENT_CERTIFICATE" - googleAPIUseMTLS = "GOOGLE_API_USE_MTLS_ENDPOINT" - googleAPIUseMTLSOld = "GOOGLE_API_USE_MTLS" - - universeDomainPlaceholder = "UNIVERSE_DOMAIN" - - mtlsMDSRoot = "/run/google-mds-mtls/root.crt" - mtlsMDSKey = "/run/google-mds-mtls/client.key" -) - -// Type represents the type of transport used. -type Type int - -const ( - // TransportTypeUnknown represents an unknown transport type and is the default option. - TransportTypeUnknown Type = iota - // TransportTypeMTLSS2A represents the mTLS transport type using S2A. - TransportTypeMTLSS2A -) - -// Options is a struct that is duplicated information from the individual -// transport packages in order to avoid cyclic deps. It correlates 1:1 with -// fields on httptransport.Options and grpctransport.Options. -type Options struct { - Endpoint string - DefaultEndpointTemplate string - DefaultMTLSEndpoint string - ClientCertProvider cert.Provider - Client *http.Client - UniverseDomain string - EnableDirectPath bool - EnableDirectPathXds bool - Logger *slog.Logger -} - -// getUniverseDomain returns the default service domain for a given Cloud -// universe. -func (o *Options) getUniverseDomain() string { - if o.UniverseDomain == "" { - return internal.DefaultUniverseDomain - } - return o.UniverseDomain -} - -// isUniverseDomainGDU returns true if the universe domain is the default Google -// universe. -func (o *Options) isUniverseDomainGDU() bool { - return o.getUniverseDomain() == internal.DefaultUniverseDomain -} - -// defaultEndpoint returns the DefaultEndpointTemplate merged with the -// universe domain if the DefaultEndpointTemplate is set, otherwise returns an -// empty string. -func (o *Options) defaultEndpoint() string { - if o.DefaultEndpointTemplate == "" { - return "" - } - return strings.Replace(o.DefaultEndpointTemplate, universeDomainPlaceholder, o.getUniverseDomain(), 1) -} - -// defaultMTLSEndpoint returns the DefaultMTLSEndpointTemplate merged with the -// universe domain if the DefaultMTLSEndpointTemplate is set, otherwise returns an -// empty string. -func (o *Options) defaultMTLSEndpoint() string { - if o.DefaultMTLSEndpoint == "" { - return "" - } - return strings.Replace(o.DefaultMTLSEndpoint, universeDomainPlaceholder, o.getUniverseDomain(), 1) -} - -// mergedEndpoint merges a user-provided Endpoint of format host[:port] with the -// default endpoint. -func (o *Options) mergedEndpoint() (string, error) { - defaultEndpoint := o.defaultEndpoint() - u, err := url.Parse(fixScheme(defaultEndpoint)) - if err != nil { - return "", err - } - return strings.Replace(defaultEndpoint, u.Host, o.Endpoint, 1), nil -} - -func fixScheme(baseURL string) string { - if !strings.Contains(baseURL, "://") { - baseURL = "https://" + baseURL - } - return baseURL -} - -// GRPCTransportCredentials embeds interface TransportCredentials with additional data. -type GRPCTransportCredentials struct { - credentials.TransportCredentials - Endpoint string - TransportType Type -} - -// GetGRPCTransportCredsAndEndpoint returns an instance of -// [google.golang.org/grpc/credentials.TransportCredentials], and the -// corresponding endpoint and transport type to use for GRPC client. -func GetGRPCTransportCredsAndEndpoint(opts *Options) (*GRPCTransportCredentials, error) { - config, err := getTransportConfig(opts) - if err != nil { - return nil, err - } - - defaultTransportCreds := credentials.NewTLS(&tls.Config{ - GetClientCertificate: config.clientCertSource, - }) - - var s2aAddr string - var transportCredsForS2A credentials.TransportCredentials - - if config.mtlsS2AAddress != "" { - s2aAddr = config.mtlsS2AAddress - transportCredsForS2A, err = loadMTLSMDSTransportCreds(mtlsMDSRoot, mtlsMDSKey) - if err != nil { - log.Printf("Loading MTLS MDS credentials failed: %v", err) - if config.s2aAddress != "" { - s2aAddr = config.s2aAddress - } else { - return &GRPCTransportCredentials{defaultTransportCreds, config.endpoint, TransportTypeUnknown}, nil - } - } - } else if config.s2aAddress != "" { - s2aAddr = config.s2aAddress - } else { - return &GRPCTransportCredentials{defaultTransportCreds, config.endpoint, TransportTypeUnknown}, nil - } - - var fallbackOpts *s2a.FallbackOptions - // In case of S2A failure, fall back to the endpoint that would've been used without S2A. - if fallbackHandshake, err := fallback.DefaultFallbackClientHandshakeFunc(config.endpoint); err == nil { - fallbackOpts = &s2a.FallbackOptions{ - FallbackClientHandshakeFunc: fallbackHandshake, - } - } - - s2aTransportCreds, err := s2a.NewClientCreds(&s2a.ClientOptions{ - S2AAddress: s2aAddr, - TransportCreds: transportCredsForS2A, - FallbackOpts: fallbackOpts, - }) - if err != nil { - // Use default if we cannot initialize S2A client transport credentials. - return &GRPCTransportCredentials{defaultTransportCreds, config.endpoint, TransportTypeUnknown}, nil - } - return &GRPCTransportCredentials{s2aTransportCreds, config.s2aMTLSEndpoint, TransportTypeMTLSS2A}, nil -} - -// GetHTTPTransportConfig returns a client certificate source and a function for -// dialing MTLS with S2A. -func GetHTTPTransportConfig(opts *Options) (cert.Provider, func(context.Context, string, string) (net.Conn, error), error) { - config, err := getTransportConfig(opts) - if err != nil { - return nil, nil, err - } - - var s2aAddr string - var transportCredsForS2A credentials.TransportCredentials - - if config.mtlsS2AAddress != "" { - s2aAddr = config.mtlsS2AAddress - transportCredsForS2A, err = loadMTLSMDSTransportCreds(mtlsMDSRoot, mtlsMDSKey) - if err != nil { - log.Printf("Loading MTLS MDS credentials failed: %v", err) - if config.s2aAddress != "" { - s2aAddr = config.s2aAddress - } else { - return config.clientCertSource, nil, nil - } - } - } else if config.s2aAddress != "" { - s2aAddr = config.s2aAddress - } else { - return config.clientCertSource, nil, nil - } - - var fallbackOpts *s2a.FallbackOptions - // In case of S2A failure, fall back to the endpoint that would've been used without S2A. - if fallbackURL, err := url.Parse(config.endpoint); err == nil { - if fallbackDialer, fallbackServerAddr, err := fallback.DefaultFallbackDialerAndAddress(fallbackURL.Hostname()); err == nil { - fallbackOpts = &s2a.FallbackOptions{ - FallbackDialer: &s2a.FallbackDialer{ - Dialer: fallbackDialer, - ServerAddr: fallbackServerAddr, - }, - } - } - } - - dialTLSContextFunc := s2a.NewS2ADialTLSContextFunc(&s2a.ClientOptions{ - S2AAddress: s2aAddr, - TransportCreds: transportCredsForS2A, - FallbackOpts: fallbackOpts, - }) - return nil, dialTLSContextFunc, nil -} - -func loadMTLSMDSTransportCreds(mtlsMDSRootFile, mtlsMDSKeyFile string) (credentials.TransportCredentials, error) { - rootPEM, err := os.ReadFile(mtlsMDSRootFile) - if err != nil { - return nil, err - } - caCertPool := x509.NewCertPool() - ok := caCertPool.AppendCertsFromPEM(rootPEM) - if !ok { - return nil, errors.New("failed to load MTLS MDS root certificate") - } - // The mTLS MDS credentials are formatted as the concatenation of a PEM-encoded certificate chain - // followed by a PEM-encoded private key. For this reason, the concatenation is passed in to the - // tls.X509KeyPair function as both the certificate chain and private key arguments. - cert, err := tls.LoadX509KeyPair(mtlsMDSKeyFile, mtlsMDSKeyFile) - if err != nil { - return nil, err - } - tlsConfig := tls.Config{ - RootCAs: caCertPool, - Certificates: []tls.Certificate{cert}, - MinVersion: tls.VersionTLS13, - } - return credentials.NewTLS(&tlsConfig), nil -} - -func getTransportConfig(opts *Options) (*transportConfig, error) { - clientCertSource, err := GetClientCertificateProvider(opts) - if err != nil { - return nil, err - } - endpoint, err := getEndpoint(opts, clientCertSource) - if err != nil { - return nil, err - } - defaultTransportConfig := transportConfig{ - clientCertSource: clientCertSource, - endpoint: endpoint, - } - - if !shouldUseS2A(clientCertSource, opts) { - return &defaultTransportConfig, nil - } - - s2aAddress := GetS2AAddress(opts.Logger) - mtlsS2AAddress := GetMTLSS2AAddress(opts.Logger) - if s2aAddress == "" && mtlsS2AAddress == "" { - return &defaultTransportConfig, nil - } - return &transportConfig{ - clientCertSource: clientCertSource, - endpoint: endpoint, - s2aAddress: s2aAddress, - mtlsS2AAddress: mtlsS2AAddress, - s2aMTLSEndpoint: opts.defaultMTLSEndpoint(), - }, nil -} - -// GetClientCertificateProvider returns a default client certificate source, if -// not provided by the user. -// -// A nil default source can be returned if the source does not exist. Any exceptions -// encountered while initializing the default source will be reported as client -// error (ex. corrupt metadata file). -func GetClientCertificateProvider(opts *Options) (cert.Provider, error) { - if !isClientCertificateEnabled(opts) { - return nil, nil - } else if opts.ClientCertProvider != nil { - return opts.ClientCertProvider, nil - } - return cert.DefaultProvider() - -} - -// isClientCertificateEnabled returns true by default for all GDU universe domain, unless explicitly overridden by env var -func isClientCertificateEnabled(opts *Options) bool { - if value, ok := os.LookupEnv(googleAPIUseCertSource); ok { - // error as false is OK - b, _ := strconv.ParseBool(value) - return b - } - return opts.isUniverseDomainGDU() -} - -type transportConfig struct { - // The client certificate source. - clientCertSource cert.Provider - // The corresponding endpoint to use based on client certificate source. - endpoint string - // The plaintext S2A address if it can be used, otherwise an empty string. - s2aAddress string - // The MTLS S2A address if it can be used, otherwise an empty string. - mtlsS2AAddress string - // The MTLS endpoint to use with S2A. - s2aMTLSEndpoint string -} - -// getEndpoint returns the endpoint for the service, taking into account the -// user-provided endpoint override "settings.Endpoint". -// -// If no endpoint override is specified, we will either return the default -// endpoint or the default mTLS endpoint if a client certificate is available. -// -// You can override the default endpoint choice (mTLS vs. regular) by setting -// the GOOGLE_API_USE_MTLS_ENDPOINT environment variable. -// -// If the endpoint override is an address (host:port) rather than full base -// URL (ex. https://...), then the user-provided address will be merged into -// the default endpoint. For example, WithEndpoint("myhost:8000") and -// DefaultEndpointTemplate("https://UNIVERSE_DOMAIN/bar/baz") will return -// "https://myhost:8080/bar/baz". Note that this does not apply to the mTLS -// endpoint. -func getEndpoint(opts *Options, clientCertSource cert.Provider) (string, error) { - if opts.Endpoint == "" { - mtlsMode := getMTLSMode() - if mtlsMode == mTLSModeAlways || (clientCertSource != nil && mtlsMode == mTLSModeAuto) { - return opts.defaultMTLSEndpoint(), nil - } - return opts.defaultEndpoint(), nil - } - if strings.Contains(opts.Endpoint, "://") { - // User passed in a full URL path, use it verbatim. - return opts.Endpoint, nil - } - if opts.defaultEndpoint() == "" { - // If DefaultEndpointTemplate is not configured, - // use the user provided endpoint verbatim. This allows a naked - // "host[:port]" URL to be used with GRPC Direct Path. - return opts.Endpoint, nil - } - - // Assume user-provided endpoint is host[:port], merge it with the default endpoint. - return opts.mergedEndpoint() -} - -func getMTLSMode() string { - mode := os.Getenv(googleAPIUseMTLS) - if mode == "" { - mode = os.Getenv(googleAPIUseMTLSOld) // Deprecated. - } - if mode == "" { - return mTLSModeAuto - } - return strings.ToLower(mode) -} diff --git a/vendor/cloud.google.com/go/auth/internal/transport/cert/default_cert.go b/vendor/cloud.google.com/go/auth/internal/transport/cert/default_cert.go deleted file mode 100644 index 5cedc50f..00000000 --- a/vendor/cloud.google.com/go/auth/internal/transport/cert/default_cert.go +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package cert - -import ( - "crypto/tls" - "errors" - "sync" -) - -// defaultCertData holds all the variables pertaining to -// the default certificate provider created by [DefaultProvider]. -// -// A singleton model is used to allow the provider to be reused -// by the transport layer. As mentioned in [DefaultProvider] (provider nil, nil) -// may be returned to indicate a default provider could not be found, which -// will skip extra tls config in the transport layer . -type defaultCertData struct { - once sync.Once - provider Provider - err error -} - -var ( - defaultCert defaultCertData -) - -// Provider is a function that can be passed into crypto/tls.Config.GetClientCertificate. -type Provider func(*tls.CertificateRequestInfo) (*tls.Certificate, error) - -// errSourceUnavailable is a sentinel error to indicate certificate source is unavailable. -var errSourceUnavailable = errors.New("certificate source is unavailable") - -// DefaultProvider returns a certificate source using the preferred EnterpriseCertificateProxySource. -// If EnterpriseCertificateProxySource is not available, fall back to the legacy SecureConnectSource. -// -// If neither source is available (due to missing configurations), a nil Source and a nil Error are -// returned to indicate that a default certificate source is unavailable. -func DefaultProvider() (Provider, error) { - defaultCert.once.Do(func() { - defaultCert.provider, defaultCert.err = NewWorkloadX509CertProvider("") - if errors.Is(defaultCert.err, errSourceUnavailable) { - defaultCert.provider, defaultCert.err = NewEnterpriseCertificateProxyProvider("") - if errors.Is(defaultCert.err, errSourceUnavailable) { - defaultCert.provider, defaultCert.err = NewSecureConnectProvider("") - if errors.Is(defaultCert.err, errSourceUnavailable) { - defaultCert.provider, defaultCert.err = nil, nil - } - } - } - }) - return defaultCert.provider, defaultCert.err -} diff --git a/vendor/cloud.google.com/go/auth/internal/transport/cert/enterprise_cert.go b/vendor/cloud.google.com/go/auth/internal/transport/cert/enterprise_cert.go deleted file mode 100644 index 6c954ae1..00000000 --- a/vendor/cloud.google.com/go/auth/internal/transport/cert/enterprise_cert.go +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package cert - -import ( - "crypto/tls" - - "github.com/googleapis/enterprise-certificate-proxy/client" -) - -type ecpSource struct { - key *client.Key -} - -// NewEnterpriseCertificateProxyProvider creates a certificate source -// using the Enterprise Certificate Proxy client, which delegates -// certifcate related operations to an OS-specific "signer binary" -// that communicates with the native keystore (ex. keychain on MacOS). -// -// The configFilePath points to a config file containing relevant parameters -// such as the certificate issuer and the location of the signer binary. -// If configFilePath is empty, the client will attempt to load the config from -// a well-known gcloud location. -func NewEnterpriseCertificateProxyProvider(configFilePath string) (Provider, error) { - key, err := client.Cred(configFilePath) - if err != nil { - // TODO(codyoss): once this is fixed upstream can handle this error a - // little better here. But be safe for now and assume unavailable. - return nil, errSourceUnavailable - } - - return (&ecpSource{ - key: key, - }).getClientCertificate, nil -} - -func (s *ecpSource) getClientCertificate(info *tls.CertificateRequestInfo) (*tls.Certificate, error) { - var cert tls.Certificate - cert.PrivateKey = s.key - cert.Certificate = s.key.CertificateChain() - return &cert, nil -} diff --git a/vendor/cloud.google.com/go/auth/internal/transport/cert/secureconnect_cert.go b/vendor/cloud.google.com/go/auth/internal/transport/cert/secureconnect_cert.go deleted file mode 100644 index 738cb216..00000000 --- a/vendor/cloud.google.com/go/auth/internal/transport/cert/secureconnect_cert.go +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package cert - -import ( - "crypto/tls" - "crypto/x509" - "encoding/json" - "errors" - "fmt" - "os" - "os/exec" - "os/user" - "path/filepath" - "sync" - "time" -) - -const ( - metadataPath = ".secureConnect" - metadataFile = "context_aware_metadata.json" -) - -type secureConnectSource struct { - metadata secureConnectMetadata - - // Cache the cert to avoid executing helper command repeatedly. - cachedCertMutex sync.Mutex - cachedCert *tls.Certificate -} - -type secureConnectMetadata struct { - Cmd []string `json:"cert_provider_command"` -} - -// NewSecureConnectProvider creates a certificate source using -// the Secure Connect Helper and its associated metadata file. -// -// The configFilePath points to the location of the context aware metadata file. -// If configFilePath is empty, use the default context aware metadata location. -func NewSecureConnectProvider(configFilePath string) (Provider, error) { - if configFilePath == "" { - user, err := user.Current() - if err != nil { - // Error locating the default config means Secure Connect is not supported. - return nil, errSourceUnavailable - } - configFilePath = filepath.Join(user.HomeDir, metadataPath, metadataFile) - } - - file, err := os.ReadFile(configFilePath) - if err != nil { - // Config file missing means Secure Connect is not supported. - // There are non-os.ErrNotExist errors that may be returned. - // (e.g. if the home directory is /dev/null, *nix systems will - // return ENOTDIR instead of ENOENT) - return nil, errSourceUnavailable - } - - var metadata secureConnectMetadata - if err := json.Unmarshal(file, &metadata); err != nil { - return nil, fmt.Errorf("cert: could not parse JSON in %q: %w", configFilePath, err) - } - if err := validateMetadata(metadata); err != nil { - return nil, fmt.Errorf("cert: invalid config in %q: %w", configFilePath, err) - } - return (&secureConnectSource{ - metadata: metadata, - }).getClientCertificate, nil -} - -func validateMetadata(metadata secureConnectMetadata) error { - if len(metadata.Cmd) == 0 { - return errors.New("empty cert_provider_command") - } - return nil -} - -func (s *secureConnectSource) getClientCertificate(info *tls.CertificateRequestInfo) (*tls.Certificate, error) { - s.cachedCertMutex.Lock() - defer s.cachedCertMutex.Unlock() - if s.cachedCert != nil && !isCertificateExpired(s.cachedCert) { - return s.cachedCert, nil - } - // Expand OS environment variables in the cert provider command such as "$HOME". - for i := 0; i < len(s.metadata.Cmd); i++ { - s.metadata.Cmd[i] = os.ExpandEnv(s.metadata.Cmd[i]) - } - command := s.metadata.Cmd - data, err := exec.Command(command[0], command[1:]...).Output() - if err != nil { - return nil, err - } - cert, err := tls.X509KeyPair(data, data) - if err != nil { - return nil, err - } - s.cachedCert = &cert - return &cert, nil -} - -// isCertificateExpired returns true if the given cert is expired or invalid. -func isCertificateExpired(cert *tls.Certificate) bool { - if len(cert.Certificate) == 0 { - return true - } - parsed, err := x509.ParseCertificate(cert.Certificate[0]) - if err != nil { - return true - } - return time.Now().After(parsed.NotAfter) -} diff --git a/vendor/cloud.google.com/go/auth/internal/transport/cert/workload_cert.go b/vendor/cloud.google.com/go/auth/internal/transport/cert/workload_cert.go deleted file mode 100644 index 347aaced..00000000 --- a/vendor/cloud.google.com/go/auth/internal/transport/cert/workload_cert.go +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright 2024 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package cert - -import ( - "crypto/tls" - "encoding/json" - "errors" - "io" - "os" - - "github.com/googleapis/enterprise-certificate-proxy/client/util" -) - -type certConfigs struct { - Workload *workloadSource `json:"workload"` -} - -type workloadSource struct { - CertPath string `json:"cert_path"` - KeyPath string `json:"key_path"` -} - -type certificateConfig struct { - CertConfigs certConfigs `json:"cert_configs"` -} - -// NewWorkloadX509CertProvider creates a certificate source -// that reads a certificate and private key file from the local file system. -// This is intended to be used for workload identity federation. -// -// The configFilePath points to a config file containing relevant parameters -// such as the certificate and key file paths. -// If configFilePath is empty, the client will attempt to load the config from -// a well-known gcloud location. -func NewWorkloadX509CertProvider(configFilePath string) (Provider, error) { - if configFilePath == "" { - envFilePath := util.GetConfigFilePathFromEnv() - if envFilePath != "" { - configFilePath = envFilePath - } else { - configFilePath = util.GetDefaultConfigFilePath() - } - } - - certFile, keyFile, err := getCertAndKeyFiles(configFilePath) - if err != nil { - return nil, err - } - - source := &workloadSource{ - CertPath: certFile, - KeyPath: keyFile, - } - return source.getClientCertificate, nil -} - -// getClientCertificate attempts to load the certificate and key from the files specified in the -// certificate config. -func (s *workloadSource) getClientCertificate(info *tls.CertificateRequestInfo) (*tls.Certificate, error) { - cert, err := tls.LoadX509KeyPair(s.CertPath, s.KeyPath) - if err != nil { - return nil, err - } - return &cert, nil -} - -// getCertAndKeyFiles attempts to read the provided config file and return the certificate and private -// key file paths. -func getCertAndKeyFiles(configFilePath string) (string, string, error) { - jsonFile, err := os.Open(configFilePath) - if err != nil { - return "", "", errSourceUnavailable - } - - byteValue, err := io.ReadAll(jsonFile) - if err != nil { - return "", "", err - } - - var config certificateConfig - if err := json.Unmarshal(byteValue, &config); err != nil { - return "", "", err - } - - if config.CertConfigs.Workload == nil { - return "", "", errSourceUnavailable - } - - certFile := config.CertConfigs.Workload.CertPath - keyFile := config.CertConfigs.Workload.KeyPath - - if certFile == "" { - return "", "", errors.New("certificate configuration is missing the certificate file location") - } - - if keyFile == "" { - return "", "", errors.New("certificate configuration is missing the key file location") - } - - return certFile, keyFile, nil -} diff --git a/vendor/cloud.google.com/go/auth/internal/transport/s2a.go b/vendor/cloud.google.com/go/auth/internal/transport/s2a.go deleted file mode 100644 index a6330995..00000000 --- a/vendor/cloud.google.com/go/auth/internal/transport/s2a.go +++ /dev/null @@ -1,138 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package transport - -import ( - "context" - "encoding/json" - "fmt" - "log" - "log/slog" - "os" - "strconv" - "sync" - - "cloud.google.com/go/auth/internal/transport/cert" - "cloud.google.com/go/compute/metadata" -) - -const ( - configEndpointSuffix = "instance/platform-security/auto-mtls-configuration" -) - -var ( - mtlsConfiguration *mtlsConfig - - mtlsOnce sync.Once -) - -// GetS2AAddress returns the S2A address to be reached via plaintext connection. -// Returns empty string if not set or invalid. -func GetS2AAddress(logger *slog.Logger) string { - getMetadataMTLSAutoConfig(logger) - if !mtlsConfiguration.valid() { - return "" - } - return mtlsConfiguration.S2A.PlaintextAddress -} - -// GetMTLSS2AAddress returns the S2A address to be reached via MTLS connection. -// Returns empty string if not set or invalid. -func GetMTLSS2AAddress(logger *slog.Logger) string { - getMetadataMTLSAutoConfig(logger) - if !mtlsConfiguration.valid() { - return "" - } - return mtlsConfiguration.S2A.MTLSAddress -} - -// mtlsConfig contains the configuration for establishing MTLS connections with Google APIs. -type mtlsConfig struct { - S2A *s2aAddresses `json:"s2a"` -} - -func (c *mtlsConfig) valid() bool { - return c != nil && c.S2A != nil -} - -// s2aAddresses contains the plaintext and/or MTLS S2A addresses. -type s2aAddresses struct { - // PlaintextAddress is the plaintext address to reach S2A - PlaintextAddress string `json:"plaintext_address"` - // MTLSAddress is the MTLS address to reach S2A - MTLSAddress string `json:"mtls_address"` -} - -func getMetadataMTLSAutoConfig(logger *slog.Logger) { - var err error - mtlsOnce.Do(func() { - mtlsConfiguration, err = queryConfig(logger) - if err != nil { - log.Printf("Getting MTLS config failed: %v", err) - } - }) -} - -var httpGetMetadataMTLSConfig = func(logger *slog.Logger) (string, error) { - metadataClient := metadata.NewWithOptions(&metadata.Options{ - Logger: logger, - }) - return metadataClient.GetWithContext(context.Background(), configEndpointSuffix) -} - -func queryConfig(logger *slog.Logger) (*mtlsConfig, error) { - resp, err := httpGetMetadataMTLSConfig(logger) - if err != nil { - return nil, fmt.Errorf("querying MTLS config from MDS endpoint failed: %w", err) - } - var config mtlsConfig - err = json.Unmarshal([]byte(resp), &config) - if err != nil { - return nil, fmt.Errorf("unmarshalling MTLS config from MDS endpoint failed: %w", err) - } - if config.S2A == nil { - return nil, fmt.Errorf("returned MTLS config from MDS endpoint is invalid: %v", config) - } - return &config, nil -} - -func shouldUseS2A(clientCertSource cert.Provider, opts *Options) bool { - // If client cert is found, use that over S2A. - if clientCertSource != nil { - return false - } - // If EXPERIMENTAL_GOOGLE_API_USE_S2A is not set to true, skip S2A. - if !isGoogleS2AEnabled() { - return false - } - // If DefaultMTLSEndpoint is not set or has endpoint override, skip S2A. - if opts.DefaultMTLSEndpoint == "" || opts.Endpoint != "" { - return false - } - // If custom HTTP client is provided, skip S2A. - if opts.Client != nil { - return false - } - // If directPath is enabled, skip S2A. - return !opts.EnableDirectPath && !opts.EnableDirectPathXds -} - -func isGoogleS2AEnabled() bool { - b, err := strconv.ParseBool(os.Getenv(googleAPIUseS2AEnv)) - if err != nil { - return false - } - return b -} diff --git a/vendor/cloud.google.com/go/auth/internal/transport/transport.go b/vendor/cloud.google.com/go/auth/internal/transport/transport.go deleted file mode 100644 index 5c8721ef..00000000 --- a/vendor/cloud.google.com/go/auth/internal/transport/transport.go +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package transport provided internal helpers for the two transport packages -// (grpctransport and httptransport). -package transport - -import ( - "crypto/tls" - "fmt" - "net" - "net/http" - "time" - - "cloud.google.com/go/auth/credentials" -) - -// CloneDetectOptions clones a user set detect option into some new memory that -// we can internally manipulate before sending onto the detect package. -func CloneDetectOptions(oldDo *credentials.DetectOptions) *credentials.DetectOptions { - if oldDo == nil { - // it is valid for users not to set this, but we will need to to default - // some options for them in this case so return some initialized memory - // to work with. - return &credentials.DetectOptions{} - } - newDo := &credentials.DetectOptions{ - // Simple types - TokenBindingType: oldDo.TokenBindingType, - Audience: oldDo.Audience, - Subject: oldDo.Subject, - EarlyTokenRefresh: oldDo.EarlyTokenRefresh, - TokenURL: oldDo.TokenURL, - STSAudience: oldDo.STSAudience, - CredentialsFile: oldDo.CredentialsFile, - UseSelfSignedJWT: oldDo.UseSelfSignedJWT, - UniverseDomain: oldDo.UniverseDomain, - - // These fields are pointer types that we just want to use exactly as - // the user set, copy the ref - Client: oldDo.Client, - Logger: oldDo.Logger, - AuthHandlerOptions: oldDo.AuthHandlerOptions, - } - - // Smartly size this memory and copy below. - if len(oldDo.CredentialsJSON) > 0 { - newDo.CredentialsJSON = make([]byte, len(oldDo.CredentialsJSON)) - copy(newDo.CredentialsJSON, oldDo.CredentialsJSON) - } - if len(oldDo.Scopes) > 0 { - newDo.Scopes = make([]string, len(oldDo.Scopes)) - copy(newDo.Scopes, oldDo.Scopes) - } - - return newDo -} - -// ValidateUniverseDomain verifies that the universe domain configured for the -// client matches the universe domain configured for the credentials. -func ValidateUniverseDomain(clientUniverseDomain, credentialsUniverseDomain string) error { - if clientUniverseDomain != credentialsUniverseDomain { - return fmt.Errorf( - "the configured universe domain (%q) does not match the universe "+ - "domain found in the credentials (%q). If you haven't configured "+ - "the universe domain explicitly, \"googleapis.com\" is the default", - clientUniverseDomain, - credentialsUniverseDomain) - } - return nil -} - -// DefaultHTTPClientWithTLS constructs an HTTPClient using the provided tlsConfig, to support mTLS. -func DefaultHTTPClientWithTLS(tlsConfig *tls.Config) *http.Client { - trans := BaseTransport() - trans.TLSClientConfig = tlsConfig - return &http.Client{Transport: trans} -} - -// BaseTransport returns a default [http.Transport] which can be used if -// [http.DefaultTransport] has been overwritten. -func BaseTransport() *http.Transport { - return &http.Transport{ - Proxy: http.ProxyFromEnvironment, - DialContext: (&net.Dialer{ - Timeout: 30 * time.Second, - KeepAlive: 30 * time.Second, - DualStack: true, - }).DialContext, - MaxIdleConns: 100, - MaxIdleConnsPerHost: 100, - IdleConnTimeout: 90 * time.Second, - TLSHandshakeTimeout: 10 * time.Second, - ExpectContinueTimeout: 1 * time.Second, - } -} diff --git a/vendor/cloud.google.com/go/auth/oauth2adapt/CHANGES.md b/vendor/cloud.google.com/go/auth/oauth2adapt/CHANGES.md deleted file mode 100644 index d9044f1a..00000000 --- a/vendor/cloud.google.com/go/auth/oauth2adapt/CHANGES.md +++ /dev/null @@ -1,75 +0,0 @@ -# Changelog - -## [0.2.7](https://github.com/googleapis/google-cloud-go/compare/auth/oauth2adapt/v0.2.6...auth/oauth2adapt/v0.2.7) (2025-01-09) - - -### Bug Fixes - -* **auth/oauth2adapt:** Update golang.org/x/net to v0.33.0 ([e9b0b69](https://github.com/googleapis/google-cloud-go/commit/e9b0b69644ea5b276cacff0a707e8a5e87efafc9)) - -## [0.2.6](https://github.com/googleapis/google-cloud-go/compare/auth/oauth2adapt/v0.2.5...auth/oauth2adapt/v0.2.6) (2024-11-21) - - -### Bug Fixes - -* **auth/oauth2adapt:** Copy map in tokenSourceAdapter.Token ([#11164](https://github.com/googleapis/google-cloud-go/issues/11164)) ([8cb0cbc](https://github.com/googleapis/google-cloud-go/commit/8cb0cbccdc32886dfb3af49fee04012937d114d2)), refs [#11161](https://github.com/googleapis/google-cloud-go/issues/11161) - -## [0.2.5](https://github.com/googleapis/google-cloud-go/compare/auth/oauth2adapt/v0.2.4...auth/oauth2adapt/v0.2.5) (2024-10-30) - - -### Bug Fixes - -* **auth/oauth2adapt:** Convert token metadata where possible ([#11062](https://github.com/googleapis/google-cloud-go/issues/11062)) ([34bf1c1](https://github.com/googleapis/google-cloud-go/commit/34bf1c164465d66745c0cfdf7cd10a8e2da92e52)) - -## [0.2.4](https://github.com/googleapis/google-cloud-go/compare/auth/oauth2adapt/v0.2.3...auth/oauth2adapt/v0.2.4) (2024-08-08) - - -### Bug Fixes - -* **auth/oauth2adapt:** Update dependencies ([257c40b](https://github.com/googleapis/google-cloud-go/commit/257c40bd6d7e59730017cf32bda8823d7a232758)) - -## [0.2.3](https://github.com/googleapis/google-cloud-go/compare/auth/oauth2adapt/v0.2.2...auth/oauth2adapt/v0.2.3) (2024-07-10) - - -### Bug Fixes - -* **auth/oauth2adapt:** Bump google.golang.org/api@v0.187.0 ([8fa9e39](https://github.com/googleapis/google-cloud-go/commit/8fa9e398e512fd8533fd49060371e61b5725a85b)) - -## [0.2.2](https://github.com/googleapis/google-cloud-go/compare/auth/oauth2adapt/v0.2.1...auth/oauth2adapt/v0.2.2) (2024-04-23) - - -### Bug Fixes - -* **auth/oauth2adapt:** Bump x/net to v0.24.0 ([ba31ed5](https://github.com/googleapis/google-cloud-go/commit/ba31ed5fda2c9664f2e1cf972469295e63deb5b4)) - -## [0.2.1](https://github.com/googleapis/google-cloud-go/compare/auth/oauth2adapt/v0.2.0...auth/oauth2adapt/v0.2.1) (2024-04-18) - - -### Bug Fixes - -* **auth/oauth2adapt:** Adapt Token Types to be translated ([#9801](https://github.com/googleapis/google-cloud-go/issues/9801)) ([70f4115](https://github.com/googleapis/google-cloud-go/commit/70f411555ebbf2b71e6d425cc8d2030644c6b438)), refs [#9800](https://github.com/googleapis/google-cloud-go/issues/9800) - -## [0.2.0](https://github.com/googleapis/google-cloud-go/compare/auth/oauth2adapt/v0.1.0...auth/oauth2adapt/v0.2.0) (2024-04-16) - - -### Features - -* **auth/oauth2adapt:** Add helpers for working with credentials types ([#9694](https://github.com/googleapis/google-cloud-go/issues/9694)) ([cf33b55](https://github.com/googleapis/google-cloud-go/commit/cf33b5514423a2ac5c2a323a1cd99aac34fd4233)) - - -### Bug Fixes - -* **auth/oauth2adapt:** Update protobuf dep to v1.33.0 ([30b038d](https://github.com/googleapis/google-cloud-go/commit/30b038d8cac0b8cd5dd4761c87f3f298760dd33a)) - -## 0.1.0 (2023-10-19) - - -### Features - -* **auth/oauth2adapt:** Adds a new module to translate types ([#8595](https://github.com/googleapis/google-cloud-go/issues/8595)) ([6933c5a](https://github.com/googleapis/google-cloud-go/commit/6933c5a0c1fc8e58cbfff8bbca439d671b94672f)) -* **auth/oauth2adapt:** Fixup deps for release ([#8747](https://github.com/googleapis/google-cloud-go/issues/8747)) ([749d243](https://github.com/googleapis/google-cloud-go/commit/749d243862b025a6487a4d2d339219889b4cfe70)) - - -### Bug Fixes - -* **auth/oauth2adapt:** Update golang.org/x/net to v0.17.0 ([174da47](https://github.com/googleapis/google-cloud-go/commit/174da47254fefb12921bbfc65b7829a453af6f5d)) diff --git a/vendor/cloud.google.com/go/auth/oauth2adapt/LICENSE b/vendor/cloud.google.com/go/auth/oauth2adapt/LICENSE deleted file mode 100644 index d6456956..00000000 --- a/vendor/cloud.google.com/go/auth/oauth2adapt/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/cloud.google.com/go/auth/oauth2adapt/oauth2adapt.go b/vendor/cloud.google.com/go/auth/oauth2adapt/oauth2adapt.go deleted file mode 100644 index 9cc33e5e..00000000 --- a/vendor/cloud.google.com/go/auth/oauth2adapt/oauth2adapt.go +++ /dev/null @@ -1,200 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package oauth2adapt helps converts types used in [cloud.google.com/go/auth] -// and [golang.org/x/oauth2]. -package oauth2adapt - -import ( - "context" - "encoding/json" - "errors" - - "cloud.google.com/go/auth" - "golang.org/x/oauth2" - "golang.org/x/oauth2/google" -) - -const ( - oauth2TokenSourceKey = "oauth2.google.tokenSource" - oauth2ServiceAccountKey = "oauth2.google.serviceAccount" - authTokenSourceKey = "auth.google.tokenSource" - authServiceAccountKey = "auth.google.serviceAccount" -) - -// TokenProviderFromTokenSource converts any [golang.org/x/oauth2.TokenSource] -// into a [cloud.google.com/go/auth.TokenProvider]. -func TokenProviderFromTokenSource(ts oauth2.TokenSource) auth.TokenProvider { - return &tokenProviderAdapter{ts: ts} -} - -type tokenProviderAdapter struct { - ts oauth2.TokenSource -} - -// Token fulfills the [cloud.google.com/go/auth.TokenProvider] interface. It -// is a light wrapper around the underlying TokenSource. -func (tp *tokenProviderAdapter) Token(context.Context) (*auth.Token, error) { - tok, err := tp.ts.Token() - if err != nil { - var err2 *oauth2.RetrieveError - if ok := errors.As(err, &err2); ok { - return nil, AuthErrorFromRetrieveError(err2) - } - return nil, err - } - // Preserve compute token metadata, for both types of tokens. - metadata := map[string]interface{}{} - if val, ok := tok.Extra(oauth2TokenSourceKey).(string); ok { - metadata[authTokenSourceKey] = val - metadata[oauth2TokenSourceKey] = val - } - if val, ok := tok.Extra(oauth2ServiceAccountKey).(string); ok { - metadata[authServiceAccountKey] = val - metadata[oauth2ServiceAccountKey] = val - } - return &auth.Token{ - Value: tok.AccessToken, - Type: tok.Type(), - Expiry: tok.Expiry, - Metadata: metadata, - }, nil -} - -// TokenSourceFromTokenProvider converts any -// [cloud.google.com/go/auth.TokenProvider] into a -// [golang.org/x/oauth2.TokenSource]. -func TokenSourceFromTokenProvider(tp auth.TokenProvider) oauth2.TokenSource { - return &tokenSourceAdapter{tp: tp} -} - -type tokenSourceAdapter struct { - tp auth.TokenProvider -} - -// Token fulfills the [golang.org/x/oauth2.TokenSource] interface. It -// is a light wrapper around the underlying TokenProvider. -func (ts *tokenSourceAdapter) Token() (*oauth2.Token, error) { - tok, err := ts.tp.Token(context.Background()) - if err != nil { - var err2 *auth.Error - if ok := errors.As(err, &err2); ok { - return nil, AddRetrieveErrorToAuthError(err2) - } - return nil, err - } - tok2 := &oauth2.Token{ - AccessToken: tok.Value, - TokenType: tok.Type, - Expiry: tok.Expiry, - } - // Preserve token metadata. - m := tok.Metadata - if m != nil { - // Copy map to avoid concurrent map writes error (#11161). - metadata := make(map[string]interface{}, len(m)+2) - for k, v := range m { - metadata[k] = v - } - // Append compute token metadata in converted form. - if val, ok := metadata[authTokenSourceKey].(string); ok && val != "" { - metadata[oauth2TokenSourceKey] = val - } - if val, ok := metadata[authServiceAccountKey].(string); ok && val != "" { - metadata[oauth2ServiceAccountKey] = val - } - tok2 = tok2.WithExtra(metadata) - } - return tok2, nil -} - -// AuthCredentialsFromOauth2Credentials converts a [golang.org/x/oauth2/google.Credentials] -// to a [cloud.google.com/go/auth.Credentials]. -func AuthCredentialsFromOauth2Credentials(creds *google.Credentials) *auth.Credentials { - if creds == nil { - return nil - } - return auth.NewCredentials(&auth.CredentialsOptions{ - TokenProvider: TokenProviderFromTokenSource(creds.TokenSource), - JSON: creds.JSON, - ProjectIDProvider: auth.CredentialsPropertyFunc(func(ctx context.Context) (string, error) { - return creds.ProjectID, nil - }), - UniverseDomainProvider: auth.CredentialsPropertyFunc(func(ctx context.Context) (string, error) { - return creds.GetUniverseDomain() - }), - }) -} - -// Oauth2CredentialsFromAuthCredentials converts a [cloud.google.com/go/auth.Credentials] -// to a [golang.org/x/oauth2/google.Credentials]. -func Oauth2CredentialsFromAuthCredentials(creds *auth.Credentials) *google.Credentials { - if creds == nil { - return nil - } - // Throw away errors as old credentials are not request aware. Also, no - // network requests are currently happening for this use case. - projectID, _ := creds.ProjectID(context.Background()) - - return &google.Credentials{ - TokenSource: TokenSourceFromTokenProvider(creds.TokenProvider), - ProjectID: projectID, - JSON: creds.JSON(), - UniverseDomainProvider: func() (string, error) { - return creds.UniverseDomain(context.Background()) - }, - } -} - -type oauth2Error struct { - ErrorCode string `json:"error"` - ErrorDescription string `json:"error_description"` - ErrorURI string `json:"error_uri"` -} - -// AddRetrieveErrorToAuthError returns the same error provided and adds a -// [golang.org/x/oauth2.RetrieveError] to the error chain by setting the `Err` field on the -// [cloud.google.com/go/auth.Error]. -func AddRetrieveErrorToAuthError(err *auth.Error) *auth.Error { - if err == nil { - return nil - } - e := &oauth2.RetrieveError{ - Response: err.Response, - Body: err.Body, - } - err.Err = e - if len(err.Body) > 0 { - var oErr oauth2Error - // ignore the error as it only fills in extra details - json.Unmarshal(err.Body, &oErr) - e.ErrorCode = oErr.ErrorCode - e.ErrorDescription = oErr.ErrorDescription - e.ErrorURI = oErr.ErrorURI - } - return err -} - -// AuthErrorFromRetrieveError returns an [cloud.google.com/go/auth.Error] that -// wraps the provided [golang.org/x/oauth2.RetrieveError]. -func AuthErrorFromRetrieveError(err *oauth2.RetrieveError) *auth.Error { - if err == nil { - return nil - } - return &auth.Error{ - Response: err.Response, - Body: err.Body, - Err: err, - } -} diff --git a/vendor/cloud.google.com/go/auth/threelegged.go b/vendor/cloud.google.com/go/auth/threelegged.go deleted file mode 100644 index 07804dc1..00000000 --- a/vendor/cloud.google.com/go/auth/threelegged.go +++ /dev/null @@ -1,382 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package auth - -import ( - "bytes" - "context" - "encoding/json" - "errors" - "fmt" - "log/slog" - "mime" - "net/http" - "net/url" - "strconv" - "strings" - "time" - - "cloud.google.com/go/auth/internal" - "github.com/googleapis/gax-go/v2/internallog" -) - -// AuthorizationHandler is a 3-legged-OAuth helper that prompts the user for -// OAuth consent at the specified auth code URL and returns an auth code and -// state upon approval. -type AuthorizationHandler func(authCodeURL string) (code string, state string, err error) - -// Options3LO are the options for doing a 3-legged OAuth2 flow. -type Options3LO struct { - // ClientID is the application's ID. - ClientID string - // ClientSecret is the application's secret. Not required if AuthHandlerOpts - // is set. - ClientSecret string - // AuthURL is the URL for authenticating. - AuthURL string - // TokenURL is the URL for retrieving a token. - TokenURL string - // AuthStyle is used to describe how to client info in the token request. - AuthStyle Style - // RefreshToken is the token used to refresh the credential. Not required - // if AuthHandlerOpts is set. - RefreshToken string - // RedirectURL is the URL to redirect users to. Optional. - RedirectURL string - // Scopes specifies requested permissions for the Token. Optional. - Scopes []string - - // URLParams are the set of values to apply to the token exchange. Optional. - URLParams url.Values - // Client is the client to be used to make the underlying token requests. - // Optional. - Client *http.Client - // EarlyTokenExpiry is the time before the token expires that it should be - // refreshed. If not set the default value is 3 minutes and 45 seconds. - // Optional. - EarlyTokenExpiry time.Duration - - // AuthHandlerOpts provides a set of options for doing a - // 3-legged OAuth2 flow with a custom [AuthorizationHandler]. Optional. - AuthHandlerOpts *AuthorizationHandlerOptions - // Logger is used for debug logging. If provided, logging will be enabled - // at the loggers configured level. By default logging is disabled unless - // enabled by setting GOOGLE_SDK_GO_LOGGING_LEVEL in which case a default - // logger will be used. Optional. - Logger *slog.Logger -} - -func (o *Options3LO) validate() error { - if o == nil { - return errors.New("auth: options must be provided") - } - if o.ClientID == "" { - return errors.New("auth: client ID must be provided") - } - if o.AuthHandlerOpts == nil && o.ClientSecret == "" { - return errors.New("auth: client secret must be provided") - } - if o.AuthURL == "" { - return errors.New("auth: auth URL must be provided") - } - if o.TokenURL == "" { - return errors.New("auth: token URL must be provided") - } - if o.AuthStyle == StyleUnknown { - return errors.New("auth: auth style must be provided") - } - if o.AuthHandlerOpts == nil && o.RefreshToken == "" { - return errors.New("auth: refresh token must be provided") - } - return nil -} - -func (o *Options3LO) logger() *slog.Logger { - return internallog.New(o.Logger) -} - -// PKCEOptions holds parameters to support PKCE. -type PKCEOptions struct { - // Challenge is the un-padded, base64-url-encoded string of the encrypted code verifier. - Challenge string // The un-padded, base64-url-encoded string of the encrypted code verifier. - // ChallengeMethod is the encryption method (ex. S256). - ChallengeMethod string - // Verifier is the original, non-encrypted secret. - Verifier string // The original, non-encrypted secret. -} - -type tokenJSON struct { - AccessToken string `json:"access_token"` - TokenType string `json:"token_type"` - RefreshToken string `json:"refresh_token"` - ExpiresIn int `json:"expires_in"` - // error fields - ErrorCode string `json:"error"` - ErrorDescription string `json:"error_description"` - ErrorURI string `json:"error_uri"` -} - -func (e *tokenJSON) expiry() (t time.Time) { - if v := e.ExpiresIn; v != 0 { - return time.Now().Add(time.Duration(v) * time.Second) - } - return -} - -func (o *Options3LO) client() *http.Client { - if o.Client != nil { - return o.Client - } - return internal.DefaultClient() -} - -// authCodeURL returns a URL that points to a OAuth2 consent page. -func (o *Options3LO) authCodeURL(state string, values url.Values) string { - var buf bytes.Buffer - buf.WriteString(o.AuthURL) - v := url.Values{ - "response_type": {"code"}, - "client_id": {o.ClientID}, - } - if o.RedirectURL != "" { - v.Set("redirect_uri", o.RedirectURL) - } - if len(o.Scopes) > 0 { - v.Set("scope", strings.Join(o.Scopes, " ")) - } - if state != "" { - v.Set("state", state) - } - if o.AuthHandlerOpts != nil { - if o.AuthHandlerOpts.PKCEOpts != nil && - o.AuthHandlerOpts.PKCEOpts.Challenge != "" { - v.Set(codeChallengeKey, o.AuthHandlerOpts.PKCEOpts.Challenge) - } - if o.AuthHandlerOpts.PKCEOpts != nil && - o.AuthHandlerOpts.PKCEOpts.ChallengeMethod != "" { - v.Set(codeChallengeMethodKey, o.AuthHandlerOpts.PKCEOpts.ChallengeMethod) - } - } - for k := range values { - v.Set(k, v.Get(k)) - } - if strings.Contains(o.AuthURL, "?") { - buf.WriteByte('&') - } else { - buf.WriteByte('?') - } - buf.WriteString(v.Encode()) - return buf.String() -} - -// New3LOTokenProvider returns a [TokenProvider] based on the 3-legged OAuth2 -// configuration. The TokenProvider is caches and auto-refreshes tokens by -// default. -func New3LOTokenProvider(opts *Options3LO) (TokenProvider, error) { - if err := opts.validate(); err != nil { - return nil, err - } - if opts.AuthHandlerOpts != nil { - return new3LOTokenProviderWithAuthHandler(opts), nil - } - return NewCachedTokenProvider(&tokenProvider3LO{opts: opts, refreshToken: opts.RefreshToken, client: opts.client()}, &CachedTokenProviderOptions{ - ExpireEarly: opts.EarlyTokenExpiry, - }), nil -} - -// AuthorizationHandlerOptions provides a set of options to specify for doing a -// 3-legged OAuth2 flow with a custom [AuthorizationHandler]. -type AuthorizationHandlerOptions struct { - // AuthorizationHandler specifies the handler used to for the authorization - // part of the flow. - Handler AuthorizationHandler - // State is used verify that the "state" is identical in the request and - // response before exchanging the auth code for OAuth2 token. - State string - // PKCEOpts allows setting configurations for PKCE. Optional. - PKCEOpts *PKCEOptions -} - -func new3LOTokenProviderWithAuthHandler(opts *Options3LO) TokenProvider { - return NewCachedTokenProvider(&tokenProviderWithHandler{opts: opts, state: opts.AuthHandlerOpts.State}, &CachedTokenProviderOptions{ - ExpireEarly: opts.EarlyTokenExpiry, - }) -} - -// exchange handles the final exchange portion of the 3lo flow. Returns a Token, -// refreshToken, and error. -func (o *Options3LO) exchange(ctx context.Context, code string) (*Token, string, error) { - // Build request - v := url.Values{ - "grant_type": {"authorization_code"}, - "code": {code}, - } - if o.RedirectURL != "" { - v.Set("redirect_uri", o.RedirectURL) - } - if o.AuthHandlerOpts != nil && - o.AuthHandlerOpts.PKCEOpts != nil && - o.AuthHandlerOpts.PKCEOpts.Verifier != "" { - v.Set(codeVerifierKey, o.AuthHandlerOpts.PKCEOpts.Verifier) - } - for k := range o.URLParams { - v.Set(k, o.URLParams.Get(k)) - } - return fetchToken(ctx, o, v) -} - -// This struct is not safe for concurrent access alone, but the way it is used -// in this package by wrapping it with a cachedTokenProvider makes it so. -type tokenProvider3LO struct { - opts *Options3LO - client *http.Client - refreshToken string -} - -func (tp *tokenProvider3LO) Token(ctx context.Context) (*Token, error) { - if tp.refreshToken == "" { - return nil, errors.New("auth: token expired and refresh token is not set") - } - v := url.Values{ - "grant_type": {"refresh_token"}, - "refresh_token": {tp.refreshToken}, - } - for k := range tp.opts.URLParams { - v.Set(k, tp.opts.URLParams.Get(k)) - } - - tk, rt, err := fetchToken(ctx, tp.opts, v) - if err != nil { - return nil, err - } - if tp.refreshToken != rt && rt != "" { - tp.refreshToken = rt - } - return tk, err -} - -type tokenProviderWithHandler struct { - opts *Options3LO - state string -} - -func (tp tokenProviderWithHandler) Token(ctx context.Context) (*Token, error) { - url := tp.opts.authCodeURL(tp.state, nil) - code, state, err := tp.opts.AuthHandlerOpts.Handler(url) - if err != nil { - return nil, err - } - if state != tp.state { - return nil, errors.New("auth: state mismatch in 3-legged-OAuth flow") - } - tok, _, err := tp.opts.exchange(ctx, code) - return tok, err -} - -// fetchToken returns a Token, refresh token, and/or an error. -func fetchToken(ctx context.Context, o *Options3LO, v url.Values) (*Token, string, error) { - var refreshToken string - if o.AuthStyle == StyleInParams { - if o.ClientID != "" { - v.Set("client_id", o.ClientID) - } - if o.ClientSecret != "" { - v.Set("client_secret", o.ClientSecret) - } - } - req, err := http.NewRequestWithContext(ctx, "POST", o.TokenURL, strings.NewReader(v.Encode())) - if err != nil { - return nil, refreshToken, err - } - req.Header.Set("Content-Type", "application/x-www-form-urlencoded") - if o.AuthStyle == StyleInHeader { - req.SetBasicAuth(url.QueryEscape(o.ClientID), url.QueryEscape(o.ClientSecret)) - } - logger := o.logger() - - logger.DebugContext(ctx, "3LO token request", "request", internallog.HTTPRequest(req, []byte(v.Encode()))) - // Make request - resp, body, err := internal.DoRequest(o.client(), req) - if err != nil { - return nil, refreshToken, err - } - logger.DebugContext(ctx, "3LO token response", "response", internallog.HTTPResponse(resp, body)) - failureStatus := resp.StatusCode < 200 || resp.StatusCode > 299 - tokError := &Error{ - Response: resp, - Body: body, - } - - var token *Token - // errors ignored because of default switch on content - content, _, _ := mime.ParseMediaType(resp.Header.Get("Content-Type")) - switch content { - case "application/x-www-form-urlencoded", "text/plain": - // some endpoints return a query string - vals, err := url.ParseQuery(string(body)) - if err != nil { - if failureStatus { - return nil, refreshToken, tokError - } - return nil, refreshToken, fmt.Errorf("auth: cannot parse response: %w", err) - } - tokError.code = vals.Get("error") - tokError.description = vals.Get("error_description") - tokError.uri = vals.Get("error_uri") - token = &Token{ - Value: vals.Get("access_token"), - Type: vals.Get("token_type"), - Metadata: make(map[string]interface{}, len(vals)), - } - for k, v := range vals { - token.Metadata[k] = v - } - refreshToken = vals.Get("refresh_token") - e := vals.Get("expires_in") - expires, _ := strconv.Atoi(e) - if expires != 0 { - token.Expiry = time.Now().Add(time.Duration(expires) * time.Second) - } - default: - var tj tokenJSON - if err = json.Unmarshal(body, &tj); err != nil { - if failureStatus { - return nil, refreshToken, tokError - } - return nil, refreshToken, fmt.Errorf("auth: cannot parse json: %w", err) - } - tokError.code = tj.ErrorCode - tokError.description = tj.ErrorDescription - tokError.uri = tj.ErrorURI - token = &Token{ - Value: tj.AccessToken, - Type: tj.TokenType, - Expiry: tj.expiry(), - Metadata: make(map[string]interface{}), - } - json.Unmarshal(body, &token.Metadata) // optional field, skip err check - refreshToken = tj.RefreshToken - } - // according to spec, servers should respond status 400 in error case - // https://www.rfc-editor.org/rfc/rfc6749#section-5.2 - // but some unorthodox servers respond 200 in error case - if failureStatus || tokError.code != "" { - return nil, refreshToken, tokError - } - if token.Value == "" { - return nil, refreshToken, errors.New("auth: server response missing access_token") - } - return token, refreshToken, nil -} diff --git a/vendor/cloud.google.com/go/compute/metadata/CHANGES.md b/vendor/cloud.google.com/go/compute/metadata/CHANGES.md deleted file mode 100644 index bcfb5d81..00000000 --- a/vendor/cloud.google.com/go/compute/metadata/CHANGES.md +++ /dev/null @@ -1,66 +0,0 @@ -# Changes - -## [0.6.0](https://github.com/googleapis/google-cloud-go/compare/compute/metadata/v0.5.2...compute/metadata/v0.6.0) (2024-12-13) - - -### Features - -* **compute/metadata:** Add debug logging ([#11078](https://github.com/googleapis/google-cloud-go/issues/11078)) ([a816814](https://github.com/googleapis/google-cloud-go/commit/a81681463906e4473570a2f426eb0dc2de64e53f)) - -## [0.5.2](https://github.com/googleapis/google-cloud-go/compare/compute/metadata/v0.5.1...compute/metadata/v0.5.2) (2024-09-20) - - -### Bug Fixes - -* **compute/metadata:** Close Response Body for failed request ([#10891](https://github.com/googleapis/google-cloud-go/issues/10891)) ([e91d45e](https://github.com/googleapis/google-cloud-go/commit/e91d45e4757a9e354114509ba9800085d9e0ff1f)) - -## [0.5.1](https://github.com/googleapis/google-cloud-go/compare/compute/metadata/v0.5.0...compute/metadata/v0.5.1) (2024-09-12) - - -### Bug Fixes - -* **compute/metadata:** Check error chain for retryable error ([#10840](https://github.com/googleapis/google-cloud-go/issues/10840)) ([2bdedef](https://github.com/googleapis/google-cloud-go/commit/2bdedeff621b223d63cebc4355fcf83bc68412cd)) - -## [0.5.0](https://github.com/googleapis/google-cloud-go/compare/compute/metadata/v0.4.0...compute/metadata/v0.5.0) (2024-07-10) - - -### Features - -* **compute/metadata:** Add sys check for windows OnGCE ([#10521](https://github.com/googleapis/google-cloud-go/issues/10521)) ([3b9a830](https://github.com/googleapis/google-cloud-go/commit/3b9a83063960d2a2ac20beb47cc15818a68bd302)) - -## [0.4.0](https://github.com/googleapis/google-cloud-go/compare/compute/metadata/v0.3.0...compute/metadata/v0.4.0) (2024-07-01) - - -### Features - -* **compute/metadata:** Add context for all functions/methods ([#10370](https://github.com/googleapis/google-cloud-go/issues/10370)) ([66b8efe](https://github.com/googleapis/google-cloud-go/commit/66b8efe7ad877e052b2987bb4475477e38c67bb3)) - - -### Documentation - -* **compute/metadata:** Update OnGCE description ([#10408](https://github.com/googleapis/google-cloud-go/issues/10408)) ([6a46dca](https://github.com/googleapis/google-cloud-go/commit/6a46dca4eae4f88ec6f88822e01e5bf8aeca787f)) - -## [0.3.0](https://github.com/googleapis/google-cloud-go/compare/compute/metadata/v0.2.3...compute/metadata/v0.3.0) (2024-04-15) - - -### Features - -* **compute/metadata:** Add context aware functions ([#9733](https://github.com/googleapis/google-cloud-go/issues/9733)) ([e4eb5b4](https://github.com/googleapis/google-cloud-go/commit/e4eb5b46ee2aec9d2fc18300bfd66015e25a0510)) - -## [0.2.3](https://github.com/googleapis/google-cloud-go/compare/compute/metadata/v0.2.2...compute/metadata/v0.2.3) (2022-12-15) - - -### Bug Fixes - -* **compute/metadata:** Switch DNS lookup to an absolute lookup ([119b410](https://github.com/googleapis/google-cloud-go/commit/119b41060c7895e45e48aee5621ad35607c4d021)), refs [#7165](https://github.com/googleapis/google-cloud-go/issues/7165) - -## [0.2.2](https://github.com/googleapis/google-cloud-go/compare/compute/metadata/v0.2.1...compute/metadata/v0.2.2) (2022-12-01) - - -### Bug Fixes - -* **compute/metadata:** Set IdleConnTimeout for http.Client ([#7084](https://github.com/googleapis/google-cloud-go/issues/7084)) ([766516a](https://github.com/googleapis/google-cloud-go/commit/766516aaf3816bfb3159efeea65aa3d1d205a3e2)), refs [#5430](https://github.com/googleapis/google-cloud-go/issues/5430) - -## [0.1.0] (2022-10-26) - -Initial release of metadata being it's own module. diff --git a/vendor/cloud.google.com/go/compute/metadata/LICENSE b/vendor/cloud.google.com/go/compute/metadata/LICENSE deleted file mode 100644 index d6456956..00000000 --- a/vendor/cloud.google.com/go/compute/metadata/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/cloud.google.com/go/compute/metadata/README.md b/vendor/cloud.google.com/go/compute/metadata/README.md deleted file mode 100644 index f940fb2c..00000000 --- a/vendor/cloud.google.com/go/compute/metadata/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# Compute API - -[![Go Reference](https://pkg.go.dev/badge/cloud.google.com/go/compute.svg)](https://pkg.go.dev/cloud.google.com/go/compute/metadata) - -This is a utility library for communicating with Google Cloud metadata service -on Google Cloud. - -## Install - -```bash -go get cloud.google.com/go/compute/metadata -``` - -## Go Version Support - -See the [Go Versions Supported](https://github.com/googleapis/google-cloud-go#go-versions-supported) -section in the root directory's README. - -## Contributing - -Contributions are welcome. Please, see the [CONTRIBUTING](https://github.com/GoogleCloudPlatform/google-cloud-go/blob/main/CONTRIBUTING.md) -document for details. - -Please note that this project is released with a Contributor Code of Conduct. -By participating in this project you agree to abide by its terms. See -[Contributor Code of Conduct](https://github.com/GoogleCloudPlatform/google-cloud-go/blob/main/CONTRIBUTING.md#contributor-code-of-conduct) -for more information. diff --git a/vendor/cloud.google.com/go/compute/metadata/log.go b/vendor/cloud.google.com/go/compute/metadata/log.go deleted file mode 100644 index 8ec673b8..00000000 --- a/vendor/cloud.google.com/go/compute/metadata/log.go +++ /dev/null @@ -1,149 +0,0 @@ -// Copyright 2024 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package metadata - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "log/slog" - "net/http" - "strings" -) - -// Code below this point is copied from github.com/googleapis/gax-go/v2/internallog -// to avoid the dependency. The compute/metadata module is used by too many -// non-client library modules that can't justify the dependency. - -// The handler returned if logging is not enabled. -type noOpHandler struct{} - -func (h noOpHandler) Enabled(_ context.Context, _ slog.Level) bool { - return false -} - -func (h noOpHandler) Handle(_ context.Context, _ slog.Record) error { - return nil -} - -func (h noOpHandler) WithAttrs(_ []slog.Attr) slog.Handler { - return h -} - -func (h noOpHandler) WithGroup(_ string) slog.Handler { - return h -} - -// httpRequest returns a lazily evaluated [slog.LogValuer] for a -// [http.Request] and the associated body. -func httpRequest(req *http.Request, body []byte) slog.LogValuer { - return &request{ - req: req, - payload: body, - } -} - -type request struct { - req *http.Request - payload []byte -} - -func (r *request) LogValue() slog.Value { - if r == nil || r.req == nil { - return slog.Value{} - } - var groupValueAttrs []slog.Attr - groupValueAttrs = append(groupValueAttrs, slog.String("method", r.req.Method)) - groupValueAttrs = append(groupValueAttrs, slog.String("url", r.req.URL.String())) - - var headerAttr []slog.Attr - for k, val := range r.req.Header { - headerAttr = append(headerAttr, slog.String(k, strings.Join(val, ","))) - } - if len(headerAttr) > 0 { - groupValueAttrs = append(groupValueAttrs, slog.Any("headers", headerAttr)) - } - - if len(r.payload) > 0 { - if attr, ok := processPayload(r.payload); ok { - groupValueAttrs = append(groupValueAttrs, attr) - } - } - return slog.GroupValue(groupValueAttrs...) -} - -// httpResponse returns a lazily evaluated [slog.LogValuer] for a -// [http.Response] and the associated body. -func httpResponse(resp *http.Response, body []byte) slog.LogValuer { - return &response{ - resp: resp, - payload: body, - } -} - -type response struct { - resp *http.Response - payload []byte -} - -func (r *response) LogValue() slog.Value { - if r == nil { - return slog.Value{} - } - var groupValueAttrs []slog.Attr - groupValueAttrs = append(groupValueAttrs, slog.String("status", fmt.Sprint(r.resp.StatusCode))) - - var headerAttr []slog.Attr - for k, val := range r.resp.Header { - headerAttr = append(headerAttr, slog.String(k, strings.Join(val, ","))) - } - if len(headerAttr) > 0 { - groupValueAttrs = append(groupValueAttrs, slog.Any("headers", headerAttr)) - } - - if len(r.payload) > 0 { - if attr, ok := processPayload(r.payload); ok { - groupValueAttrs = append(groupValueAttrs, attr) - } - } - return slog.GroupValue(groupValueAttrs...) -} - -func processPayload(payload []byte) (slog.Attr, bool) { - peekChar := payload[0] - if peekChar == '{' { - // JSON object - var m map[string]any - if err := json.Unmarshal(payload, &m); err == nil { - return slog.Any("payload", m), true - } - } else if peekChar == '[' { - // JSON array - var m []any - if err := json.Unmarshal(payload, &m); err == nil { - return slog.Any("payload", m), true - } - } else { - // Everything else - buf := &bytes.Buffer{} - if err := json.Compact(buf, payload); err != nil { - // Write raw payload incase of error - buf.Write(payload) - } - return slog.String("payload", buf.String()), true - } - return slog.Attr{}, false -} diff --git a/vendor/cloud.google.com/go/compute/metadata/metadata.go b/vendor/cloud.google.com/go/compute/metadata/metadata.go deleted file mode 100644 index 4c18a383..00000000 --- a/vendor/cloud.google.com/go/compute/metadata/metadata.go +++ /dev/null @@ -1,872 +0,0 @@ -// Copyright 2014 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package metadata provides access to Google Compute Engine (GCE) -// metadata and API service accounts. -// -// This package is a wrapper around the GCE metadata service, -// as documented at https://cloud.google.com/compute/docs/metadata/overview. -package metadata // import "cloud.google.com/go/compute/metadata" - -import ( - "context" - "encoding/json" - "fmt" - "io" - "log/slog" - "net" - "net/http" - "net/url" - "os" - "strings" - "sync" - "time" -) - -const ( - // metadataIP is the documented metadata server IP address. - metadataIP = "169.254.169.254" - - // metadataHostEnv is the environment variable specifying the - // GCE metadata hostname. If empty, the default value of - // metadataIP ("169.254.169.254") is used instead. - // This is variable name is not defined by any spec, as far as - // I know; it was made up for the Go package. - metadataHostEnv = "GCE_METADATA_HOST" - - userAgent = "gcloud-golang/0.1" -) - -type cachedValue struct { - k string - trim bool - mu sync.Mutex - v string -} - -var ( - projID = &cachedValue{k: "project/project-id", trim: true} - projNum = &cachedValue{k: "project/numeric-project-id", trim: true} - instID = &cachedValue{k: "instance/id", trim: true} -) - -var defaultClient = &Client{ - hc: newDefaultHTTPClient(), - logger: slog.New(noOpHandler{}), -} - -func newDefaultHTTPClient() *http.Client { - return &http.Client{ - Transport: &http.Transport{ - Dial: (&net.Dialer{ - Timeout: 2 * time.Second, - KeepAlive: 30 * time.Second, - }).Dial, - IdleConnTimeout: 60 * time.Second, - }, - Timeout: 5 * time.Second, - } -} - -// NotDefinedError is returned when requested metadata is not defined. -// -// The underlying string is the suffix after "/computeMetadata/v1/". -// -// This error is not returned if the value is defined to be the empty -// string. -type NotDefinedError string - -func (suffix NotDefinedError) Error() string { - return fmt.Sprintf("metadata: GCE metadata %q not defined", string(suffix)) -} - -func (c *cachedValue) get(ctx context.Context, cl *Client) (v string, err error) { - defer c.mu.Unlock() - c.mu.Lock() - if c.v != "" { - return c.v, nil - } - if c.trim { - v, err = cl.getTrimmed(ctx, c.k) - } else { - v, err = cl.GetWithContext(ctx, c.k) - } - if err == nil { - c.v = v - } - return -} - -var ( - onGCEOnce sync.Once - onGCE bool -) - -// OnGCE reports whether this process is running on Google Compute Platforms. -// NOTE: True returned from `OnGCE` does not guarantee that the metadata server -// is accessible from this process and have all the metadata defined. -func OnGCE() bool { - onGCEOnce.Do(initOnGCE) - return onGCE -} - -func initOnGCE() { - onGCE = testOnGCE() -} - -func testOnGCE() bool { - // The user explicitly said they're on GCE, so trust them. - if os.Getenv(metadataHostEnv) != "" { - return true - } - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - resc := make(chan bool, 2) - - // Try two strategies in parallel. - // See https://github.com/googleapis/google-cloud-go/issues/194 - go func() { - req, _ := http.NewRequest("GET", "http://"+metadataIP, nil) - req.Header.Set("User-Agent", userAgent) - res, err := newDefaultHTTPClient().Do(req.WithContext(ctx)) - if err != nil { - resc <- false - return - } - defer res.Body.Close() - resc <- res.Header.Get("Metadata-Flavor") == "Google" - }() - - go func() { - resolver := &net.Resolver{} - addrs, err := resolver.LookupHost(ctx, "metadata.google.internal.") - if err != nil || len(addrs) == 0 { - resc <- false - return - } - resc <- strsContains(addrs, metadataIP) - }() - - tryHarder := systemInfoSuggestsGCE() - if tryHarder { - res := <-resc - if res { - // The first strategy succeeded, so let's use it. - return true - } - // Wait for either the DNS or metadata server probe to - // contradict the other one and say we are running on - // GCE. Give it a lot of time to do so, since the system - // info already suggests we're running on a GCE BIOS. - timer := time.NewTimer(5 * time.Second) - defer timer.Stop() - select { - case res = <-resc: - return res - case <-timer.C: - // Too slow. Who knows what this system is. - return false - } - } - - // There's no hint from the system info that we're running on - // GCE, so use the first probe's result as truth, whether it's - // true or false. The goal here is to optimize for speed for - // users who are NOT running on GCE. We can't assume that - // either a DNS lookup or an HTTP request to a blackholed IP - // address is fast. Worst case this should return when the - // metaClient's Transport.ResponseHeaderTimeout or - // Transport.Dial.Timeout fires (in two seconds). - return <-resc -} - -// Subscribe calls Client.SubscribeWithContext on the default client. -// -// Deprecated: Please use the context aware variant [SubscribeWithContext]. -func Subscribe(suffix string, fn func(v string, ok bool) error) error { - return defaultClient.SubscribeWithContext(context.Background(), suffix, func(ctx context.Context, v string, ok bool) error { return fn(v, ok) }) -} - -// SubscribeWithContext calls Client.SubscribeWithContext on the default client. -func SubscribeWithContext(ctx context.Context, suffix string, fn func(ctx context.Context, v string, ok bool) error) error { - return defaultClient.SubscribeWithContext(ctx, suffix, fn) -} - -// Get calls Client.GetWithContext on the default client. -// -// Deprecated: Please use the context aware variant [GetWithContext]. -func Get(suffix string) (string, error) { - return defaultClient.GetWithContext(context.Background(), suffix) -} - -// GetWithContext calls Client.GetWithContext on the default client. -func GetWithContext(ctx context.Context, suffix string) (string, error) { - return defaultClient.GetWithContext(ctx, suffix) -} - -// ProjectID returns the current instance's project ID string. -// -// Deprecated: Please use the context aware variant [ProjectIDWithContext]. -func ProjectID() (string, error) { - return defaultClient.ProjectIDWithContext(context.Background()) -} - -// ProjectIDWithContext returns the current instance's project ID string. -func ProjectIDWithContext(ctx context.Context) (string, error) { - return defaultClient.ProjectIDWithContext(ctx) -} - -// NumericProjectID returns the current instance's numeric project ID. -// -// Deprecated: Please use the context aware variant [NumericProjectIDWithContext]. -func NumericProjectID() (string, error) { - return defaultClient.NumericProjectIDWithContext(context.Background()) -} - -// NumericProjectIDWithContext returns the current instance's numeric project ID. -func NumericProjectIDWithContext(ctx context.Context) (string, error) { - return defaultClient.NumericProjectIDWithContext(ctx) -} - -// InternalIP returns the instance's primary internal IP address. -// -// Deprecated: Please use the context aware variant [InternalIPWithContext]. -func InternalIP() (string, error) { - return defaultClient.InternalIPWithContext(context.Background()) -} - -// InternalIPWithContext returns the instance's primary internal IP address. -func InternalIPWithContext(ctx context.Context) (string, error) { - return defaultClient.InternalIPWithContext(ctx) -} - -// ExternalIP returns the instance's primary external (public) IP address. -// -// Deprecated: Please use the context aware variant [ExternalIPWithContext]. -func ExternalIP() (string, error) { - return defaultClient.ExternalIPWithContext(context.Background()) -} - -// ExternalIPWithContext returns the instance's primary external (public) IP address. -func ExternalIPWithContext(ctx context.Context) (string, error) { - return defaultClient.ExternalIPWithContext(ctx) -} - -// Email calls Client.EmailWithContext on the default client. -// -// Deprecated: Please use the context aware variant [EmailWithContext]. -func Email(serviceAccount string) (string, error) { - return defaultClient.EmailWithContext(context.Background(), serviceAccount) -} - -// EmailWithContext calls Client.EmailWithContext on the default client. -func EmailWithContext(ctx context.Context, serviceAccount string) (string, error) { - return defaultClient.EmailWithContext(ctx, serviceAccount) -} - -// Hostname returns the instance's hostname. This will be of the form -// ".c..internal". -// -// Deprecated: Please use the context aware variant [HostnameWithContext]. -func Hostname() (string, error) { - return defaultClient.HostnameWithContext(context.Background()) -} - -// HostnameWithContext returns the instance's hostname. This will be of the form -// ".c..internal". -func HostnameWithContext(ctx context.Context) (string, error) { - return defaultClient.HostnameWithContext(ctx) -} - -// InstanceTags returns the list of user-defined instance tags, -// assigned when initially creating a GCE instance. -// -// Deprecated: Please use the context aware variant [InstanceTagsWithContext]. -func InstanceTags() ([]string, error) { - return defaultClient.InstanceTagsWithContext(context.Background()) -} - -// InstanceTagsWithContext returns the list of user-defined instance tags, -// assigned when initially creating a GCE instance. -func InstanceTagsWithContext(ctx context.Context) ([]string, error) { - return defaultClient.InstanceTagsWithContext(ctx) -} - -// InstanceID returns the current VM's numeric instance ID. -// -// Deprecated: Please use the context aware variant [InstanceIDWithContext]. -func InstanceID() (string, error) { - return defaultClient.InstanceIDWithContext(context.Background()) -} - -// InstanceIDWithContext returns the current VM's numeric instance ID. -func InstanceIDWithContext(ctx context.Context) (string, error) { - return defaultClient.InstanceIDWithContext(ctx) -} - -// InstanceName returns the current VM's instance ID string. -// -// Deprecated: Please use the context aware variant [InstanceNameWithContext]. -func InstanceName() (string, error) { - return defaultClient.InstanceNameWithContext(context.Background()) -} - -// InstanceNameWithContext returns the current VM's instance ID string. -func InstanceNameWithContext(ctx context.Context) (string, error) { - return defaultClient.InstanceNameWithContext(ctx) -} - -// Zone returns the current VM's zone, such as "us-central1-b". -// -// Deprecated: Please use the context aware variant [ZoneWithContext]. -func Zone() (string, error) { - return defaultClient.ZoneWithContext(context.Background()) -} - -// ZoneWithContext returns the current VM's zone, such as "us-central1-b". -func ZoneWithContext(ctx context.Context) (string, error) { - return defaultClient.ZoneWithContext(ctx) -} - -// InstanceAttributes calls Client.InstanceAttributesWithContext on the default client. -// -// Deprecated: Please use the context aware variant [InstanceAttributesWithContext. -func InstanceAttributes() ([]string, error) { - return defaultClient.InstanceAttributesWithContext(context.Background()) -} - -// InstanceAttributesWithContext calls Client.ProjectAttributesWithContext on the default client. -func InstanceAttributesWithContext(ctx context.Context) ([]string, error) { - return defaultClient.InstanceAttributesWithContext(ctx) -} - -// ProjectAttributes calls Client.ProjectAttributesWithContext on the default client. -// -// Deprecated: Please use the context aware variant [ProjectAttributesWithContext]. -func ProjectAttributes() ([]string, error) { - return defaultClient.ProjectAttributesWithContext(context.Background()) -} - -// ProjectAttributesWithContext calls Client.ProjectAttributesWithContext on the default client. -func ProjectAttributesWithContext(ctx context.Context) ([]string, error) { - return defaultClient.ProjectAttributesWithContext(ctx) -} - -// InstanceAttributeValue calls Client.InstanceAttributeValueWithContext on the default client. -// -// Deprecated: Please use the context aware variant [InstanceAttributeValueWithContext]. -func InstanceAttributeValue(attr string) (string, error) { - return defaultClient.InstanceAttributeValueWithContext(context.Background(), attr) -} - -// InstanceAttributeValueWithContext calls Client.InstanceAttributeValueWithContext on the default client. -func InstanceAttributeValueWithContext(ctx context.Context, attr string) (string, error) { - return defaultClient.InstanceAttributeValueWithContext(ctx, attr) -} - -// ProjectAttributeValue calls Client.ProjectAttributeValueWithContext on the default client. -// -// Deprecated: Please use the context aware variant [ProjectAttributeValueWithContext]. -func ProjectAttributeValue(attr string) (string, error) { - return defaultClient.ProjectAttributeValueWithContext(context.Background(), attr) -} - -// ProjectAttributeValueWithContext calls Client.ProjectAttributeValueWithContext on the default client. -func ProjectAttributeValueWithContext(ctx context.Context, attr string) (string, error) { - return defaultClient.ProjectAttributeValueWithContext(ctx, attr) -} - -// Scopes calls Client.ScopesWithContext on the default client. -// -// Deprecated: Please use the context aware variant [ScopesWithContext]. -func Scopes(serviceAccount string) ([]string, error) { - return defaultClient.ScopesWithContext(context.Background(), serviceAccount) -} - -// ScopesWithContext calls Client.ScopesWithContext on the default client. -func ScopesWithContext(ctx context.Context, serviceAccount string) ([]string, error) { - return defaultClient.ScopesWithContext(ctx, serviceAccount) -} - -func strsContains(ss []string, s string) bool { - for _, v := range ss { - if v == s { - return true - } - } - return false -} - -// A Client provides metadata. -type Client struct { - hc *http.Client - logger *slog.Logger -} - -// Options for configuring a [Client]. -type Options struct { - // Client is the HTTP client used to make requests. Optional. - Client *http.Client - // Logger is used to log information about HTTP request and responses. - // If not provided, nothing will be logged. Optional. - Logger *slog.Logger -} - -// NewClient returns a Client that can be used to fetch metadata. -// Returns the client that uses the specified http.Client for HTTP requests. -// If nil is specified, returns the default client. -func NewClient(c *http.Client) *Client { - return NewWithOptions(&Options{ - Client: c, - }) -} - -// NewWithOptions returns a Client that is configured with the provided Options. -func NewWithOptions(opts *Options) *Client { - if opts == nil { - return defaultClient - } - client := opts.Client - if client == nil { - client = newDefaultHTTPClient() - } - logger := opts.Logger - if logger == nil { - logger = slog.New(noOpHandler{}) - } - return &Client{hc: client, logger: logger} -} - -// getETag returns a value from the metadata service as well as the associated ETag. -// This func is otherwise equivalent to Get. -func (c *Client) getETag(ctx context.Context, suffix string) (value, etag string, err error) { - // Using a fixed IP makes it very difficult to spoof the metadata service in - // a container, which is an important use-case for local testing of cloud - // deployments. To enable spoofing of the metadata service, the environment - // variable GCE_METADATA_HOST is first inspected to decide where metadata - // requests shall go. - host := os.Getenv(metadataHostEnv) - if host == "" { - // Using 169.254.169.254 instead of "metadata" here because Go - // binaries built with the "netgo" tag and without cgo won't - // know the search suffix for "metadata" is - // ".google.internal", and this IP address is documented as - // being stable anyway. - host = metadataIP - } - suffix = strings.TrimLeft(suffix, "/") - u := "http://" + host + "/computeMetadata/v1/" + suffix - req, err := http.NewRequestWithContext(ctx, "GET", u, nil) - if err != nil { - return "", "", err - } - req.Header.Set("Metadata-Flavor", "Google") - req.Header.Set("User-Agent", userAgent) - var res *http.Response - var reqErr error - var body []byte - retryer := newRetryer() - for { - c.logger.DebugContext(ctx, "metadata request", "request", httpRequest(req, nil)) - res, reqErr = c.hc.Do(req) - var code int - if res != nil { - code = res.StatusCode - body, err = io.ReadAll(res.Body) - if err != nil { - res.Body.Close() - return "", "", err - } - c.logger.DebugContext(ctx, "metadata response", "response", httpResponse(res, body)) - res.Body.Close() - } - if delay, shouldRetry := retryer.Retry(code, reqErr); shouldRetry { - if res != nil && res.Body != nil { - res.Body.Close() - } - if err := sleep(ctx, delay); err != nil { - return "", "", err - } - continue - } - break - } - if reqErr != nil { - return "", "", reqErr - } - if res.StatusCode == http.StatusNotFound { - return "", "", NotDefinedError(suffix) - } - if res.StatusCode != 200 { - return "", "", &Error{Code: res.StatusCode, Message: string(body)} - } - return string(body), res.Header.Get("Etag"), nil -} - -// Get returns a value from the metadata service. -// The suffix is appended to "http://${GCE_METADATA_HOST}/computeMetadata/v1/". -// -// If the GCE_METADATA_HOST environment variable is not defined, a default of -// 169.254.169.254 will be used instead. -// -// If the requested metadata is not defined, the returned error will -// be of type NotDefinedError. -// -// Deprecated: Please use the context aware variant [Client.GetWithContext]. -func (c *Client) Get(suffix string) (string, error) { - return c.GetWithContext(context.Background(), suffix) -} - -// GetWithContext returns a value from the metadata service. -// The suffix is appended to "http://${GCE_METADATA_HOST}/computeMetadata/v1/". -// -// If the GCE_METADATA_HOST environment variable is not defined, a default of -// 169.254.169.254 will be used instead. -// -// If the requested metadata is not defined, the returned error will -// be of type NotDefinedError. -// -// NOTE: Without an extra deadline in the context this call can take in the -// worst case, with internal backoff retries, up to 15 seconds (e.g. when server -// is responding slowly). Pass context with additional timeouts when needed. -func (c *Client) GetWithContext(ctx context.Context, suffix string) (string, error) { - val, _, err := c.getETag(ctx, suffix) - return val, err -} - -func (c *Client) getTrimmed(ctx context.Context, suffix string) (s string, err error) { - s, err = c.GetWithContext(ctx, suffix) - s = strings.TrimSpace(s) - return -} - -func (c *Client) lines(ctx context.Context, suffix string) ([]string, error) { - j, err := c.GetWithContext(ctx, suffix) - if err != nil { - return nil, err - } - s := strings.Split(strings.TrimSpace(j), "\n") - for i := range s { - s[i] = strings.TrimSpace(s[i]) - } - return s, nil -} - -// ProjectID returns the current instance's project ID string. -// -// Deprecated: Please use the context aware variant [Client.ProjectIDWithContext]. -func (c *Client) ProjectID() (string, error) { return c.ProjectIDWithContext(context.Background()) } - -// ProjectIDWithContext returns the current instance's project ID string. -func (c *Client) ProjectIDWithContext(ctx context.Context) (string, error) { return projID.get(ctx, c) } - -// NumericProjectID returns the current instance's numeric project ID. -// -// Deprecated: Please use the context aware variant [Client.NumericProjectIDWithContext]. -func (c *Client) NumericProjectID() (string, error) { - return c.NumericProjectIDWithContext(context.Background()) -} - -// NumericProjectIDWithContext returns the current instance's numeric project ID. -func (c *Client) NumericProjectIDWithContext(ctx context.Context) (string, error) { - return projNum.get(ctx, c) -} - -// InstanceID returns the current VM's numeric instance ID. -// -// Deprecated: Please use the context aware variant [Client.InstanceIDWithContext]. -func (c *Client) InstanceID() (string, error) { - return c.InstanceIDWithContext(context.Background()) -} - -// InstanceIDWithContext returns the current VM's numeric instance ID. -func (c *Client) InstanceIDWithContext(ctx context.Context) (string, error) { - return instID.get(ctx, c) -} - -// InternalIP returns the instance's primary internal IP address. -// -// Deprecated: Please use the context aware variant [Client.InternalIPWithContext]. -func (c *Client) InternalIP() (string, error) { - return c.InternalIPWithContext(context.Background()) -} - -// InternalIPWithContext returns the instance's primary internal IP address. -func (c *Client) InternalIPWithContext(ctx context.Context) (string, error) { - return c.getTrimmed(ctx, "instance/network-interfaces/0/ip") -} - -// Email returns the email address associated with the service account. -// -// Deprecated: Please use the context aware variant [Client.EmailWithContext]. -func (c *Client) Email(serviceAccount string) (string, error) { - return c.EmailWithContext(context.Background(), serviceAccount) -} - -// EmailWithContext returns the email address associated with the service account. -// The serviceAccount parameter default value (empty string or "default" value) -// will use the instance's main account. -func (c *Client) EmailWithContext(ctx context.Context, serviceAccount string) (string, error) { - if serviceAccount == "" { - serviceAccount = "default" - } - return c.getTrimmed(ctx, "instance/service-accounts/"+serviceAccount+"/email") -} - -// ExternalIP returns the instance's primary external (public) IP address. -// -// Deprecated: Please use the context aware variant [Client.ExternalIPWithContext]. -func (c *Client) ExternalIP() (string, error) { - return c.ExternalIPWithContext(context.Background()) -} - -// ExternalIPWithContext returns the instance's primary external (public) IP address. -func (c *Client) ExternalIPWithContext(ctx context.Context) (string, error) { - return c.getTrimmed(ctx, "instance/network-interfaces/0/access-configs/0/external-ip") -} - -// Hostname returns the instance's hostname. This will be of the form -// ".c..internal". -// -// Deprecated: Please use the context aware variant [Client.HostnameWithContext]. -func (c *Client) Hostname() (string, error) { - return c.HostnameWithContext(context.Background()) -} - -// HostnameWithContext returns the instance's hostname. This will be of the form -// ".c..internal". -func (c *Client) HostnameWithContext(ctx context.Context) (string, error) { - return c.getTrimmed(ctx, "instance/hostname") -} - -// InstanceTags returns the list of user-defined instance tags. -// -// Deprecated: Please use the context aware variant [Client.InstanceTagsWithContext]. -func (c *Client) InstanceTags() ([]string, error) { - return c.InstanceTagsWithContext(context.Background()) -} - -// InstanceTagsWithContext returns the list of user-defined instance tags, -// assigned when initially creating a GCE instance. -func (c *Client) InstanceTagsWithContext(ctx context.Context) ([]string, error) { - var s []string - j, err := c.GetWithContext(ctx, "instance/tags") - if err != nil { - return nil, err - } - if err := json.NewDecoder(strings.NewReader(j)).Decode(&s); err != nil { - return nil, err - } - return s, nil -} - -// InstanceName returns the current VM's instance ID string. -// -// Deprecated: Please use the context aware variant [Client.InstanceNameWithContext]. -func (c *Client) InstanceName() (string, error) { - return c.InstanceNameWithContext(context.Background()) -} - -// InstanceNameWithContext returns the current VM's instance ID string. -func (c *Client) InstanceNameWithContext(ctx context.Context) (string, error) { - return c.getTrimmed(ctx, "instance/name") -} - -// Zone returns the current VM's zone, such as "us-central1-b". -// -// Deprecated: Please use the context aware variant [Client.ZoneWithContext]. -func (c *Client) Zone() (string, error) { - return c.ZoneWithContext(context.Background()) -} - -// ZoneWithContext returns the current VM's zone, such as "us-central1-b". -func (c *Client) ZoneWithContext(ctx context.Context) (string, error) { - zone, err := c.getTrimmed(ctx, "instance/zone") - // zone is of the form "projects//zones/". - if err != nil { - return "", err - } - return zone[strings.LastIndex(zone, "/")+1:], nil -} - -// InstanceAttributes returns the list of user-defined attributes, -// assigned when initially creating a GCE VM instance. The value of an -// attribute can be obtained with InstanceAttributeValue. -// -// Deprecated: Please use the context aware variant [Client.InstanceAttributesWithContext]. -func (c *Client) InstanceAttributes() ([]string, error) { - return c.InstanceAttributesWithContext(context.Background()) -} - -// InstanceAttributesWithContext returns the list of user-defined attributes, -// assigned when initially creating a GCE VM instance. The value of an -// attribute can be obtained with InstanceAttributeValue. -func (c *Client) InstanceAttributesWithContext(ctx context.Context) ([]string, error) { - return c.lines(ctx, "instance/attributes/") -} - -// ProjectAttributes returns the list of user-defined attributes -// applying to the project as a whole, not just this VM. The value of -// an attribute can be obtained with ProjectAttributeValue. -// -// Deprecated: Please use the context aware variant [Client.ProjectAttributesWithContext]. -func (c *Client) ProjectAttributes() ([]string, error) { - return c.ProjectAttributesWithContext(context.Background()) -} - -// ProjectAttributesWithContext returns the list of user-defined attributes -// applying to the project as a whole, not just this VM. The value of -// an attribute can be obtained with ProjectAttributeValue. -func (c *Client) ProjectAttributesWithContext(ctx context.Context) ([]string, error) { - return c.lines(ctx, "project/attributes/") -} - -// InstanceAttributeValue returns the value of the provided VM -// instance attribute. -// -// If the requested attribute is not defined, the returned error will -// be of type NotDefinedError. -// -// InstanceAttributeValue may return ("", nil) if the attribute was -// defined to be the empty string. -// -// Deprecated: Please use the context aware variant [Client.InstanceAttributeValueWithContext]. -func (c *Client) InstanceAttributeValue(attr string) (string, error) { - return c.InstanceAttributeValueWithContext(context.Background(), attr) -} - -// InstanceAttributeValueWithContext returns the value of the provided VM -// instance attribute. -// -// If the requested attribute is not defined, the returned error will -// be of type NotDefinedError. -// -// InstanceAttributeValue may return ("", nil) if the attribute was -// defined to be the empty string. -func (c *Client) InstanceAttributeValueWithContext(ctx context.Context, attr string) (string, error) { - return c.GetWithContext(ctx, "instance/attributes/"+attr) -} - -// ProjectAttributeValue returns the value of the provided -// project attribute. -// -// If the requested attribute is not defined, the returned error will -// be of type NotDefinedError. -// -// ProjectAttributeValue may return ("", nil) if the attribute was -// defined to be the empty string. -// -// Deprecated: Please use the context aware variant [Client.ProjectAttributeValueWithContext]. -func (c *Client) ProjectAttributeValue(attr string) (string, error) { - return c.ProjectAttributeValueWithContext(context.Background(), attr) -} - -// ProjectAttributeValueWithContext returns the value of the provided -// project attribute. -// -// If the requested attribute is not defined, the returned error will -// be of type NotDefinedError. -// -// ProjectAttributeValue may return ("", nil) if the attribute was -// defined to be the empty string. -func (c *Client) ProjectAttributeValueWithContext(ctx context.Context, attr string) (string, error) { - return c.GetWithContext(ctx, "project/attributes/"+attr) -} - -// Scopes returns the service account scopes for the given account. -// The account may be empty or the string "default" to use the instance's -// main account. -// -// Deprecated: Please use the context aware variant [Client.ScopesWithContext]. -func (c *Client) Scopes(serviceAccount string) ([]string, error) { - return c.ScopesWithContext(context.Background(), serviceAccount) -} - -// ScopesWithContext returns the service account scopes for the given account. -// The account may be empty or the string "default" to use the instance's -// main account. -func (c *Client) ScopesWithContext(ctx context.Context, serviceAccount string) ([]string, error) { - if serviceAccount == "" { - serviceAccount = "default" - } - return c.lines(ctx, "instance/service-accounts/"+serviceAccount+"/scopes") -} - -// Subscribe subscribes to a value from the metadata service. -// The suffix is appended to "http://${GCE_METADATA_HOST}/computeMetadata/v1/". -// The suffix may contain query parameters. -// -// Deprecated: Please use the context aware variant [Client.SubscribeWithContext]. -func (c *Client) Subscribe(suffix string, fn func(v string, ok bool) error) error { - return c.SubscribeWithContext(context.Background(), suffix, func(ctx context.Context, v string, ok bool) error { return fn(v, ok) }) -} - -// SubscribeWithContext subscribes to a value from the metadata service. -// The suffix is appended to "http://${GCE_METADATA_HOST}/computeMetadata/v1/". -// The suffix may contain query parameters. -// -// SubscribeWithContext calls fn with the latest metadata value indicated by the -// provided suffix. If the metadata value is deleted, fn is called with the -// empty string and ok false. Subscribe blocks until fn returns a non-nil error -// or the value is deleted. Subscribe returns the error value returned from the -// last call to fn, which may be nil when ok == false. -func (c *Client) SubscribeWithContext(ctx context.Context, suffix string, fn func(ctx context.Context, v string, ok bool) error) error { - const failedSubscribeSleep = time.Second * 5 - - // First check to see if the metadata value exists at all. - val, lastETag, err := c.getETag(ctx, suffix) - if err != nil { - return err - } - - if err := fn(ctx, val, true); err != nil { - return err - } - - ok := true - if strings.ContainsRune(suffix, '?') { - suffix += "&wait_for_change=true&last_etag=" - } else { - suffix += "?wait_for_change=true&last_etag=" - } - for { - val, etag, err := c.getETag(ctx, suffix+url.QueryEscape(lastETag)) - if err != nil { - if _, deleted := err.(NotDefinedError); !deleted { - time.Sleep(failedSubscribeSleep) - continue // Retry on other errors. - } - ok = false - } - lastETag = etag - - if err := fn(ctx, val, ok); err != nil || !ok { - return err - } - } -} - -// Error contains an error response from the server. -type Error struct { - // Code is the HTTP response status code. - Code int - // Message is the server response message. - Message string -} - -func (e *Error) Error() string { - return fmt.Sprintf("compute: Received %d `%s`", e.Code, e.Message) -} diff --git a/vendor/cloud.google.com/go/compute/metadata/retry.go b/vendor/cloud.google.com/go/compute/metadata/retry.go deleted file mode 100644 index 3d4bc75d..00000000 --- a/vendor/cloud.google.com/go/compute/metadata/retry.go +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright 2021 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package metadata - -import ( - "context" - "io" - "math/rand" - "net/http" - "time" -) - -const ( - maxRetryAttempts = 5 -) - -var ( - syscallRetryable = func(error) bool { return false } -) - -// defaultBackoff is basically equivalent to gax.Backoff without the need for -// the dependency. -type defaultBackoff struct { - max time.Duration - mul float64 - cur time.Duration -} - -func (b *defaultBackoff) Pause() time.Duration { - d := time.Duration(1 + rand.Int63n(int64(b.cur))) - b.cur = time.Duration(float64(b.cur) * b.mul) - if b.cur > b.max { - b.cur = b.max - } - return d -} - -// sleep is the equivalent of gax.Sleep without the need for the dependency. -func sleep(ctx context.Context, d time.Duration) error { - t := time.NewTimer(d) - select { - case <-ctx.Done(): - t.Stop() - return ctx.Err() - case <-t.C: - return nil - } -} - -func newRetryer() *metadataRetryer { - return &metadataRetryer{bo: &defaultBackoff{ - cur: 100 * time.Millisecond, - max: 30 * time.Second, - mul: 2, - }} -} - -type backoff interface { - Pause() time.Duration -} - -type metadataRetryer struct { - bo backoff - attempts int -} - -func (r *metadataRetryer) Retry(status int, err error) (time.Duration, bool) { - if status == http.StatusOK { - return 0, false - } - retryOk := shouldRetry(status, err) - if !retryOk { - return 0, false - } - if r.attempts == maxRetryAttempts { - return 0, false - } - r.attempts++ - return r.bo.Pause(), true -} - -func shouldRetry(status int, err error) bool { - if 500 <= status && status <= 599 { - return true - } - if err == io.ErrUnexpectedEOF { - return true - } - // Transient network errors should be retried. - if syscallRetryable(err) { - return true - } - if err, ok := err.(interface{ Temporary() bool }); ok { - if err.Temporary() { - return true - } - } - if err, ok := err.(interface{ Unwrap() error }); ok { - return shouldRetry(status, err.Unwrap()) - } - return false -} diff --git a/vendor/cloud.google.com/go/compute/metadata/retry_linux.go b/vendor/cloud.google.com/go/compute/metadata/retry_linux.go deleted file mode 100644 index 2e53f012..00000000 --- a/vendor/cloud.google.com/go/compute/metadata/retry_linux.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2021 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build linux -// +build linux - -package metadata - -import ( - "errors" - "syscall" -) - -func init() { - // Initialize syscallRetryable to return true on transient socket-level - // errors. These errors are specific to Linux. - syscallRetryable = func(err error) bool { - return errors.Is(err, syscall.ECONNRESET) || errors.Is(err, syscall.ECONNREFUSED) - } -} diff --git a/vendor/cloud.google.com/go/compute/metadata/syscheck.go b/vendor/cloud.google.com/go/compute/metadata/syscheck.go deleted file mode 100644 index e0704fa6..00000000 --- a/vendor/cloud.google.com/go/compute/metadata/syscheck.go +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2024 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build !windows && !linux - -package metadata - -// systemInfoSuggestsGCE reports whether the local system (without -// doing network requests) suggests that we're running on GCE. If this -// returns true, testOnGCE tries a bit harder to reach its metadata -// server. -func systemInfoSuggestsGCE() bool { - // We don't currently have checks for other GOOS - return false -} diff --git a/vendor/cloud.google.com/go/compute/metadata/syscheck_linux.go b/vendor/cloud.google.com/go/compute/metadata/syscheck_linux.go deleted file mode 100644 index 74689acb..00000000 --- a/vendor/cloud.google.com/go/compute/metadata/syscheck_linux.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2024 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build linux - -package metadata - -import ( - "os" - "strings" -) - -func systemInfoSuggestsGCE() bool { - b, _ := os.ReadFile("/sys/class/dmi/id/product_name") - name := strings.TrimSpace(string(b)) - return name == "Google" || name == "Google Compute Engine" -} diff --git a/vendor/cloud.google.com/go/compute/metadata/syscheck_windows.go b/vendor/cloud.google.com/go/compute/metadata/syscheck_windows.go deleted file mode 100644 index c0ce6278..00000000 --- a/vendor/cloud.google.com/go/compute/metadata/syscheck_windows.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2024 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build windows - -package metadata - -import ( - "strings" - - "golang.org/x/sys/windows/registry" -) - -func systemInfoSuggestsGCE() bool { - k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SYSTEM\HardwareConfig\Current`, registry.QUERY_VALUE) - if err != nil { - return false - } - defer k.Close() - - s, _, err := k.GetStringValue("SystemProductName") - if err != nil { - return false - } - s = strings.TrimSpace(s) - return strings.HasPrefix(s, "Google") -} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/LICENSE.txt b/vendor/github.com/Azure/azure-sdk-for-go/LICENSE.txt deleted file mode 100644 index 05b0ebf5..00000000 --- a/vendor/github.com/Azure/azure-sdk-for-go/LICENSE.txt +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) Microsoft Corporation. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/Azure/azure-sdk-for-go/NOTICE.txt b/vendor/github.com/Azure/azure-sdk-for-go/NOTICE.txt deleted file mode 100644 index a338672e..00000000 --- a/vendor/github.com/Azure/azure-sdk-for-go/NOTICE.txt +++ /dev/null @@ -1,29 +0,0 @@ -NOTICES AND INFORMATION -Do Not Translate or Localize - -This software incorporates material from third parties. Microsoft makes certain -open source code available at https://3rdpartysource.microsoft.com, or you may -send a check or money order for US $5.00, including the product name, the open -source component name, and version number, to: - -Source Code Compliance Team -Microsoft Corporation -One Microsoft Way -Redmond, WA 98052 -USA - -Notwithstanding any other terms, you may reverse engineer this software to the -extent required to debug changes to any libraries licensed under the GNU Lesser -General Public License. - ------------------------------------------------------------------------------- - -Azure SDK for Go uses third-party libraries or other resources that may be -distributed under licenses different than the Azure SDK for Go software. - -In the event that we accidentally failed to list a required notice, please -bring it to our attention. Post an issue or email us: - - azgosdkhelp@microsoft.com - -The attached notices are provided for information only. diff --git a/vendor/github.com/Azure/azure-sdk-for-go/profiles/latest/dns/mgmt/dns/models.go b/vendor/github.com/Azure/azure-sdk-for-go/profiles/latest/dns/mgmt/dns/models.go deleted file mode 100644 index 34f8b023..00000000 --- a/vendor/github.com/Azure/azure-sdk-for-go/profiles/latest/dns/mgmt/dns/models.go +++ /dev/null @@ -1,128 +0,0 @@ -//go:build go1.9 -// +build go1.9 - -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See License.txt in the project root for license information. - -// This code was auto-generated by: -// github.com/Azure/azure-sdk-for-go/eng/tools/profileBuilder - -package dns - -import ( - "context" - - original "github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns" -) - -const ( - DefaultBaseURI = original.DefaultBaseURI -) - -type RecordType = original.RecordType - -const ( - A RecordType = original.A - AAAA RecordType = original.AAAA - CAA RecordType = original.CAA - CNAME RecordType = original.CNAME - MX RecordType = original.MX - NS RecordType = original.NS - PTR RecordType = original.PTR - SOA RecordType = original.SOA - SRV RecordType = original.SRV - TXT RecordType = original.TXT -) - -type ZoneType = original.ZoneType - -const ( - Private ZoneType = original.Private - Public ZoneType = original.Public -) - -type ARecord = original.ARecord -type AaaaRecord = original.AaaaRecord -type BaseClient = original.BaseClient -type CaaRecord = original.CaaRecord -type CloudError = original.CloudError -type CloudErrorBody = original.CloudErrorBody -type CnameRecord = original.CnameRecord -type MxRecord = original.MxRecord -type NsRecord = original.NsRecord -type PtrRecord = original.PtrRecord -type RecordSet = original.RecordSet -type RecordSetListResult = original.RecordSetListResult -type RecordSetListResultIterator = original.RecordSetListResultIterator -type RecordSetListResultPage = original.RecordSetListResultPage -type RecordSetProperties = original.RecordSetProperties -type RecordSetUpdateParameters = original.RecordSetUpdateParameters -type RecordSetsClient = original.RecordSetsClient -type Resource = original.Resource -type ResourceReference = original.ResourceReference -type ResourceReferenceClient = original.ResourceReferenceClient -type ResourceReferenceRequest = original.ResourceReferenceRequest -type ResourceReferenceRequestProperties = original.ResourceReferenceRequestProperties -type ResourceReferenceResult = original.ResourceReferenceResult -type ResourceReferenceResultProperties = original.ResourceReferenceResultProperties -type SoaRecord = original.SoaRecord -type SrvRecord = original.SrvRecord -type SubResource = original.SubResource -type TxtRecord = original.TxtRecord -type Zone = original.Zone -type ZoneListResult = original.ZoneListResult -type ZoneListResultIterator = original.ZoneListResultIterator -type ZoneListResultPage = original.ZoneListResultPage -type ZoneProperties = original.ZoneProperties -type ZoneUpdate = original.ZoneUpdate -type ZonesClient = original.ZonesClient -type ZonesDeleteFuture = original.ZonesDeleteFuture - -func New(subscriptionID string) BaseClient { - return original.New(subscriptionID) -} -func NewRecordSetListResultIterator(page RecordSetListResultPage) RecordSetListResultIterator { - return original.NewRecordSetListResultIterator(page) -} -func NewRecordSetListResultPage(cur RecordSetListResult, getNextPage func(context.Context, RecordSetListResult) (RecordSetListResult, error)) RecordSetListResultPage { - return original.NewRecordSetListResultPage(cur, getNextPage) -} -func NewRecordSetsClient(subscriptionID string) RecordSetsClient { - return original.NewRecordSetsClient(subscriptionID) -} -func NewRecordSetsClientWithBaseURI(baseURI string, subscriptionID string) RecordSetsClient { - return original.NewRecordSetsClientWithBaseURI(baseURI, subscriptionID) -} -func NewResourceReferenceClient(subscriptionID string) ResourceReferenceClient { - return original.NewResourceReferenceClient(subscriptionID) -} -func NewResourceReferenceClientWithBaseURI(baseURI string, subscriptionID string) ResourceReferenceClient { - return original.NewResourceReferenceClientWithBaseURI(baseURI, subscriptionID) -} -func NewWithBaseURI(baseURI string, subscriptionID string) BaseClient { - return original.NewWithBaseURI(baseURI, subscriptionID) -} -func NewZoneListResultIterator(page ZoneListResultPage) ZoneListResultIterator { - return original.NewZoneListResultIterator(page) -} -func NewZoneListResultPage(cur ZoneListResult, getNextPage func(context.Context, ZoneListResult) (ZoneListResult, error)) ZoneListResultPage { - return original.NewZoneListResultPage(cur, getNextPage) -} -func NewZonesClient(subscriptionID string) ZonesClient { - return original.NewZonesClient(subscriptionID) -} -func NewZonesClientWithBaseURI(baseURI string, subscriptionID string) ZonesClient { - return original.NewZonesClientWithBaseURI(baseURI, subscriptionID) -} -func PossibleRecordTypeValues() []RecordType { - return original.PossibleRecordTypeValues() -} -func PossibleZoneTypeValues() []ZoneType { - return original.PossibleZoneTypeValues() -} -func UserAgent() string { - return original.UserAgent() + " profiles/latest" -} -func Version() string { - return original.Version() -} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/profiles/latest/privatedns/mgmt/privatedns/models.go b/vendor/github.com/Azure/azure-sdk-for-go/profiles/latest/privatedns/mgmt/privatedns/models.go deleted file mode 100644 index e11287f1..00000000 --- a/vendor/github.com/Azure/azure-sdk-for-go/profiles/latest/privatedns/mgmt/privatedns/models.go +++ /dev/null @@ -1,149 +0,0 @@ -//go:build go1.9 -// +build go1.9 - -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See License.txt in the project root for license information. - -// This code was auto-generated by: -// github.com/Azure/azure-sdk-for-go/eng/tools/profileBuilder - -package privatedns - -import ( - "context" - - original "github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2020-06-01/privatedns" -) - -const ( - DefaultBaseURI = original.DefaultBaseURI -) - -type ProvisioningState = original.ProvisioningState - -const ( - Canceled ProvisioningState = original.Canceled - Creating ProvisioningState = original.Creating - Deleting ProvisioningState = original.Deleting - Failed ProvisioningState = original.Failed - Succeeded ProvisioningState = original.Succeeded - Updating ProvisioningState = original.Updating -) - -type RecordType = original.RecordType - -const ( - A RecordType = original.A - AAAA RecordType = original.AAAA - CNAME RecordType = original.CNAME - MX RecordType = original.MX - PTR RecordType = original.PTR - SOA RecordType = original.SOA - SRV RecordType = original.SRV - TXT RecordType = original.TXT -) - -type VirtualNetworkLinkState = original.VirtualNetworkLinkState - -const ( - Completed VirtualNetworkLinkState = original.Completed - InProgress VirtualNetworkLinkState = original.InProgress -) - -type ARecord = original.ARecord -type AaaaRecord = original.AaaaRecord -type BaseClient = original.BaseClient -type CloudError = original.CloudError -type CloudErrorBody = original.CloudErrorBody -type CnameRecord = original.CnameRecord -type MxRecord = original.MxRecord -type PrivateZone = original.PrivateZone -type PrivateZoneListResult = original.PrivateZoneListResult -type PrivateZoneListResultIterator = original.PrivateZoneListResultIterator -type PrivateZoneListResultPage = original.PrivateZoneListResultPage -type PrivateZoneProperties = original.PrivateZoneProperties -type PrivateZonesClient = original.PrivateZonesClient -type PrivateZonesCreateOrUpdateFuture = original.PrivateZonesCreateOrUpdateFuture -type PrivateZonesDeleteFuture = original.PrivateZonesDeleteFuture -type PrivateZonesUpdateFuture = original.PrivateZonesUpdateFuture -type ProxyResource = original.ProxyResource -type PtrRecord = original.PtrRecord -type RecordSet = original.RecordSet -type RecordSetListResult = original.RecordSetListResult -type RecordSetListResultIterator = original.RecordSetListResultIterator -type RecordSetListResultPage = original.RecordSetListResultPage -type RecordSetProperties = original.RecordSetProperties -type RecordSetsClient = original.RecordSetsClient -type Resource = original.Resource -type SoaRecord = original.SoaRecord -type SrvRecord = original.SrvRecord -type SubResource = original.SubResource -type TrackedResource = original.TrackedResource -type TxtRecord = original.TxtRecord -type VirtualNetworkLink = original.VirtualNetworkLink -type VirtualNetworkLinkListResult = original.VirtualNetworkLinkListResult -type VirtualNetworkLinkListResultIterator = original.VirtualNetworkLinkListResultIterator -type VirtualNetworkLinkListResultPage = original.VirtualNetworkLinkListResultPage -type VirtualNetworkLinkProperties = original.VirtualNetworkLinkProperties -type VirtualNetworkLinksClient = original.VirtualNetworkLinksClient -type VirtualNetworkLinksCreateOrUpdateFuture = original.VirtualNetworkLinksCreateOrUpdateFuture -type VirtualNetworkLinksDeleteFuture = original.VirtualNetworkLinksDeleteFuture -type VirtualNetworkLinksUpdateFuture = original.VirtualNetworkLinksUpdateFuture - -func New(subscriptionID string) BaseClient { - return original.New(subscriptionID) -} -func NewPrivateZoneListResultIterator(page PrivateZoneListResultPage) PrivateZoneListResultIterator { - return original.NewPrivateZoneListResultIterator(page) -} -func NewPrivateZoneListResultPage(cur PrivateZoneListResult, getNextPage func(context.Context, PrivateZoneListResult) (PrivateZoneListResult, error)) PrivateZoneListResultPage { - return original.NewPrivateZoneListResultPage(cur, getNextPage) -} -func NewPrivateZonesClient(subscriptionID string) PrivateZonesClient { - return original.NewPrivateZonesClient(subscriptionID) -} -func NewPrivateZonesClientWithBaseURI(baseURI string, subscriptionID string) PrivateZonesClient { - return original.NewPrivateZonesClientWithBaseURI(baseURI, subscriptionID) -} -func NewRecordSetListResultIterator(page RecordSetListResultPage) RecordSetListResultIterator { - return original.NewRecordSetListResultIterator(page) -} -func NewRecordSetListResultPage(cur RecordSetListResult, getNextPage func(context.Context, RecordSetListResult) (RecordSetListResult, error)) RecordSetListResultPage { - return original.NewRecordSetListResultPage(cur, getNextPage) -} -func NewRecordSetsClient(subscriptionID string) RecordSetsClient { - return original.NewRecordSetsClient(subscriptionID) -} -func NewRecordSetsClientWithBaseURI(baseURI string, subscriptionID string) RecordSetsClient { - return original.NewRecordSetsClientWithBaseURI(baseURI, subscriptionID) -} -func NewVirtualNetworkLinkListResultIterator(page VirtualNetworkLinkListResultPage) VirtualNetworkLinkListResultIterator { - return original.NewVirtualNetworkLinkListResultIterator(page) -} -func NewVirtualNetworkLinkListResultPage(cur VirtualNetworkLinkListResult, getNextPage func(context.Context, VirtualNetworkLinkListResult) (VirtualNetworkLinkListResult, error)) VirtualNetworkLinkListResultPage { - return original.NewVirtualNetworkLinkListResultPage(cur, getNextPage) -} -func NewVirtualNetworkLinksClient(subscriptionID string) VirtualNetworkLinksClient { - return original.NewVirtualNetworkLinksClient(subscriptionID) -} -func NewVirtualNetworkLinksClientWithBaseURI(baseURI string, subscriptionID string) VirtualNetworkLinksClient { - return original.NewVirtualNetworkLinksClientWithBaseURI(baseURI, subscriptionID) -} -func NewWithBaseURI(baseURI string, subscriptionID string) BaseClient { - return original.NewWithBaseURI(baseURI, subscriptionID) -} -func PossibleProvisioningStateValues() []ProvisioningState { - return original.PossibleProvisioningStateValues() -} -func PossibleRecordTypeValues() []RecordType { - return original.PossibleRecordTypeValues() -} -func PossibleVirtualNetworkLinkStateValues() []VirtualNetworkLinkState { - return original.PossibleVirtualNetworkLinkStateValues() -} -func UserAgent() string { - return original.UserAgent() + " profiles/latest" -} -func Version() string { - return original.Version() -} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns/CHANGELOG.md b/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns/CHANGELOG.md deleted file mode 100644 index 52911e4c..00000000 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns/CHANGELOG.md +++ /dev/null @@ -1,2 +0,0 @@ -# Change History - diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns/_meta.json b/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns/_meta.json deleted file mode 100644 index f3f56908..00000000 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns/_meta.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "commit": "3c764635e7d442b3e74caf593029fcd440b3ef82", - "readme": "/_/azure-rest-api-specs/specification/dns/resource-manager/readme.md", - "tag": "package-2018-05", - "use": "@microsoft.azure/autorest.go@2.1.187", - "repository_url": "https://github.com/Azure/azure-rest-api-specs.git", - "autorest_command": "autorest --use=@microsoft.azure/autorest.go@2.1.187 --tag=package-2018-05 --go-sdk-folder=/_/azure-sdk-for-go --go --verbose --use-onever --version=2.0.4421 --go.license-header=MICROSOFT_MIT_NO_VERSION /_/azure-rest-api-specs/specification/dns/resource-manager/readme.md", - "additional_properties": { - "additional_options": "--go --verbose --use-onever --version=2.0.4421 --go.license-header=MICROSOFT_MIT_NO_VERSION" - } -} \ No newline at end of file diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns/client.go b/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns/client.go deleted file mode 100644 index 8e442bba..00000000 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns/client.go +++ /dev/null @@ -1,43 +0,0 @@ -// Deprecated: Please note, this package has been deprecated. A replacement package is available [github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dns/armdns](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dns/armdns). We strongly encourage you to upgrade to continue receiving updates. See [Migration Guide](https://aka.ms/azsdk/golang/t2/migration) for guidance on upgrading. Refer to our [deprecation policy](https://azure.github.io/azure-sdk/policies_support.html) for more details. -// -// Package dns implements the Azure ARM Dns service API version 2018-05-01. -// -// The DNS Management Client. -package dns - -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See License.txt in the project root for license information. -// -// Code generated by Microsoft (R) AutoRest Code Generator. -// Changes may cause incorrect behavior and will be lost if the code is regenerated. - -import ( - "github.com/Azure/go-autorest/autorest" -) - -const ( - // DefaultBaseURI is the default URI used for the service Dns - DefaultBaseURI = "https://management.azure.com" -) - -// BaseClient is the base client for Dns. -type BaseClient struct { - autorest.Client - BaseURI string - SubscriptionID string -} - -// New creates an instance of the BaseClient client. -func New(subscriptionID string) BaseClient { - return NewWithBaseURI(DefaultBaseURI, subscriptionID) -} - -// NewWithBaseURI creates an instance of the BaseClient client using a custom endpoint. Use this when interacting with -// an Azure cloud that uses a non-standard base URI (sovereign clouds, Azure stack). -func NewWithBaseURI(baseURI string, subscriptionID string) BaseClient { - return BaseClient{ - Client: autorest.NewClientWithUserAgent(UserAgent()), - BaseURI: baseURI, - SubscriptionID: subscriptionID, - } -} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns/enums.go b/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns/enums.go deleted file mode 100644 index 90319aff..00000000 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns/enums.go +++ /dev/null @@ -1,53 +0,0 @@ -package dns - -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See License.txt in the project root for license information. -// -// Code generated by Microsoft (R) AutoRest Code Generator. -// Changes may cause incorrect behavior and will be lost if the code is regenerated. - -// RecordType enumerates the values for record type. -type RecordType string - -const ( - // A ... - A RecordType = "A" - // AAAA ... - AAAA RecordType = "AAAA" - // CAA ... - CAA RecordType = "CAA" - // CNAME ... - CNAME RecordType = "CNAME" - // MX ... - MX RecordType = "MX" - // NS ... - NS RecordType = "NS" - // PTR ... - PTR RecordType = "PTR" - // SOA ... - SOA RecordType = "SOA" - // SRV ... - SRV RecordType = "SRV" - // TXT ... - TXT RecordType = "TXT" -) - -// PossibleRecordTypeValues returns an array of possible values for the RecordType const type. -func PossibleRecordTypeValues() []RecordType { - return []RecordType{A, AAAA, CAA, CNAME, MX, NS, PTR, SOA, SRV, TXT} -} - -// ZoneType enumerates the values for zone type. -type ZoneType string - -const ( - // Private ... - Private ZoneType = "Private" - // Public ... - Public ZoneType = "Public" -) - -// PossibleZoneTypeValues returns an array of possible values for the ZoneType const type. -func PossibleZoneTypeValues() []ZoneType { - return []ZoneType{Private, Public} -} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns/models.go b/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns/models.go deleted file mode 100644 index 50355232..00000000 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns/models.go +++ /dev/null @@ -1,961 +0,0 @@ -package dns - -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See License.txt in the project root for license information. -// -// Code generated by Microsoft (R) AutoRest Code Generator. -// Changes may cause incorrect behavior and will be lost if the code is regenerated. - -import ( - "context" - "encoding/json" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/to" - "github.com/Azure/go-autorest/tracing" - "net/http" -) - -// The package's fully qualified name. -const fqdn = "github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns" - -// AaaaRecord an AAAA record. -type AaaaRecord struct { - // Ipv6Address - The IPv6 address of this AAAA record. - Ipv6Address *string `json:"ipv6Address,omitempty"` -} - -// ARecord an A record. -type ARecord struct { - // Ipv4Address - The IPv4 address of this A record. - Ipv4Address *string `json:"ipv4Address,omitempty"` -} - -// CaaRecord a CAA record. -type CaaRecord struct { - // Flags - The flags for this CAA record as an integer between 0 and 255. - Flags *int32 `json:"flags,omitempty"` - // Tag - The tag for this CAA record. - Tag *string `json:"tag,omitempty"` - // Value - The value for this CAA record. - Value *string `json:"value,omitempty"` -} - -// CloudError an error response from the service. -type CloudError struct { - // Error - Cloud error body. - Error *CloudErrorBody `json:"error,omitempty"` -} - -// CloudErrorBody an error response from the service. -type CloudErrorBody struct { - // Code - An identifier for the error. Codes are invariant and are intended to be consumed programmatically. - Code *string `json:"code,omitempty"` - // Message - A message describing the error, intended to be suitable for display in a user interface. - Message *string `json:"message,omitempty"` - // Target - The target of the particular error. For example, the name of the property in error. - Target *string `json:"target,omitempty"` - // Details - A list of additional details about the error. - Details *[]CloudErrorBody `json:"details,omitempty"` -} - -// CnameRecord a CNAME record. -type CnameRecord struct { - // Cname - The canonical name for this CNAME record. - Cname *string `json:"cname,omitempty"` -} - -// MxRecord an MX record. -type MxRecord struct { - // Preference - The preference value for this MX record. - Preference *int32 `json:"preference,omitempty"` - // Exchange - The domain name of the mail host for this MX record. - Exchange *string `json:"exchange,omitempty"` -} - -// NsRecord an NS record. -type NsRecord struct { - // Nsdname - The name server name for this NS record. - Nsdname *string `json:"nsdname,omitempty"` -} - -// PtrRecord a PTR record. -type PtrRecord struct { - // Ptrdname - The PTR target domain name for this PTR record. - Ptrdname *string `json:"ptrdname,omitempty"` -} - -// RecordSet describes a DNS record set (a collection of DNS records with the same name and type). -type RecordSet struct { - autorest.Response `json:"-"` - // ID - READ-ONLY; The ID of the record set. - ID *string `json:"id,omitempty"` - // Name - READ-ONLY; The name of the record set. - Name *string `json:"name,omitempty"` - // Type - READ-ONLY; The type of the record set. - Type *string `json:"type,omitempty"` - // Etag - The etag of the record set. - Etag *string `json:"etag,omitempty"` - // RecordSetProperties - The properties of the record set. - *RecordSetProperties `json:"properties,omitempty"` -} - -// MarshalJSON is the custom marshaler for RecordSet. -func (rs RecordSet) MarshalJSON() ([]byte, error) { - objectMap := make(map[string]interface{}) - if rs.Etag != nil { - objectMap["etag"] = rs.Etag - } - if rs.RecordSetProperties != nil { - objectMap["properties"] = rs.RecordSetProperties - } - return json.Marshal(objectMap) -} - -// UnmarshalJSON is the custom unmarshaler for RecordSet struct. -func (rs *RecordSet) UnmarshalJSON(body []byte) error { - var m map[string]*json.RawMessage - err := json.Unmarshal(body, &m) - if err != nil { - return err - } - for k, v := range m { - switch k { - case "id": - if v != nil { - var ID string - err = json.Unmarshal(*v, &ID) - if err != nil { - return err - } - rs.ID = &ID - } - case "name": - if v != nil { - var name string - err = json.Unmarshal(*v, &name) - if err != nil { - return err - } - rs.Name = &name - } - case "type": - if v != nil { - var typeVar string - err = json.Unmarshal(*v, &typeVar) - if err != nil { - return err - } - rs.Type = &typeVar - } - case "etag": - if v != nil { - var etag string - err = json.Unmarshal(*v, &etag) - if err != nil { - return err - } - rs.Etag = &etag - } - case "properties": - if v != nil { - var recordSetProperties RecordSetProperties - err = json.Unmarshal(*v, &recordSetProperties) - if err != nil { - return err - } - rs.RecordSetProperties = &recordSetProperties - } - } - } - - return nil -} - -// RecordSetListResult the response to a record set List operation. -type RecordSetListResult struct { - autorest.Response `json:"-"` - // Value - Information about the record sets in the response. - Value *[]RecordSet `json:"value,omitempty"` - // NextLink - READ-ONLY; The continuation token for the next page of results. - NextLink *string `json:"nextLink,omitempty"` -} - -// MarshalJSON is the custom marshaler for RecordSetListResult. -func (rslr RecordSetListResult) MarshalJSON() ([]byte, error) { - objectMap := make(map[string]interface{}) - if rslr.Value != nil { - objectMap["value"] = rslr.Value - } - return json.Marshal(objectMap) -} - -// RecordSetListResultIterator provides access to a complete listing of RecordSet values. -type RecordSetListResultIterator struct { - i int - page RecordSetListResultPage -} - -// NextWithContext advances to the next value. If there was an error making -// the request the iterator does not advance and the error is returned. -func (iter *RecordSetListResultIterator) NextWithContext(ctx context.Context) (err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/RecordSetListResultIterator.NextWithContext") - defer func() { - sc := -1 - if iter.Response().Response.Response != nil { - sc = iter.Response().Response.Response.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - iter.i++ - if iter.i < len(iter.page.Values()) { - return nil - } - err = iter.page.NextWithContext(ctx) - if err != nil { - iter.i-- - return err - } - iter.i = 0 - return nil -} - -// Next advances to the next value. If there was an error making -// the request the iterator does not advance and the error is returned. -// Deprecated: Use NextWithContext() instead. -func (iter *RecordSetListResultIterator) Next() error { - return iter.NextWithContext(context.Background()) -} - -// NotDone returns true if the enumeration should be started or is not yet complete. -func (iter RecordSetListResultIterator) NotDone() bool { - return iter.page.NotDone() && iter.i < len(iter.page.Values()) -} - -// Response returns the raw server response from the last page request. -func (iter RecordSetListResultIterator) Response() RecordSetListResult { - return iter.page.Response() -} - -// Value returns the current value or a zero-initialized value if the -// iterator has advanced beyond the end of the collection. -func (iter RecordSetListResultIterator) Value() RecordSet { - if !iter.page.NotDone() { - return RecordSet{} - } - return iter.page.Values()[iter.i] -} - -// Creates a new instance of the RecordSetListResultIterator type. -func NewRecordSetListResultIterator(page RecordSetListResultPage) RecordSetListResultIterator { - return RecordSetListResultIterator{page: page} -} - -// IsEmpty returns true if the ListResult contains no values. -func (rslr RecordSetListResult) IsEmpty() bool { - return rslr.Value == nil || len(*rslr.Value) == 0 -} - -// hasNextLink returns true if the NextLink is not empty. -func (rslr RecordSetListResult) hasNextLink() bool { - return rslr.NextLink != nil && len(*rslr.NextLink) != 0 -} - -// recordSetListResultPreparer prepares a request to retrieve the next set of results. -// It returns nil if no more results exist. -func (rslr RecordSetListResult) recordSetListResultPreparer(ctx context.Context) (*http.Request, error) { - if !rslr.hasNextLink() { - return nil, nil - } - return autorest.Prepare((&http.Request{}).WithContext(ctx), - autorest.AsJSON(), - autorest.AsGet(), - autorest.WithBaseURL(to.String(rslr.NextLink))) -} - -// RecordSetListResultPage contains a page of RecordSet values. -type RecordSetListResultPage struct { - fn func(context.Context, RecordSetListResult) (RecordSetListResult, error) - rslr RecordSetListResult -} - -// NextWithContext advances to the next page of values. If there was an error making -// the request the page does not advance and the error is returned. -func (page *RecordSetListResultPage) NextWithContext(ctx context.Context) (err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/RecordSetListResultPage.NextWithContext") - defer func() { - sc := -1 - if page.Response().Response.Response != nil { - sc = page.Response().Response.Response.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - for { - next, err := page.fn(ctx, page.rslr) - if err != nil { - return err - } - page.rslr = next - if !next.hasNextLink() || !next.IsEmpty() { - break - } - } - return nil -} - -// Next advances to the next page of values. If there was an error making -// the request the page does not advance and the error is returned. -// Deprecated: Use NextWithContext() instead. -func (page *RecordSetListResultPage) Next() error { - return page.NextWithContext(context.Background()) -} - -// NotDone returns true if the page enumeration should be started or is not yet complete. -func (page RecordSetListResultPage) NotDone() bool { - return !page.rslr.IsEmpty() -} - -// Response returns the raw server response from the last page request. -func (page RecordSetListResultPage) Response() RecordSetListResult { - return page.rslr -} - -// Values returns the slice of values for the current page or nil if there are no values. -func (page RecordSetListResultPage) Values() []RecordSet { - if page.rslr.IsEmpty() { - return nil - } - return *page.rslr.Value -} - -// Creates a new instance of the RecordSetListResultPage type. -func NewRecordSetListResultPage(cur RecordSetListResult, getNextPage func(context.Context, RecordSetListResult) (RecordSetListResult, error)) RecordSetListResultPage { - return RecordSetListResultPage{ - fn: getNextPage, - rslr: cur, - } -} - -// RecordSetProperties represents the properties of the records in the record set. -type RecordSetProperties struct { - // Metadata - The metadata attached to the record set. - Metadata map[string]*string `json:"metadata"` - // TTL - The TTL (time-to-live) of the records in the record set. - TTL *int64 `json:"TTL,omitempty"` - // Fqdn - READ-ONLY; Fully qualified domain name of the record set. - Fqdn *string `json:"fqdn,omitempty"` - // ProvisioningState - READ-ONLY; provisioning State of the record set. - ProvisioningState *string `json:"provisioningState,omitempty"` - // TargetResource - A reference to an azure resource from where the dns resource value is taken. - TargetResource *SubResource `json:"targetResource,omitempty"` - // ARecords - The list of A records in the record set. - ARecords *[]ARecord `json:"ARecords,omitempty"` - // AaaaRecords - The list of AAAA records in the record set. - AaaaRecords *[]AaaaRecord `json:"AAAARecords,omitempty"` - // MxRecords - The list of MX records in the record set. - MxRecords *[]MxRecord `json:"MXRecords,omitempty"` - // NsRecords - The list of NS records in the record set. - NsRecords *[]NsRecord `json:"NSRecords,omitempty"` - // PtrRecords - The list of PTR records in the record set. - PtrRecords *[]PtrRecord `json:"PTRRecords,omitempty"` - // SrvRecords - The list of SRV records in the record set. - SrvRecords *[]SrvRecord `json:"SRVRecords,omitempty"` - // TxtRecords - The list of TXT records in the record set. - TxtRecords *[]TxtRecord `json:"TXTRecords,omitempty"` - // CnameRecord - The CNAME record in the record set. - CnameRecord *CnameRecord `json:"CNAMERecord,omitempty"` - // SoaRecord - The SOA record in the record set. - SoaRecord *SoaRecord `json:"SOARecord,omitempty"` - // CaaRecords - The list of CAA records in the record set. - CaaRecords *[]CaaRecord `json:"caaRecords,omitempty"` -} - -// MarshalJSON is the custom marshaler for RecordSetProperties. -func (rsp RecordSetProperties) MarshalJSON() ([]byte, error) { - objectMap := make(map[string]interface{}) - if rsp.Metadata != nil { - objectMap["metadata"] = rsp.Metadata - } - if rsp.TTL != nil { - objectMap["TTL"] = rsp.TTL - } - if rsp.TargetResource != nil { - objectMap["targetResource"] = rsp.TargetResource - } - if rsp.ARecords != nil { - objectMap["ARecords"] = rsp.ARecords - } - if rsp.AaaaRecords != nil { - objectMap["AAAARecords"] = rsp.AaaaRecords - } - if rsp.MxRecords != nil { - objectMap["MXRecords"] = rsp.MxRecords - } - if rsp.NsRecords != nil { - objectMap["NSRecords"] = rsp.NsRecords - } - if rsp.PtrRecords != nil { - objectMap["PTRRecords"] = rsp.PtrRecords - } - if rsp.SrvRecords != nil { - objectMap["SRVRecords"] = rsp.SrvRecords - } - if rsp.TxtRecords != nil { - objectMap["TXTRecords"] = rsp.TxtRecords - } - if rsp.CnameRecord != nil { - objectMap["CNAMERecord"] = rsp.CnameRecord - } - if rsp.SoaRecord != nil { - objectMap["SOARecord"] = rsp.SoaRecord - } - if rsp.CaaRecords != nil { - objectMap["caaRecords"] = rsp.CaaRecords - } - return json.Marshal(objectMap) -} - -// RecordSetUpdateParameters parameters supplied to update a record set. -type RecordSetUpdateParameters struct { - // RecordSet - Specifies information about the record set being updated. - RecordSet *RecordSet `json:"RecordSet,omitempty"` -} - -// Resource common properties of an Azure Resource Manager resource -type Resource struct { - // ID - READ-ONLY; Resource ID. - ID *string `json:"id,omitempty"` - // Name - READ-ONLY; Resource name. - Name *string `json:"name,omitempty"` - // Type - READ-ONLY; Resource type. - Type *string `json:"type,omitempty"` - // Location - Resource location. - Location *string `json:"location,omitempty"` - // Tags - Resource tags. - Tags map[string]*string `json:"tags"` -} - -// MarshalJSON is the custom marshaler for Resource. -func (r Resource) MarshalJSON() ([]byte, error) { - objectMap := make(map[string]interface{}) - if r.Location != nil { - objectMap["location"] = r.Location - } - if r.Tags != nil { - objectMap["tags"] = r.Tags - } - return json.Marshal(objectMap) -} - -// ResourceReference represents a single Azure resource and its referencing DNS records. -type ResourceReference struct { - // DNSResources - A list of dns Records - DNSResources *[]SubResource `json:"dnsResources,omitempty"` - // TargetResource - A reference to an azure resource from where the dns resource value is taken. - TargetResource *SubResource `json:"targetResource,omitempty"` -} - -// ResourceReferenceRequest represents the properties of the Dns Resource Reference Request. -type ResourceReferenceRequest struct { - // ResourceReferenceRequestProperties - The properties of the Resource Reference Request. - *ResourceReferenceRequestProperties `json:"properties,omitempty"` -} - -// MarshalJSON is the custom marshaler for ResourceReferenceRequest. -func (rrr ResourceReferenceRequest) MarshalJSON() ([]byte, error) { - objectMap := make(map[string]interface{}) - if rrr.ResourceReferenceRequestProperties != nil { - objectMap["properties"] = rrr.ResourceReferenceRequestProperties - } - return json.Marshal(objectMap) -} - -// UnmarshalJSON is the custom unmarshaler for ResourceReferenceRequest struct. -func (rrr *ResourceReferenceRequest) UnmarshalJSON(body []byte) error { - var m map[string]*json.RawMessage - err := json.Unmarshal(body, &m) - if err != nil { - return err - } - for k, v := range m { - switch k { - case "properties": - if v != nil { - var resourceReferenceRequestProperties ResourceReferenceRequestProperties - err = json.Unmarshal(*v, &resourceReferenceRequestProperties) - if err != nil { - return err - } - rrr.ResourceReferenceRequestProperties = &resourceReferenceRequestProperties - } - } - } - - return nil -} - -// ResourceReferenceRequestProperties represents the properties of the Dns Resource Reference Request. -type ResourceReferenceRequestProperties struct { - // TargetResources - A list of references to azure resources for which referencing dns records need to be queried. - TargetResources *[]SubResource `json:"targetResources,omitempty"` -} - -// ResourceReferenceResult represents the properties of the Dns Resource Reference Result. -type ResourceReferenceResult struct { - autorest.Response `json:"-"` - // ResourceReferenceResultProperties - The result of dns resource reference request. Returns a list of dns resource references for each of the azure resource in the request. - *ResourceReferenceResultProperties `json:"properties,omitempty"` -} - -// MarshalJSON is the custom marshaler for ResourceReferenceResult. -func (rrr ResourceReferenceResult) MarshalJSON() ([]byte, error) { - objectMap := make(map[string]interface{}) - if rrr.ResourceReferenceResultProperties != nil { - objectMap["properties"] = rrr.ResourceReferenceResultProperties - } - return json.Marshal(objectMap) -} - -// UnmarshalJSON is the custom unmarshaler for ResourceReferenceResult struct. -func (rrr *ResourceReferenceResult) UnmarshalJSON(body []byte) error { - var m map[string]*json.RawMessage - err := json.Unmarshal(body, &m) - if err != nil { - return err - } - for k, v := range m { - switch k { - case "properties": - if v != nil { - var resourceReferenceResultProperties ResourceReferenceResultProperties - err = json.Unmarshal(*v, &resourceReferenceResultProperties) - if err != nil { - return err - } - rrr.ResourceReferenceResultProperties = &resourceReferenceResultProperties - } - } - } - - return nil -} - -// ResourceReferenceResultProperties the result of dns resource reference request. Returns a list of dns -// resource references for each of the azure resource in the request. -type ResourceReferenceResultProperties struct { - // DNSResourceReferences - The result of dns resource reference request. A list of dns resource references for each of the azure resource in the request - DNSResourceReferences *[]ResourceReference `json:"dnsResourceReferences,omitempty"` -} - -// SoaRecord an SOA record. -type SoaRecord struct { - // Host - The domain name of the authoritative name server for this SOA record. - Host *string `json:"host,omitempty"` - // Email - The email contact for this SOA record. - Email *string `json:"email,omitempty"` - // SerialNumber - The serial number for this SOA record. - SerialNumber *int64 `json:"serialNumber,omitempty"` - // RefreshTime - The refresh value for this SOA record. - RefreshTime *int64 `json:"refreshTime,omitempty"` - // RetryTime - The retry time for this SOA record. - RetryTime *int64 `json:"retryTime,omitempty"` - // ExpireTime - The expire time for this SOA record. - ExpireTime *int64 `json:"expireTime,omitempty"` - // MinimumTTL - The minimum value for this SOA record. By convention this is used to determine the negative caching duration. - MinimumTTL *int64 `json:"minimumTTL,omitempty"` -} - -// SrvRecord an SRV record. -type SrvRecord struct { - // Priority - The priority value for this SRV record. - Priority *int32 `json:"priority,omitempty"` - // Weight - The weight value for this SRV record. - Weight *int32 `json:"weight,omitempty"` - // Port - The port value for this SRV record. - Port *int32 `json:"port,omitempty"` - // Target - The target domain name for this SRV record. - Target *string `json:"target,omitempty"` -} - -// SubResource a reference to a another resource -type SubResource struct { - // ID - Resource Id. - ID *string `json:"id,omitempty"` -} - -// TxtRecord a TXT record. -type TxtRecord struct { - // Value - The text value of this TXT record. - Value *[]string `json:"value,omitempty"` -} - -// Zone describes a DNS zone. -type Zone struct { - autorest.Response `json:"-"` - // Etag - The etag of the zone. - Etag *string `json:"etag,omitempty"` - // ZoneProperties - The properties of the zone. - *ZoneProperties `json:"properties,omitempty"` - // ID - READ-ONLY; Resource ID. - ID *string `json:"id,omitempty"` - // Name - READ-ONLY; Resource name. - Name *string `json:"name,omitempty"` - // Type - READ-ONLY; Resource type. - Type *string `json:"type,omitempty"` - // Location - Resource location. - Location *string `json:"location,omitempty"` - // Tags - Resource tags. - Tags map[string]*string `json:"tags"` -} - -// MarshalJSON is the custom marshaler for Zone. -func (z Zone) MarshalJSON() ([]byte, error) { - objectMap := make(map[string]interface{}) - if z.Etag != nil { - objectMap["etag"] = z.Etag - } - if z.ZoneProperties != nil { - objectMap["properties"] = z.ZoneProperties - } - if z.Location != nil { - objectMap["location"] = z.Location - } - if z.Tags != nil { - objectMap["tags"] = z.Tags - } - return json.Marshal(objectMap) -} - -// UnmarshalJSON is the custom unmarshaler for Zone struct. -func (z *Zone) UnmarshalJSON(body []byte) error { - var m map[string]*json.RawMessage - err := json.Unmarshal(body, &m) - if err != nil { - return err - } - for k, v := range m { - switch k { - case "etag": - if v != nil { - var etag string - err = json.Unmarshal(*v, &etag) - if err != nil { - return err - } - z.Etag = &etag - } - case "properties": - if v != nil { - var zoneProperties ZoneProperties - err = json.Unmarshal(*v, &zoneProperties) - if err != nil { - return err - } - z.ZoneProperties = &zoneProperties - } - case "id": - if v != nil { - var ID string - err = json.Unmarshal(*v, &ID) - if err != nil { - return err - } - z.ID = &ID - } - case "name": - if v != nil { - var name string - err = json.Unmarshal(*v, &name) - if err != nil { - return err - } - z.Name = &name - } - case "type": - if v != nil { - var typeVar string - err = json.Unmarshal(*v, &typeVar) - if err != nil { - return err - } - z.Type = &typeVar - } - case "location": - if v != nil { - var location string - err = json.Unmarshal(*v, &location) - if err != nil { - return err - } - z.Location = &location - } - case "tags": - if v != nil { - var tags map[string]*string - err = json.Unmarshal(*v, &tags) - if err != nil { - return err - } - z.Tags = tags - } - } - } - - return nil -} - -// ZoneListResult the response to a Zone List or ListAll operation. -type ZoneListResult struct { - autorest.Response `json:"-"` - // Value - Information about the DNS zones. - Value *[]Zone `json:"value,omitempty"` - // NextLink - READ-ONLY; The continuation token for the next page of results. - NextLink *string `json:"nextLink,omitempty"` -} - -// MarshalJSON is the custom marshaler for ZoneListResult. -func (zlr ZoneListResult) MarshalJSON() ([]byte, error) { - objectMap := make(map[string]interface{}) - if zlr.Value != nil { - objectMap["value"] = zlr.Value - } - return json.Marshal(objectMap) -} - -// ZoneListResultIterator provides access to a complete listing of Zone values. -type ZoneListResultIterator struct { - i int - page ZoneListResultPage -} - -// NextWithContext advances to the next value. If there was an error making -// the request the iterator does not advance and the error is returned. -func (iter *ZoneListResultIterator) NextWithContext(ctx context.Context) (err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/ZoneListResultIterator.NextWithContext") - defer func() { - sc := -1 - if iter.Response().Response.Response != nil { - sc = iter.Response().Response.Response.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - iter.i++ - if iter.i < len(iter.page.Values()) { - return nil - } - err = iter.page.NextWithContext(ctx) - if err != nil { - iter.i-- - return err - } - iter.i = 0 - return nil -} - -// Next advances to the next value. If there was an error making -// the request the iterator does not advance and the error is returned. -// Deprecated: Use NextWithContext() instead. -func (iter *ZoneListResultIterator) Next() error { - return iter.NextWithContext(context.Background()) -} - -// NotDone returns true if the enumeration should be started or is not yet complete. -func (iter ZoneListResultIterator) NotDone() bool { - return iter.page.NotDone() && iter.i < len(iter.page.Values()) -} - -// Response returns the raw server response from the last page request. -func (iter ZoneListResultIterator) Response() ZoneListResult { - return iter.page.Response() -} - -// Value returns the current value or a zero-initialized value if the -// iterator has advanced beyond the end of the collection. -func (iter ZoneListResultIterator) Value() Zone { - if !iter.page.NotDone() { - return Zone{} - } - return iter.page.Values()[iter.i] -} - -// Creates a new instance of the ZoneListResultIterator type. -func NewZoneListResultIterator(page ZoneListResultPage) ZoneListResultIterator { - return ZoneListResultIterator{page: page} -} - -// IsEmpty returns true if the ListResult contains no values. -func (zlr ZoneListResult) IsEmpty() bool { - return zlr.Value == nil || len(*zlr.Value) == 0 -} - -// hasNextLink returns true if the NextLink is not empty. -func (zlr ZoneListResult) hasNextLink() bool { - return zlr.NextLink != nil && len(*zlr.NextLink) != 0 -} - -// zoneListResultPreparer prepares a request to retrieve the next set of results. -// It returns nil if no more results exist. -func (zlr ZoneListResult) zoneListResultPreparer(ctx context.Context) (*http.Request, error) { - if !zlr.hasNextLink() { - return nil, nil - } - return autorest.Prepare((&http.Request{}).WithContext(ctx), - autorest.AsJSON(), - autorest.AsGet(), - autorest.WithBaseURL(to.String(zlr.NextLink))) -} - -// ZoneListResultPage contains a page of Zone values. -type ZoneListResultPage struct { - fn func(context.Context, ZoneListResult) (ZoneListResult, error) - zlr ZoneListResult -} - -// NextWithContext advances to the next page of values. If there was an error making -// the request the page does not advance and the error is returned. -func (page *ZoneListResultPage) NextWithContext(ctx context.Context) (err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/ZoneListResultPage.NextWithContext") - defer func() { - sc := -1 - if page.Response().Response.Response != nil { - sc = page.Response().Response.Response.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - for { - next, err := page.fn(ctx, page.zlr) - if err != nil { - return err - } - page.zlr = next - if !next.hasNextLink() || !next.IsEmpty() { - break - } - } - return nil -} - -// Next advances to the next page of values. If there was an error making -// the request the page does not advance and the error is returned. -// Deprecated: Use NextWithContext() instead. -func (page *ZoneListResultPage) Next() error { - return page.NextWithContext(context.Background()) -} - -// NotDone returns true if the page enumeration should be started or is not yet complete. -func (page ZoneListResultPage) NotDone() bool { - return !page.zlr.IsEmpty() -} - -// Response returns the raw server response from the last page request. -func (page ZoneListResultPage) Response() ZoneListResult { - return page.zlr -} - -// Values returns the slice of values for the current page or nil if there are no values. -func (page ZoneListResultPage) Values() []Zone { - if page.zlr.IsEmpty() { - return nil - } - return *page.zlr.Value -} - -// Creates a new instance of the ZoneListResultPage type. -func NewZoneListResultPage(cur ZoneListResult, getNextPage func(context.Context, ZoneListResult) (ZoneListResult, error)) ZoneListResultPage { - return ZoneListResultPage{ - fn: getNextPage, - zlr: cur, - } -} - -// ZoneProperties represents the properties of the zone. -type ZoneProperties struct { - // MaxNumberOfRecordSets - READ-ONLY; The maximum number of record sets that can be created in this DNS zone. This is a read-only property and any attempt to set this value will be ignored. - MaxNumberOfRecordSets *int64 `json:"maxNumberOfRecordSets,omitempty"` - // MaxNumberOfRecordsPerRecordSet - READ-ONLY; The maximum number of records per record set that can be created in this DNS zone. This is a read-only property and any attempt to set this value will be ignored. - MaxNumberOfRecordsPerRecordSet *int64 `json:"maxNumberOfRecordsPerRecordSet,omitempty"` - // NumberOfRecordSets - READ-ONLY; The current number of record sets in this DNS zone. This is a read-only property and any attempt to set this value will be ignored. - NumberOfRecordSets *int64 `json:"numberOfRecordSets,omitempty"` - // NameServers - READ-ONLY; The name servers for this DNS zone. This is a read-only property and any attempt to set this value will be ignored. - NameServers *[]string `json:"nameServers,omitempty"` - // ZoneType - The type of this DNS zone (Public or Private). Possible values include: 'Public', 'Private' - ZoneType ZoneType `json:"zoneType,omitempty"` - // RegistrationVirtualNetworks - A list of references to virtual networks that register hostnames in this DNS zone. This is a only when ZoneType is Private. - RegistrationVirtualNetworks *[]SubResource `json:"registrationVirtualNetworks,omitempty"` - // ResolutionVirtualNetworks - A list of references to virtual networks that resolve records in this DNS zone. This is a only when ZoneType is Private. - ResolutionVirtualNetworks *[]SubResource `json:"resolutionVirtualNetworks,omitempty"` -} - -// MarshalJSON is the custom marshaler for ZoneProperties. -func (zp ZoneProperties) MarshalJSON() ([]byte, error) { - objectMap := make(map[string]interface{}) - if zp.ZoneType != "" { - objectMap["zoneType"] = zp.ZoneType - } - if zp.RegistrationVirtualNetworks != nil { - objectMap["registrationVirtualNetworks"] = zp.RegistrationVirtualNetworks - } - if zp.ResolutionVirtualNetworks != nil { - objectMap["resolutionVirtualNetworks"] = zp.ResolutionVirtualNetworks - } - return json.Marshal(objectMap) -} - -// ZonesDeleteFuture an abstraction for monitoring and retrieving the results of a long-running operation. -type ZonesDeleteFuture struct { - azure.FutureAPI - // Result returns the result of the asynchronous operation. - // If the operation has not completed it will return an error. - Result func(ZonesClient) (autorest.Response, error) -} - -// UnmarshalJSON is the custom unmarshaller for CreateFuture. -func (future *ZonesDeleteFuture) UnmarshalJSON(body []byte) error { - var azFuture azure.Future - if err := json.Unmarshal(body, &azFuture); err != nil { - return err - } - future.FutureAPI = &azFuture - future.Result = future.result - return nil -} - -// result is the default implementation for ZonesDeleteFuture.Result. -func (future *ZonesDeleteFuture) result(client ZonesClient) (ar autorest.Response, err error) { - var done bool - done, err = future.DoneWithContext(context.Background(), client) - if err != nil { - err = autorest.NewErrorWithError(err, "dns.ZonesDeleteFuture", "Result", future.Response(), "Polling failure") - return - } - if !done { - ar.Response = future.Response() - err = azure.NewAsyncOpIncompleteError("dns.ZonesDeleteFuture") - return - } - ar.Response = future.Response() - return -} - -// ZoneUpdate describes a request to update a DNS zone. -type ZoneUpdate struct { - // Tags - Resource tags. - Tags map[string]*string `json:"tags"` -} - -// MarshalJSON is the custom marshaler for ZoneUpdate. -func (zu ZoneUpdate) MarshalJSON() ([]byte, error) { - objectMap := make(map[string]interface{}) - if zu.Tags != nil { - objectMap["tags"] = zu.Tags - } - return json.Marshal(objectMap) -} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns/recordsets.go b/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns/recordsets.go deleted file mode 100644 index d3aa10e2..00000000 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns/recordsets.go +++ /dev/null @@ -1,774 +0,0 @@ -package dns - -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See License.txt in the project root for license information. -// -// Code generated by Microsoft (R) AutoRest Code Generator. -// Changes may cause incorrect behavior and will be lost if the code is regenerated. - -import ( - "context" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/tracing" - "net/http" -) - -// RecordSetsClient is the the DNS Management Client. -type RecordSetsClient struct { - BaseClient -} - -// NewRecordSetsClient creates an instance of the RecordSetsClient client. -func NewRecordSetsClient(subscriptionID string) RecordSetsClient { - return NewRecordSetsClientWithBaseURI(DefaultBaseURI, subscriptionID) -} - -// NewRecordSetsClientWithBaseURI creates an instance of the RecordSetsClient client using a custom endpoint. Use this -// when interacting with an Azure cloud that uses a non-standard base URI (sovereign clouds, Azure stack). -func NewRecordSetsClientWithBaseURI(baseURI string, subscriptionID string) RecordSetsClient { - return RecordSetsClient{NewWithBaseURI(baseURI, subscriptionID)} -} - -// CreateOrUpdate creates or updates a record set within a DNS zone. -// Parameters: -// resourceGroupName - the name of the resource group. -// zoneName - the name of the DNS zone (without a terminating dot). -// relativeRecordSetName - the name of the record set, relative to the name of the zone. -// recordType - the type of DNS record in this record set. Record sets of type SOA can be updated but not -// created (they are created when the DNS zone is created). -// parameters - parameters supplied to the CreateOrUpdate operation. -// ifMatch - the etag of the record set. Omit this value to always overwrite the current record set. Specify -// the last-seen etag value to prevent accidentally overwriting any concurrent changes. -// ifNoneMatch - set to '*' to allow a new record set to be created, but to prevent updating an existing record -// set. Other values will be ignored. -func (client RecordSetsClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType RecordType, parameters RecordSet, ifMatch string, ifNoneMatch string) (result RecordSet, err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/RecordSetsClient.CreateOrUpdate") - defer func() { - sc := -1 - if result.Response.Response != nil { - sc = result.Response.Response.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - req, err := client.CreateOrUpdatePreparer(ctx, resourceGroupName, zoneName, relativeRecordSetName, recordType, parameters, ifMatch, ifNoneMatch) - if err != nil { - err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "CreateOrUpdate", nil, "Failure preparing request") - return - } - - resp, err := client.CreateOrUpdateSender(req) - if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "CreateOrUpdate", resp, "Failure sending request") - return - } - - result, err = client.CreateOrUpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "CreateOrUpdate", resp, "Failure responding to request") - return - } - - return -} - -// CreateOrUpdatePreparer prepares the CreateOrUpdate request. -func (client RecordSetsClient) CreateOrUpdatePreparer(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType RecordType, parameters RecordSet, ifMatch string, ifNoneMatch string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "recordType": autorest.Encode("path", recordType), - "relativeRecordSetName": relativeRecordSetName, - "resourceGroupName": autorest.Encode("path", resourceGroupName), - "subscriptionId": autorest.Encode("path", client.SubscriptionID), - "zoneName": autorest.Encode("path", zoneName), - } - - const APIVersion = "2018-05-01" - queryParameters := map[string]interface{}{ - "api-version": APIVersion, - } - - parameters.ID = nil - parameters.Name = nil - parameters.Type = nil - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/json; charset=utf-8"), - autorest.AsPut(), - autorest.WithBaseURL(client.BaseURI), - autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/dnsZones/{zoneName}/{recordType}/{relativeRecordSetName}", pathParameters), - autorest.WithJSON(parameters), - autorest.WithQueryParameters(queryParameters)) - if len(ifMatch) > 0 { - preparer = autorest.DecoratePreparer(preparer, - autorest.WithHeader("If-Match", autorest.String(ifMatch))) - } - if len(ifNoneMatch) > 0 { - preparer = autorest.DecoratePreparer(preparer, - autorest.WithHeader("If-None-Match", autorest.String(ifNoneMatch))) - } - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the -// http.Response Body if it receives an error. -func (client RecordSetsClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { - return client.Send(req, azure.DoRetryWithRegistration(client.Client)) -} - -// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always -// closes the http.Response Body. -func (client RecordSetsClient) CreateOrUpdateResponder(resp *http.Response) (result RecordSet, err error) { - err = autorest.Respond( - resp, - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated), - autorest.ByUnmarshallingJSON(&result), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - return -} - -// Delete deletes a record set from a DNS zone. This operation cannot be undone. -// Parameters: -// resourceGroupName - the name of the resource group. -// zoneName - the name of the DNS zone (without a terminating dot). -// relativeRecordSetName - the name of the record set, relative to the name of the zone. -// recordType - the type of DNS record in this record set. Record sets of type SOA cannot be deleted (they are -// deleted when the DNS zone is deleted). -// ifMatch - the etag of the record set. Omit this value to always delete the current record set. Specify the -// last-seen etag value to prevent accidentally deleting any concurrent changes. -func (client RecordSetsClient) Delete(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType RecordType, ifMatch string) (result autorest.Response, err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/RecordSetsClient.Delete") - defer func() { - sc := -1 - if result.Response != nil { - sc = result.Response.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - req, err := client.DeletePreparer(ctx, resourceGroupName, zoneName, relativeRecordSetName, recordType, ifMatch) - if err != nil { - err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "Delete", nil, "Failure preparing request") - return - } - - resp, err := client.DeleteSender(req) - if err != nil { - result.Response = resp - err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "Delete", resp, "Failure sending request") - return - } - - result, err = client.DeleteResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "Delete", resp, "Failure responding to request") - return - } - - return -} - -// DeletePreparer prepares the Delete request. -func (client RecordSetsClient) DeletePreparer(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType RecordType, ifMatch string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "recordType": autorest.Encode("path", recordType), - "relativeRecordSetName": relativeRecordSetName, - "resourceGroupName": autorest.Encode("path", resourceGroupName), - "subscriptionId": autorest.Encode("path", client.SubscriptionID), - "zoneName": autorest.Encode("path", zoneName), - } - - const APIVersion = "2018-05-01" - queryParameters := map[string]interface{}{ - "api-version": APIVersion, - } - - preparer := autorest.CreatePreparer( - autorest.AsDelete(), - autorest.WithBaseURL(client.BaseURI), - autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/dnsZones/{zoneName}/{recordType}/{relativeRecordSetName}", pathParameters), - autorest.WithQueryParameters(queryParameters)) - if len(ifMatch) > 0 { - preparer = autorest.DecoratePreparer(preparer, - autorest.WithHeader("If-Match", autorest.String(ifMatch))) - } - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// DeleteSender sends the Delete request. The method will close the -// http.Response Body if it receives an error. -func (client RecordSetsClient) DeleteSender(req *http.Request) (*http.Response, error) { - return client.Send(req, azure.DoRetryWithRegistration(client.Client)) -} - -// DeleteResponder handles the response to the Delete request. The method always -// closes the http.Response Body. -func (client RecordSetsClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNoContent), - autorest.ByClosing()) - result.Response = resp - return -} - -// Get gets a record set. -// Parameters: -// resourceGroupName - the name of the resource group. -// zoneName - the name of the DNS zone (without a terminating dot). -// relativeRecordSetName - the name of the record set, relative to the name of the zone. -// recordType - the type of DNS record in this record set. -func (client RecordSetsClient) Get(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType RecordType) (result RecordSet, err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/RecordSetsClient.Get") - defer func() { - sc := -1 - if result.Response.Response != nil { - sc = result.Response.Response.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - req, err := client.GetPreparer(ctx, resourceGroupName, zoneName, relativeRecordSetName, recordType) - if err != nil { - err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "Get", nil, "Failure preparing request") - return - } - - resp, err := client.GetSender(req) - if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "Get", resp, "Failure sending request") - return - } - - result, err = client.GetResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "Get", resp, "Failure responding to request") - return - } - - return -} - -// GetPreparer prepares the Get request. -func (client RecordSetsClient) GetPreparer(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType RecordType) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "recordType": autorest.Encode("path", recordType), - "relativeRecordSetName": relativeRecordSetName, - "resourceGroupName": autorest.Encode("path", resourceGroupName), - "subscriptionId": autorest.Encode("path", client.SubscriptionID), - "zoneName": autorest.Encode("path", zoneName), - } - - const APIVersion = "2018-05-01" - queryParameters := map[string]interface{}{ - "api-version": APIVersion, - } - - preparer := autorest.CreatePreparer( - autorest.AsGet(), - autorest.WithBaseURL(client.BaseURI), - autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/dnsZones/{zoneName}/{recordType}/{relativeRecordSetName}", pathParameters), - autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// GetSender sends the Get request. The method will close the -// http.Response Body if it receives an error. -func (client RecordSetsClient) GetSender(req *http.Request) (*http.Response, error) { - return client.Send(req, azure.DoRetryWithRegistration(client.Client)) -} - -// GetResponder handles the response to the Get request. The method always -// closes the http.Response Body. -func (client RecordSetsClient) GetResponder(resp *http.Response) (result RecordSet, err error) { - err = autorest.Respond( - resp, - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByUnmarshallingJSON(&result), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - return -} - -// ListAllByDNSZone lists all record sets in a DNS zone. -// Parameters: -// resourceGroupName - the name of the resource group. -// zoneName - the name of the DNS zone (without a terminating dot). -// top - the maximum number of record sets to return. If not specified, returns up to 100 record sets. -// recordSetNameSuffix - the suffix label of the record set name that has to be used to filter the record set -// enumerations. If this parameter is specified, Enumeration will return only records that end with -// . -func (client RecordSetsClient) ListAllByDNSZone(ctx context.Context, resourceGroupName string, zoneName string, top *int32, recordSetNameSuffix string) (result RecordSetListResultPage, err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/RecordSetsClient.ListAllByDNSZone") - defer func() { - sc := -1 - if result.rslr.Response.Response != nil { - sc = result.rslr.Response.Response.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - result.fn = client.listAllByDNSZoneNextResults - req, err := client.ListAllByDNSZonePreparer(ctx, resourceGroupName, zoneName, top, recordSetNameSuffix) - if err != nil { - err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "ListAllByDNSZone", nil, "Failure preparing request") - return - } - - resp, err := client.ListAllByDNSZoneSender(req) - if err != nil { - result.rslr.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "ListAllByDNSZone", resp, "Failure sending request") - return - } - - result.rslr, err = client.ListAllByDNSZoneResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "ListAllByDNSZone", resp, "Failure responding to request") - return - } - if result.rslr.hasNextLink() && result.rslr.IsEmpty() { - err = result.NextWithContext(ctx) - return - } - - return -} - -// ListAllByDNSZonePreparer prepares the ListAllByDNSZone request. -func (client RecordSetsClient) ListAllByDNSZonePreparer(ctx context.Context, resourceGroupName string, zoneName string, top *int32, recordSetNameSuffix string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "resourceGroupName": autorest.Encode("path", resourceGroupName), - "subscriptionId": autorest.Encode("path", client.SubscriptionID), - "zoneName": autorest.Encode("path", zoneName), - } - - const APIVersion = "2018-05-01" - queryParameters := map[string]interface{}{ - "api-version": APIVersion, - } - if top != nil { - queryParameters["$top"] = autorest.Encode("query", *top) - } - if len(recordSetNameSuffix) > 0 { - queryParameters["$recordsetnamesuffix"] = autorest.Encode("query", recordSetNameSuffix) - } - - preparer := autorest.CreatePreparer( - autorest.AsGet(), - autorest.WithBaseURL(client.BaseURI), - autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/dnsZones/{zoneName}/all", pathParameters), - autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// ListAllByDNSZoneSender sends the ListAllByDNSZone request. The method will close the -// http.Response Body if it receives an error. -func (client RecordSetsClient) ListAllByDNSZoneSender(req *http.Request) (*http.Response, error) { - return client.Send(req, azure.DoRetryWithRegistration(client.Client)) -} - -// ListAllByDNSZoneResponder handles the response to the ListAllByDNSZone request. The method always -// closes the http.Response Body. -func (client RecordSetsClient) ListAllByDNSZoneResponder(resp *http.Response) (result RecordSetListResult, err error) { - err = autorest.Respond( - resp, - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByUnmarshallingJSON(&result), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - return -} - -// listAllByDNSZoneNextResults retrieves the next set of results, if any. -func (client RecordSetsClient) listAllByDNSZoneNextResults(ctx context.Context, lastResults RecordSetListResult) (result RecordSetListResult, err error) { - req, err := lastResults.recordSetListResultPreparer(ctx) - if err != nil { - return result, autorest.NewErrorWithError(err, "dns.RecordSetsClient", "listAllByDNSZoneNextResults", nil, "Failure preparing next results request") - } - if req == nil { - return - } - resp, err := client.ListAllByDNSZoneSender(req) - if err != nil { - result.Response = autorest.Response{Response: resp} - return result, autorest.NewErrorWithError(err, "dns.RecordSetsClient", "listAllByDNSZoneNextResults", resp, "Failure sending next results request") - } - result, err = client.ListAllByDNSZoneResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "listAllByDNSZoneNextResults", resp, "Failure responding to next results request") - } - return -} - -// ListAllByDNSZoneComplete enumerates all values, automatically crossing page boundaries as required. -func (client RecordSetsClient) ListAllByDNSZoneComplete(ctx context.Context, resourceGroupName string, zoneName string, top *int32, recordSetNameSuffix string) (result RecordSetListResultIterator, err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/RecordSetsClient.ListAllByDNSZone") - defer func() { - sc := -1 - if result.Response().Response.Response != nil { - sc = result.page.Response().Response.Response.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - result.page, err = client.ListAllByDNSZone(ctx, resourceGroupName, zoneName, top, recordSetNameSuffix) - return -} - -// ListByDNSZone lists all record sets in a DNS zone. -// Parameters: -// resourceGroupName - the name of the resource group. -// zoneName - the name of the DNS zone (without a terminating dot). -// top - the maximum number of record sets to return. If not specified, returns up to 100 record sets. -// recordsetnamesuffix - the suffix label of the record set name that has to be used to filter the record set -// enumerations. If this parameter is specified, Enumeration will return only records that end with -// . -func (client RecordSetsClient) ListByDNSZone(ctx context.Context, resourceGroupName string, zoneName string, top *int32, recordsetnamesuffix string) (result RecordSetListResultPage, err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/RecordSetsClient.ListByDNSZone") - defer func() { - sc := -1 - if result.rslr.Response.Response != nil { - sc = result.rslr.Response.Response.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - result.fn = client.listByDNSZoneNextResults - req, err := client.ListByDNSZonePreparer(ctx, resourceGroupName, zoneName, top, recordsetnamesuffix) - if err != nil { - err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "ListByDNSZone", nil, "Failure preparing request") - return - } - - resp, err := client.ListByDNSZoneSender(req) - if err != nil { - result.rslr.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "ListByDNSZone", resp, "Failure sending request") - return - } - - result.rslr, err = client.ListByDNSZoneResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "ListByDNSZone", resp, "Failure responding to request") - return - } - if result.rslr.hasNextLink() && result.rslr.IsEmpty() { - err = result.NextWithContext(ctx) - return - } - - return -} - -// ListByDNSZonePreparer prepares the ListByDNSZone request. -func (client RecordSetsClient) ListByDNSZonePreparer(ctx context.Context, resourceGroupName string, zoneName string, top *int32, recordsetnamesuffix string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "resourceGroupName": autorest.Encode("path", resourceGroupName), - "subscriptionId": autorest.Encode("path", client.SubscriptionID), - "zoneName": autorest.Encode("path", zoneName), - } - - const APIVersion = "2018-05-01" - queryParameters := map[string]interface{}{ - "api-version": APIVersion, - } - if top != nil { - queryParameters["$top"] = autorest.Encode("query", *top) - } - if len(recordsetnamesuffix) > 0 { - queryParameters["$recordsetnamesuffix"] = autorest.Encode("query", recordsetnamesuffix) - } - - preparer := autorest.CreatePreparer( - autorest.AsGet(), - autorest.WithBaseURL(client.BaseURI), - autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/dnsZones/{zoneName}/recordsets", pathParameters), - autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// ListByDNSZoneSender sends the ListByDNSZone request. The method will close the -// http.Response Body if it receives an error. -func (client RecordSetsClient) ListByDNSZoneSender(req *http.Request) (*http.Response, error) { - return client.Send(req, azure.DoRetryWithRegistration(client.Client)) -} - -// ListByDNSZoneResponder handles the response to the ListByDNSZone request. The method always -// closes the http.Response Body. -func (client RecordSetsClient) ListByDNSZoneResponder(resp *http.Response) (result RecordSetListResult, err error) { - err = autorest.Respond( - resp, - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByUnmarshallingJSON(&result), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - return -} - -// listByDNSZoneNextResults retrieves the next set of results, if any. -func (client RecordSetsClient) listByDNSZoneNextResults(ctx context.Context, lastResults RecordSetListResult) (result RecordSetListResult, err error) { - req, err := lastResults.recordSetListResultPreparer(ctx) - if err != nil { - return result, autorest.NewErrorWithError(err, "dns.RecordSetsClient", "listByDNSZoneNextResults", nil, "Failure preparing next results request") - } - if req == nil { - return - } - resp, err := client.ListByDNSZoneSender(req) - if err != nil { - result.Response = autorest.Response{Response: resp} - return result, autorest.NewErrorWithError(err, "dns.RecordSetsClient", "listByDNSZoneNextResults", resp, "Failure sending next results request") - } - result, err = client.ListByDNSZoneResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "listByDNSZoneNextResults", resp, "Failure responding to next results request") - } - return -} - -// ListByDNSZoneComplete enumerates all values, automatically crossing page boundaries as required. -func (client RecordSetsClient) ListByDNSZoneComplete(ctx context.Context, resourceGroupName string, zoneName string, top *int32, recordsetnamesuffix string) (result RecordSetListResultIterator, err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/RecordSetsClient.ListByDNSZone") - defer func() { - sc := -1 - if result.Response().Response.Response != nil { - sc = result.page.Response().Response.Response.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - result.page, err = client.ListByDNSZone(ctx, resourceGroupName, zoneName, top, recordsetnamesuffix) - return -} - -// ListByType lists the record sets of a specified type in a DNS zone. -// Parameters: -// resourceGroupName - the name of the resource group. -// zoneName - the name of the DNS zone (without a terminating dot). -// recordType - the type of record sets to enumerate. -// top - the maximum number of record sets to return. If not specified, returns up to 100 record sets. -// recordsetnamesuffix - the suffix label of the record set name that has to be used to filter the record set -// enumerations. If this parameter is specified, Enumeration will return only records that end with -// . -func (client RecordSetsClient) ListByType(ctx context.Context, resourceGroupName string, zoneName string, recordType RecordType, top *int32, recordsetnamesuffix string) (result RecordSetListResultPage, err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/RecordSetsClient.ListByType") - defer func() { - sc := -1 - if result.rslr.Response.Response != nil { - sc = result.rslr.Response.Response.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - result.fn = client.listByTypeNextResults - req, err := client.ListByTypePreparer(ctx, resourceGroupName, zoneName, recordType, top, recordsetnamesuffix) - if err != nil { - err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "ListByType", nil, "Failure preparing request") - return - } - - resp, err := client.ListByTypeSender(req) - if err != nil { - result.rslr.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "ListByType", resp, "Failure sending request") - return - } - - result.rslr, err = client.ListByTypeResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "ListByType", resp, "Failure responding to request") - return - } - if result.rslr.hasNextLink() && result.rslr.IsEmpty() { - err = result.NextWithContext(ctx) - return - } - - return -} - -// ListByTypePreparer prepares the ListByType request. -func (client RecordSetsClient) ListByTypePreparer(ctx context.Context, resourceGroupName string, zoneName string, recordType RecordType, top *int32, recordsetnamesuffix string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "recordType": autorest.Encode("path", recordType), - "resourceGroupName": autorest.Encode("path", resourceGroupName), - "subscriptionId": autorest.Encode("path", client.SubscriptionID), - "zoneName": autorest.Encode("path", zoneName), - } - - const APIVersion = "2018-05-01" - queryParameters := map[string]interface{}{ - "api-version": APIVersion, - } - if top != nil { - queryParameters["$top"] = autorest.Encode("query", *top) - } - if len(recordsetnamesuffix) > 0 { - queryParameters["$recordsetnamesuffix"] = autorest.Encode("query", recordsetnamesuffix) - } - - preparer := autorest.CreatePreparer( - autorest.AsGet(), - autorest.WithBaseURL(client.BaseURI), - autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/dnsZones/{zoneName}/{recordType}", pathParameters), - autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// ListByTypeSender sends the ListByType request. The method will close the -// http.Response Body if it receives an error. -func (client RecordSetsClient) ListByTypeSender(req *http.Request) (*http.Response, error) { - return client.Send(req, azure.DoRetryWithRegistration(client.Client)) -} - -// ListByTypeResponder handles the response to the ListByType request. The method always -// closes the http.Response Body. -func (client RecordSetsClient) ListByTypeResponder(resp *http.Response) (result RecordSetListResult, err error) { - err = autorest.Respond( - resp, - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByUnmarshallingJSON(&result), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - return -} - -// listByTypeNextResults retrieves the next set of results, if any. -func (client RecordSetsClient) listByTypeNextResults(ctx context.Context, lastResults RecordSetListResult) (result RecordSetListResult, err error) { - req, err := lastResults.recordSetListResultPreparer(ctx) - if err != nil { - return result, autorest.NewErrorWithError(err, "dns.RecordSetsClient", "listByTypeNextResults", nil, "Failure preparing next results request") - } - if req == nil { - return - } - resp, err := client.ListByTypeSender(req) - if err != nil { - result.Response = autorest.Response{Response: resp} - return result, autorest.NewErrorWithError(err, "dns.RecordSetsClient", "listByTypeNextResults", resp, "Failure sending next results request") - } - result, err = client.ListByTypeResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "listByTypeNextResults", resp, "Failure responding to next results request") - } - return -} - -// ListByTypeComplete enumerates all values, automatically crossing page boundaries as required. -func (client RecordSetsClient) ListByTypeComplete(ctx context.Context, resourceGroupName string, zoneName string, recordType RecordType, top *int32, recordsetnamesuffix string) (result RecordSetListResultIterator, err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/RecordSetsClient.ListByType") - defer func() { - sc := -1 - if result.Response().Response.Response != nil { - sc = result.page.Response().Response.Response.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - result.page, err = client.ListByType(ctx, resourceGroupName, zoneName, recordType, top, recordsetnamesuffix) - return -} - -// Update updates a record set within a DNS zone. -// Parameters: -// resourceGroupName - the name of the resource group. -// zoneName - the name of the DNS zone (without a terminating dot). -// relativeRecordSetName - the name of the record set, relative to the name of the zone. -// recordType - the type of DNS record in this record set. -// parameters - parameters supplied to the Update operation. -// ifMatch - the etag of the record set. Omit this value to always overwrite the current record set. Specify -// the last-seen etag value to prevent accidentally overwriting concurrent changes. -func (client RecordSetsClient) Update(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType RecordType, parameters RecordSet, ifMatch string) (result RecordSet, err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/RecordSetsClient.Update") - defer func() { - sc := -1 - if result.Response.Response != nil { - sc = result.Response.Response.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - req, err := client.UpdatePreparer(ctx, resourceGroupName, zoneName, relativeRecordSetName, recordType, parameters, ifMatch) - if err != nil { - err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "Update", nil, "Failure preparing request") - return - } - - resp, err := client.UpdateSender(req) - if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "Update", resp, "Failure sending request") - return - } - - result, err = client.UpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "dns.RecordSetsClient", "Update", resp, "Failure responding to request") - return - } - - return -} - -// UpdatePreparer prepares the Update request. -func (client RecordSetsClient) UpdatePreparer(ctx context.Context, resourceGroupName string, zoneName string, relativeRecordSetName string, recordType RecordType, parameters RecordSet, ifMatch string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "recordType": autorest.Encode("path", recordType), - "relativeRecordSetName": relativeRecordSetName, - "resourceGroupName": autorest.Encode("path", resourceGroupName), - "subscriptionId": autorest.Encode("path", client.SubscriptionID), - "zoneName": autorest.Encode("path", zoneName), - } - - const APIVersion = "2018-05-01" - queryParameters := map[string]interface{}{ - "api-version": APIVersion, - } - - parameters.ID = nil - parameters.Name = nil - parameters.Type = nil - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/json; charset=utf-8"), - autorest.AsPatch(), - autorest.WithBaseURL(client.BaseURI), - autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/dnsZones/{zoneName}/{recordType}/{relativeRecordSetName}", pathParameters), - autorest.WithJSON(parameters), - autorest.WithQueryParameters(queryParameters)) - if len(ifMatch) > 0 { - preparer = autorest.DecoratePreparer(preparer, - autorest.WithHeader("If-Match", autorest.String(ifMatch))) - } - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// UpdateSender sends the Update request. The method will close the -// http.Response Body if it receives an error. -func (client RecordSetsClient) UpdateSender(req *http.Request) (*http.Response, error) { - return client.Send(req, azure.DoRetryWithRegistration(client.Client)) -} - -// UpdateResponder handles the response to the Update request. The method always -// closes the http.Response Body. -func (client RecordSetsClient) UpdateResponder(resp *http.Response) (result RecordSet, err error) { - err = autorest.Respond( - resp, - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByUnmarshallingJSON(&result), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - return -} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns/resourcereference.go b/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns/resourcereference.go deleted file mode 100644 index 87573585..00000000 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns/resourcereference.go +++ /dev/null @@ -1,107 +0,0 @@ -package dns - -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See License.txt in the project root for license information. -// -// Code generated by Microsoft (R) AutoRest Code Generator. -// Changes may cause incorrect behavior and will be lost if the code is regenerated. - -import ( - "context" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/tracing" - "net/http" -) - -// ResourceReferenceClient is the the DNS Management Client. -type ResourceReferenceClient struct { - BaseClient -} - -// NewResourceReferenceClient creates an instance of the ResourceReferenceClient client. -func NewResourceReferenceClient(subscriptionID string) ResourceReferenceClient { - return NewResourceReferenceClientWithBaseURI(DefaultBaseURI, subscriptionID) -} - -// NewResourceReferenceClientWithBaseURI creates an instance of the ResourceReferenceClient client using a custom -// endpoint. Use this when interacting with an Azure cloud that uses a non-standard base URI (sovereign clouds, Azure -// stack). -func NewResourceReferenceClientWithBaseURI(baseURI string, subscriptionID string) ResourceReferenceClient { - return ResourceReferenceClient{NewWithBaseURI(baseURI, subscriptionID)} -} - -// GetByTargetResources returns the DNS records specified by the referencing targetResourceIds. -// Parameters: -// parameters - properties for dns resource reference request. -func (client ResourceReferenceClient) GetByTargetResources(ctx context.Context, parameters ResourceReferenceRequest) (result ResourceReferenceResult, err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/ResourceReferenceClient.GetByTargetResources") - defer func() { - sc := -1 - if result.Response.Response != nil { - sc = result.Response.Response.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - req, err := client.GetByTargetResourcesPreparer(ctx, parameters) - if err != nil { - err = autorest.NewErrorWithError(err, "dns.ResourceReferenceClient", "GetByTargetResources", nil, "Failure preparing request") - return - } - - resp, err := client.GetByTargetResourcesSender(req) - if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "dns.ResourceReferenceClient", "GetByTargetResources", resp, "Failure sending request") - return - } - - result, err = client.GetByTargetResourcesResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "dns.ResourceReferenceClient", "GetByTargetResources", resp, "Failure responding to request") - return - } - - return -} - -// GetByTargetResourcesPreparer prepares the GetByTargetResources request. -func (client ResourceReferenceClient) GetByTargetResourcesPreparer(ctx context.Context, parameters ResourceReferenceRequest) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "subscriptionId": autorest.Encode("path", client.SubscriptionID), - } - - const APIVersion = "2018-05-01" - queryParameters := map[string]interface{}{ - "api-version": APIVersion, - } - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/json; charset=utf-8"), - autorest.AsPost(), - autorest.WithBaseURL(client.BaseURI), - autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Network/getDnsResourceReference", pathParameters), - autorest.WithJSON(parameters), - autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// GetByTargetResourcesSender sends the GetByTargetResources request. The method will close the -// http.Response Body if it receives an error. -func (client ResourceReferenceClient) GetByTargetResourcesSender(req *http.Request) (*http.Response, error) { - return client.Send(req, azure.DoRetryWithRegistration(client.Client)) -} - -// GetByTargetResourcesResponder handles the response to the GetByTargetResources request. The method always -// closes the http.Response Body. -func (client ResourceReferenceClient) GetByTargetResourcesResponder(resp *http.Response) (result ResourceReferenceResult, err error) { - err = autorest.Respond( - resp, - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByUnmarshallingJSON(&result), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - return -} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns/version.go b/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns/version.go deleted file mode 100644 index 940b45d2..00000000 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns/version.go +++ /dev/null @@ -1,19 +0,0 @@ -package dns - -import "github.com/Azure/azure-sdk-for-go/version" - -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See License.txt in the project root for license information. -// -// Code generated by Microsoft (R) AutoRest Code Generator. -// Changes may cause incorrect behavior and will be lost if the code is regenerated. - -// UserAgent returns the UserAgent string to use when sending http.Requests. -func UserAgent() string { - return "Azure-SDK-For-Go/" + Version() + " dns/2018-05-01" -} - -// Version returns the semantic version (see http://semver.org) of the client. -func Version() string { - return version.Number -} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns/zones.go b/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns/zones.go deleted file mode 100644 index e004a725..00000000 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns/zones.go +++ /dev/null @@ -1,606 +0,0 @@ -package dns - -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See License.txt in the project root for license information. -// -// Code generated by Microsoft (R) AutoRest Code Generator. -// Changes may cause incorrect behavior and will be lost if the code is regenerated. - -import ( - "context" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/tracing" - "net/http" -) - -// ZonesClient is the the DNS Management Client. -type ZonesClient struct { - BaseClient -} - -// NewZonesClient creates an instance of the ZonesClient client. -func NewZonesClient(subscriptionID string) ZonesClient { - return NewZonesClientWithBaseURI(DefaultBaseURI, subscriptionID) -} - -// NewZonesClientWithBaseURI creates an instance of the ZonesClient client using a custom endpoint. Use this when -// interacting with an Azure cloud that uses a non-standard base URI (sovereign clouds, Azure stack). -func NewZonesClientWithBaseURI(baseURI string, subscriptionID string) ZonesClient { - return ZonesClient{NewWithBaseURI(baseURI, subscriptionID)} -} - -// CreateOrUpdate creates or updates a DNS zone. Does not modify DNS records within the zone. -// Parameters: -// resourceGroupName - the name of the resource group. -// zoneName - the name of the DNS zone (without a terminating dot). -// parameters - parameters supplied to the CreateOrUpdate operation. -// ifMatch - the etag of the DNS zone. Omit this value to always overwrite the current zone. Specify the -// last-seen etag value to prevent accidentally overwriting any concurrent changes. -// ifNoneMatch - set to '*' to allow a new DNS zone to be created, but to prevent updating an existing zone. -// Other values will be ignored. -func (client ZonesClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, zoneName string, parameters Zone, ifMatch string, ifNoneMatch string) (result Zone, err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/ZonesClient.CreateOrUpdate") - defer func() { - sc := -1 - if result.Response.Response != nil { - sc = result.Response.Response.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - req, err := client.CreateOrUpdatePreparer(ctx, resourceGroupName, zoneName, parameters, ifMatch, ifNoneMatch) - if err != nil { - err = autorest.NewErrorWithError(err, "dns.ZonesClient", "CreateOrUpdate", nil, "Failure preparing request") - return - } - - resp, err := client.CreateOrUpdateSender(req) - if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "dns.ZonesClient", "CreateOrUpdate", resp, "Failure sending request") - return - } - - result, err = client.CreateOrUpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "dns.ZonesClient", "CreateOrUpdate", resp, "Failure responding to request") - return - } - - return -} - -// CreateOrUpdatePreparer prepares the CreateOrUpdate request. -func (client ZonesClient) CreateOrUpdatePreparer(ctx context.Context, resourceGroupName string, zoneName string, parameters Zone, ifMatch string, ifNoneMatch string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "resourceGroupName": autorest.Encode("path", resourceGroupName), - "subscriptionId": autorest.Encode("path", client.SubscriptionID), - "zoneName": autorest.Encode("path", zoneName), - } - - const APIVersion = "2018-05-01" - queryParameters := map[string]interface{}{ - "api-version": APIVersion, - } - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/json; charset=utf-8"), - autorest.AsPut(), - autorest.WithBaseURL(client.BaseURI), - autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/dnsZones/{zoneName}", pathParameters), - autorest.WithJSON(parameters), - autorest.WithQueryParameters(queryParameters)) - if len(ifMatch) > 0 { - preparer = autorest.DecoratePreparer(preparer, - autorest.WithHeader("If-Match", autorest.String(ifMatch))) - } - if len(ifNoneMatch) > 0 { - preparer = autorest.DecoratePreparer(preparer, - autorest.WithHeader("If-None-Match", autorest.String(ifNoneMatch))) - } - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the -// http.Response Body if it receives an error. -func (client ZonesClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { - return client.Send(req, azure.DoRetryWithRegistration(client.Client)) -} - -// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always -// closes the http.Response Body. -func (client ZonesClient) CreateOrUpdateResponder(resp *http.Response) (result Zone, err error) { - err = autorest.Respond( - resp, - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated), - autorest.ByUnmarshallingJSON(&result), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - return -} - -// Delete deletes a DNS zone. WARNING: All DNS records in the zone will also be deleted. This operation cannot be -// undone. -// Parameters: -// resourceGroupName - the name of the resource group. -// zoneName - the name of the DNS zone (without a terminating dot). -// ifMatch - the etag of the DNS zone. Omit this value to always delete the current zone. Specify the last-seen -// etag value to prevent accidentally deleting any concurrent changes. -func (client ZonesClient) Delete(ctx context.Context, resourceGroupName string, zoneName string, ifMatch string) (result ZonesDeleteFuture, err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/ZonesClient.Delete") - defer func() { - sc := -1 - if result.FutureAPI != nil && result.FutureAPI.Response() != nil { - sc = result.FutureAPI.Response().StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - req, err := client.DeletePreparer(ctx, resourceGroupName, zoneName, ifMatch) - if err != nil { - err = autorest.NewErrorWithError(err, "dns.ZonesClient", "Delete", nil, "Failure preparing request") - return - } - - result, err = client.DeleteSender(req) - if err != nil { - err = autorest.NewErrorWithError(err, "dns.ZonesClient", "Delete", result.Response(), "Failure sending request") - return - } - - return -} - -// DeletePreparer prepares the Delete request. -func (client ZonesClient) DeletePreparer(ctx context.Context, resourceGroupName string, zoneName string, ifMatch string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "resourceGroupName": autorest.Encode("path", resourceGroupName), - "subscriptionId": autorest.Encode("path", client.SubscriptionID), - "zoneName": autorest.Encode("path", zoneName), - } - - const APIVersion = "2018-05-01" - queryParameters := map[string]interface{}{ - "api-version": APIVersion, - } - - preparer := autorest.CreatePreparer( - autorest.AsDelete(), - autorest.WithBaseURL(client.BaseURI), - autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/dnsZones/{zoneName}", pathParameters), - autorest.WithQueryParameters(queryParameters)) - if len(ifMatch) > 0 { - preparer = autorest.DecoratePreparer(preparer, - autorest.WithHeader("If-Match", autorest.String(ifMatch))) - } - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// DeleteSender sends the Delete request. The method will close the -// http.Response Body if it receives an error. -func (client ZonesClient) DeleteSender(req *http.Request) (future ZonesDeleteFuture, err error) { - var resp *http.Response - future.FutureAPI = &azure.Future{} - resp, err = client.Send(req, azure.DoRetryWithRegistration(client.Client)) - if err != nil { - return - } - var azf azure.Future - azf, err = azure.NewFutureFromResponse(resp) - future.FutureAPI = &azf - future.Result = future.result - return -} - -// DeleteResponder handles the response to the Delete request. The method always -// closes the http.Response Body. -func (client ZonesClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent), - autorest.ByClosing()) - result.Response = resp - return -} - -// Get gets a DNS zone. Retrieves the zone properties, but not the record sets within the zone. -// Parameters: -// resourceGroupName - the name of the resource group. -// zoneName - the name of the DNS zone (without a terminating dot). -func (client ZonesClient) Get(ctx context.Context, resourceGroupName string, zoneName string) (result Zone, err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/ZonesClient.Get") - defer func() { - sc := -1 - if result.Response.Response != nil { - sc = result.Response.Response.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - req, err := client.GetPreparer(ctx, resourceGroupName, zoneName) - if err != nil { - err = autorest.NewErrorWithError(err, "dns.ZonesClient", "Get", nil, "Failure preparing request") - return - } - - resp, err := client.GetSender(req) - if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "dns.ZonesClient", "Get", resp, "Failure sending request") - return - } - - result, err = client.GetResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "dns.ZonesClient", "Get", resp, "Failure responding to request") - return - } - - return -} - -// GetPreparer prepares the Get request. -func (client ZonesClient) GetPreparer(ctx context.Context, resourceGroupName string, zoneName string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "resourceGroupName": autorest.Encode("path", resourceGroupName), - "subscriptionId": autorest.Encode("path", client.SubscriptionID), - "zoneName": autorest.Encode("path", zoneName), - } - - const APIVersion = "2018-05-01" - queryParameters := map[string]interface{}{ - "api-version": APIVersion, - } - - preparer := autorest.CreatePreparer( - autorest.AsGet(), - autorest.WithBaseURL(client.BaseURI), - autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/dnsZones/{zoneName}", pathParameters), - autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// GetSender sends the Get request. The method will close the -// http.Response Body if it receives an error. -func (client ZonesClient) GetSender(req *http.Request) (*http.Response, error) { - return client.Send(req, azure.DoRetryWithRegistration(client.Client)) -} - -// GetResponder handles the response to the Get request. The method always -// closes the http.Response Body. -func (client ZonesClient) GetResponder(resp *http.Response) (result Zone, err error) { - err = autorest.Respond( - resp, - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByUnmarshallingJSON(&result), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - return -} - -// List lists the DNS zones in all resource groups in a subscription. -// Parameters: -// top - the maximum number of DNS zones to return. If not specified, returns up to 100 zones. -func (client ZonesClient) List(ctx context.Context, top *int32) (result ZoneListResultPage, err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/ZonesClient.List") - defer func() { - sc := -1 - if result.zlr.Response.Response != nil { - sc = result.zlr.Response.Response.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - result.fn = client.listNextResults - req, err := client.ListPreparer(ctx, top) - if err != nil { - err = autorest.NewErrorWithError(err, "dns.ZonesClient", "List", nil, "Failure preparing request") - return - } - - resp, err := client.ListSender(req) - if err != nil { - result.zlr.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "dns.ZonesClient", "List", resp, "Failure sending request") - return - } - - result.zlr, err = client.ListResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "dns.ZonesClient", "List", resp, "Failure responding to request") - return - } - if result.zlr.hasNextLink() && result.zlr.IsEmpty() { - err = result.NextWithContext(ctx) - return - } - - return -} - -// ListPreparer prepares the List request. -func (client ZonesClient) ListPreparer(ctx context.Context, top *int32) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "subscriptionId": autorest.Encode("path", client.SubscriptionID), - } - - const APIVersion = "2018-05-01" - queryParameters := map[string]interface{}{ - "api-version": APIVersion, - } - if top != nil { - queryParameters["$top"] = autorest.Encode("query", *top) - } - - preparer := autorest.CreatePreparer( - autorest.AsGet(), - autorest.WithBaseURL(client.BaseURI), - autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Network/dnszones", pathParameters), - autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// ListSender sends the List request. The method will close the -// http.Response Body if it receives an error. -func (client ZonesClient) ListSender(req *http.Request) (*http.Response, error) { - return client.Send(req, azure.DoRetryWithRegistration(client.Client)) -} - -// ListResponder handles the response to the List request. The method always -// closes the http.Response Body. -func (client ZonesClient) ListResponder(resp *http.Response) (result ZoneListResult, err error) { - err = autorest.Respond( - resp, - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByUnmarshallingJSON(&result), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - return -} - -// listNextResults retrieves the next set of results, if any. -func (client ZonesClient) listNextResults(ctx context.Context, lastResults ZoneListResult) (result ZoneListResult, err error) { - req, err := lastResults.zoneListResultPreparer(ctx) - if err != nil { - return result, autorest.NewErrorWithError(err, "dns.ZonesClient", "listNextResults", nil, "Failure preparing next results request") - } - if req == nil { - return - } - resp, err := client.ListSender(req) - if err != nil { - result.Response = autorest.Response{Response: resp} - return result, autorest.NewErrorWithError(err, "dns.ZonesClient", "listNextResults", resp, "Failure sending next results request") - } - result, err = client.ListResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "dns.ZonesClient", "listNextResults", resp, "Failure responding to next results request") - } - return -} - -// ListComplete enumerates all values, automatically crossing page boundaries as required. -func (client ZonesClient) ListComplete(ctx context.Context, top *int32) (result ZoneListResultIterator, err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/ZonesClient.List") - defer func() { - sc := -1 - if result.Response().Response.Response != nil { - sc = result.page.Response().Response.Response.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - result.page, err = client.List(ctx, top) - return -} - -// ListByResourceGroup lists the DNS zones within a resource group. -// Parameters: -// resourceGroupName - the name of the resource group. -// top - the maximum number of record sets to return. If not specified, returns up to 100 record sets. -func (client ZonesClient) ListByResourceGroup(ctx context.Context, resourceGroupName string, top *int32) (result ZoneListResultPage, err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/ZonesClient.ListByResourceGroup") - defer func() { - sc := -1 - if result.zlr.Response.Response != nil { - sc = result.zlr.Response.Response.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - result.fn = client.listByResourceGroupNextResults - req, err := client.ListByResourceGroupPreparer(ctx, resourceGroupName, top) - if err != nil { - err = autorest.NewErrorWithError(err, "dns.ZonesClient", "ListByResourceGroup", nil, "Failure preparing request") - return - } - - resp, err := client.ListByResourceGroupSender(req) - if err != nil { - result.zlr.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "dns.ZonesClient", "ListByResourceGroup", resp, "Failure sending request") - return - } - - result.zlr, err = client.ListByResourceGroupResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "dns.ZonesClient", "ListByResourceGroup", resp, "Failure responding to request") - return - } - if result.zlr.hasNextLink() && result.zlr.IsEmpty() { - err = result.NextWithContext(ctx) - return - } - - return -} - -// ListByResourceGroupPreparer prepares the ListByResourceGroup request. -func (client ZonesClient) ListByResourceGroupPreparer(ctx context.Context, resourceGroupName string, top *int32) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "resourceGroupName": autorest.Encode("path", resourceGroupName), - "subscriptionId": autorest.Encode("path", client.SubscriptionID), - } - - const APIVersion = "2018-05-01" - queryParameters := map[string]interface{}{ - "api-version": APIVersion, - } - if top != nil { - queryParameters["$top"] = autorest.Encode("query", *top) - } - - preparer := autorest.CreatePreparer( - autorest.AsGet(), - autorest.WithBaseURL(client.BaseURI), - autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/dnsZones", pathParameters), - autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// ListByResourceGroupSender sends the ListByResourceGroup request. The method will close the -// http.Response Body if it receives an error. -func (client ZonesClient) ListByResourceGroupSender(req *http.Request) (*http.Response, error) { - return client.Send(req, azure.DoRetryWithRegistration(client.Client)) -} - -// ListByResourceGroupResponder handles the response to the ListByResourceGroup request. The method always -// closes the http.Response Body. -func (client ZonesClient) ListByResourceGroupResponder(resp *http.Response) (result ZoneListResult, err error) { - err = autorest.Respond( - resp, - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByUnmarshallingJSON(&result), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - return -} - -// listByResourceGroupNextResults retrieves the next set of results, if any. -func (client ZonesClient) listByResourceGroupNextResults(ctx context.Context, lastResults ZoneListResult) (result ZoneListResult, err error) { - req, err := lastResults.zoneListResultPreparer(ctx) - if err != nil { - return result, autorest.NewErrorWithError(err, "dns.ZonesClient", "listByResourceGroupNextResults", nil, "Failure preparing next results request") - } - if req == nil { - return - } - resp, err := client.ListByResourceGroupSender(req) - if err != nil { - result.Response = autorest.Response{Response: resp} - return result, autorest.NewErrorWithError(err, "dns.ZonesClient", "listByResourceGroupNextResults", resp, "Failure sending next results request") - } - result, err = client.ListByResourceGroupResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "dns.ZonesClient", "listByResourceGroupNextResults", resp, "Failure responding to next results request") - } - return -} - -// ListByResourceGroupComplete enumerates all values, automatically crossing page boundaries as required. -func (client ZonesClient) ListByResourceGroupComplete(ctx context.Context, resourceGroupName string, top *int32) (result ZoneListResultIterator, err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/ZonesClient.ListByResourceGroup") - defer func() { - sc := -1 - if result.Response().Response.Response != nil { - sc = result.page.Response().Response.Response.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - result.page, err = client.ListByResourceGroup(ctx, resourceGroupName, top) - return -} - -// Update updates a DNS zone. Does not modify DNS records within the zone. -// Parameters: -// resourceGroupName - the name of the resource group. -// zoneName - the name of the DNS zone (without a terminating dot). -// parameters - parameters supplied to the Update operation. -// ifMatch - the etag of the DNS zone. Omit this value to always overwrite the current zone. Specify the -// last-seen etag value to prevent accidentally overwriting any concurrent changes. -func (client ZonesClient) Update(ctx context.Context, resourceGroupName string, zoneName string, parameters ZoneUpdate, ifMatch string) (result Zone, err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/ZonesClient.Update") - defer func() { - sc := -1 - if result.Response.Response != nil { - sc = result.Response.Response.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - req, err := client.UpdatePreparer(ctx, resourceGroupName, zoneName, parameters, ifMatch) - if err != nil { - err = autorest.NewErrorWithError(err, "dns.ZonesClient", "Update", nil, "Failure preparing request") - return - } - - resp, err := client.UpdateSender(req) - if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "dns.ZonesClient", "Update", resp, "Failure sending request") - return - } - - result, err = client.UpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "dns.ZonesClient", "Update", resp, "Failure responding to request") - return - } - - return -} - -// UpdatePreparer prepares the Update request. -func (client ZonesClient) UpdatePreparer(ctx context.Context, resourceGroupName string, zoneName string, parameters ZoneUpdate, ifMatch string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "resourceGroupName": autorest.Encode("path", resourceGroupName), - "subscriptionId": autorest.Encode("path", client.SubscriptionID), - "zoneName": autorest.Encode("path", zoneName), - } - - const APIVersion = "2018-05-01" - queryParameters := map[string]interface{}{ - "api-version": APIVersion, - } - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/json; charset=utf-8"), - autorest.AsPatch(), - autorest.WithBaseURL(client.BaseURI), - autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/dnsZones/{zoneName}", pathParameters), - autorest.WithJSON(parameters), - autorest.WithQueryParameters(queryParameters)) - if len(ifMatch) > 0 { - preparer = autorest.DecoratePreparer(preparer, - autorest.WithHeader("If-Match", autorest.String(ifMatch))) - } - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// UpdateSender sends the Update request. The method will close the -// http.Response Body if it receives an error. -func (client ZonesClient) UpdateSender(req *http.Request) (*http.Response, error) { - return client.Send(req, azure.DoRetryWithRegistration(client.Client)) -} - -// UpdateResponder handles the response to the Update request. The method always -// closes the http.Response Body. -func (client ZonesClient) UpdateResponder(resp *http.Response) (result Zone, err error) { - err = autorest.Respond( - resp, - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByUnmarshallingJSON(&result), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - return -} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2020-06-01/privatedns/CHANGELOG.md b/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2020-06-01/privatedns/CHANGELOG.md deleted file mode 100644 index 52911e4c..00000000 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2020-06-01/privatedns/CHANGELOG.md +++ /dev/null @@ -1,2 +0,0 @@ -# Change History - diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2020-06-01/privatedns/_meta.json b/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2020-06-01/privatedns/_meta.json deleted file mode 100644 index b7152c03..00000000 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2020-06-01/privatedns/_meta.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "commit": "1c8d7850afbec9ede6de6f2d14bcc30896a74ed6", - "readme": "/_/azure-rest-api-specs/specification/privatedns/resource-manager/readme.md", - "tag": "package-2020-06", - "use": "@microsoft.azure/autorest.go@2.1.188", - "repository_url": "https://github.com/Azure/azure-rest-api-specs.git", - "autorest_command": "autorest --use=@microsoft.azure/autorest.go@2.1.188 --tag=package-2020-06 --go-sdk-folder=/_/azure-sdk-for-go --go --verbose --use-onever --version=2.0.4421 --go.license-header=MICROSOFT_MIT_NO_VERSION /_/azure-rest-api-specs/specification/privatedns/resource-manager/readme.md", - "additional_properties": { - "additional_options": "--go --verbose --use-onever --version=2.0.4421 --go.license-header=MICROSOFT_MIT_NO_VERSION" - } -} \ No newline at end of file diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2020-06-01/privatedns/client.go b/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2020-06-01/privatedns/client.go deleted file mode 100644 index f433024c..00000000 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2020-06-01/privatedns/client.go +++ /dev/null @@ -1,43 +0,0 @@ -// Deprecated: Please note, this package has been deprecated. A replacement package is available [github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/privatedns/armprivatedns](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/privatedns/armprivatedns). We strongly encourage you to upgrade to continue receiving updates. See [Migration Guide](https://aka.ms/azsdk/golang/t2/migration) for guidance on upgrading. Refer to our [deprecation policy](https://azure.github.io/azure-sdk/policies_support.html) for more details. -// -// Package privatedns implements the Azure ARM Privatedns service API version 2020-06-01. -// -// The Private DNS Management Client. -package privatedns - -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See License.txt in the project root for license information. -// -// Code generated by Microsoft (R) AutoRest Code Generator. -// Changes may cause incorrect behavior and will be lost if the code is regenerated. - -import ( - "github.com/Azure/go-autorest/autorest" -) - -const ( - // DefaultBaseURI is the default URI used for the service Privatedns - DefaultBaseURI = "https://management.azure.com" -) - -// BaseClient is the base client for Privatedns. -type BaseClient struct { - autorest.Client - BaseURI string - SubscriptionID string -} - -// New creates an instance of the BaseClient client. -func New(subscriptionID string) BaseClient { - return NewWithBaseURI(DefaultBaseURI, subscriptionID) -} - -// NewWithBaseURI creates an instance of the BaseClient client using a custom endpoint. Use this when interacting with -// an Azure cloud that uses a non-standard base URI (sovereign clouds, Azure stack). -func NewWithBaseURI(baseURI string, subscriptionID string) BaseClient { - return BaseClient{ - Client: autorest.NewClientWithUserAgent(UserAgent()), - BaseURI: baseURI, - SubscriptionID: subscriptionID, - } -} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2020-06-01/privatedns/enums.go b/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2020-06-01/privatedns/enums.go deleted file mode 100644 index a4cbf2a6..00000000 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2020-06-01/privatedns/enums.go +++ /dev/null @@ -1,72 +0,0 @@ -package privatedns - -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See License.txt in the project root for license information. -// -// Code generated by Microsoft (R) AutoRest Code Generator. -// Changes may cause incorrect behavior and will be lost if the code is regenerated. - -// ProvisioningState enumerates the values for provisioning state. -type ProvisioningState string - -const ( - // Canceled ... - Canceled ProvisioningState = "Canceled" - // Creating ... - Creating ProvisioningState = "Creating" - // Deleting ... - Deleting ProvisioningState = "Deleting" - // Failed ... - Failed ProvisioningState = "Failed" - // Succeeded ... - Succeeded ProvisioningState = "Succeeded" - // Updating ... - Updating ProvisioningState = "Updating" -) - -// PossibleProvisioningStateValues returns an array of possible values for the ProvisioningState const type. -func PossibleProvisioningStateValues() []ProvisioningState { - return []ProvisioningState{Canceled, Creating, Deleting, Failed, Succeeded, Updating} -} - -// RecordType enumerates the values for record type. -type RecordType string - -const ( - // A ... - A RecordType = "A" - // AAAA ... - AAAA RecordType = "AAAA" - // CNAME ... - CNAME RecordType = "CNAME" - // MX ... - MX RecordType = "MX" - // PTR ... - PTR RecordType = "PTR" - // SOA ... - SOA RecordType = "SOA" - // SRV ... - SRV RecordType = "SRV" - // TXT ... - TXT RecordType = "TXT" -) - -// PossibleRecordTypeValues returns an array of possible values for the RecordType const type. -func PossibleRecordTypeValues() []RecordType { - return []RecordType{A, AAAA, CNAME, MX, PTR, SOA, SRV, TXT} -} - -// VirtualNetworkLinkState enumerates the values for virtual network link state. -type VirtualNetworkLinkState string - -const ( - // Completed ... - Completed VirtualNetworkLinkState = "Completed" - // InProgress ... - InProgress VirtualNetworkLinkState = "InProgress" -) - -// PossibleVirtualNetworkLinkStateValues returns an array of possible values for the VirtualNetworkLinkState const type. -func PossibleVirtualNetworkLinkStateValues() []VirtualNetworkLinkState { - return []VirtualNetworkLinkState{Completed, InProgress} -} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2020-06-01/privatedns/models.go b/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2020-06-01/privatedns/models.go deleted file mode 100644 index 23bc8491..00000000 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2020-06-01/privatedns/models.go +++ /dev/null @@ -1,1352 +0,0 @@ -package privatedns - -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See License.txt in the project root for license information. -// -// Code generated by Microsoft (R) AutoRest Code Generator. -// Changes may cause incorrect behavior and will be lost if the code is regenerated. - -import ( - "context" - "encoding/json" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/to" - "github.com/Azure/go-autorest/tracing" - "net/http" -) - -// The package's fully qualified name. -const fqdn = "github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2020-06-01/privatedns" - -// AaaaRecord an AAAA record. -type AaaaRecord struct { - // Ipv6Address - The IPv6 address of this AAAA record. - Ipv6Address *string `json:"ipv6Address,omitempty"` -} - -// ARecord an A record. -type ARecord struct { - // Ipv4Address - The IPv4 address of this A record. - Ipv4Address *string `json:"ipv4Address,omitempty"` -} - -// CloudError an error response from the service. -type CloudError struct { - // Error - Cloud error body. - Error *CloudErrorBody `json:"error,omitempty"` -} - -// CloudErrorBody an error response from the service. -type CloudErrorBody struct { - // Code - An identifier for the error. Codes are invariant and are intended to be consumed programmatically. - Code *string `json:"code,omitempty"` - // Message - A message describing the error, intended to be suitable for display in a user interface. - Message *string `json:"message,omitempty"` - // Target - The target of the particular error. For example, the name of the property in error. - Target *string `json:"target,omitempty"` - // Details - A list of additional details about the error. - Details *[]CloudErrorBody `json:"details,omitempty"` -} - -// CnameRecord a CNAME record. -type CnameRecord struct { - // Cname - The canonical name for this CNAME record. - Cname *string `json:"cname,omitempty"` -} - -// MxRecord an MX record. -type MxRecord struct { - // Preference - The preference value for this MX record. - Preference *int32 `json:"preference,omitempty"` - // Exchange - The domain name of the mail host for this MX record. - Exchange *string `json:"exchange,omitempty"` -} - -// PrivateZone describes a Private DNS zone. -type PrivateZone struct { - autorest.Response `json:"-"` - // Etag - The ETag of the zone. - Etag *string `json:"etag,omitempty"` - // PrivateZoneProperties - Properties of the Private DNS zone. - *PrivateZoneProperties `json:"properties,omitempty"` - // Tags - Resource tags. - Tags map[string]*string `json:"tags"` - // Location - The Azure Region where the resource lives - Location *string `json:"location,omitempty"` - // ID - READ-ONLY; Fully qualified resource Id for the resource. Example - '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/privateDnsZones/{privateDnsZoneName}'. - ID *string `json:"id,omitempty"` - // Name - READ-ONLY; The name of the resource - Name *string `json:"name,omitempty"` - // Type - READ-ONLY; The type of the resource. Example - 'Microsoft.Network/privateDnsZones'. - Type *string `json:"type,omitempty"` -} - -// MarshalJSON is the custom marshaler for PrivateZone. -func (pz PrivateZone) MarshalJSON() ([]byte, error) { - objectMap := make(map[string]interface{}) - if pz.Etag != nil { - objectMap["etag"] = pz.Etag - } - if pz.PrivateZoneProperties != nil { - objectMap["properties"] = pz.PrivateZoneProperties - } - if pz.Tags != nil { - objectMap["tags"] = pz.Tags - } - if pz.Location != nil { - objectMap["location"] = pz.Location - } - return json.Marshal(objectMap) -} - -// UnmarshalJSON is the custom unmarshaler for PrivateZone struct. -func (pz *PrivateZone) UnmarshalJSON(body []byte) error { - var m map[string]*json.RawMessage - err := json.Unmarshal(body, &m) - if err != nil { - return err - } - for k, v := range m { - switch k { - case "etag": - if v != nil { - var etag string - err = json.Unmarshal(*v, &etag) - if err != nil { - return err - } - pz.Etag = &etag - } - case "properties": - if v != nil { - var privateZoneProperties PrivateZoneProperties - err = json.Unmarshal(*v, &privateZoneProperties) - if err != nil { - return err - } - pz.PrivateZoneProperties = &privateZoneProperties - } - case "tags": - if v != nil { - var tags map[string]*string - err = json.Unmarshal(*v, &tags) - if err != nil { - return err - } - pz.Tags = tags - } - case "location": - if v != nil { - var location string - err = json.Unmarshal(*v, &location) - if err != nil { - return err - } - pz.Location = &location - } - case "id": - if v != nil { - var ID string - err = json.Unmarshal(*v, &ID) - if err != nil { - return err - } - pz.ID = &ID - } - case "name": - if v != nil { - var name string - err = json.Unmarshal(*v, &name) - if err != nil { - return err - } - pz.Name = &name - } - case "type": - if v != nil { - var typeVar string - err = json.Unmarshal(*v, &typeVar) - if err != nil { - return err - } - pz.Type = &typeVar - } - } - } - - return nil -} - -// PrivateZoneListResult the response to a Private DNS zone list operation. -type PrivateZoneListResult struct { - autorest.Response `json:"-"` - // Value - Information about the Private DNS zones. - Value *[]PrivateZone `json:"value,omitempty"` - // NextLink - READ-ONLY; The continuation token for the next page of results. - NextLink *string `json:"nextLink,omitempty"` -} - -// MarshalJSON is the custom marshaler for PrivateZoneListResult. -func (pzlr PrivateZoneListResult) MarshalJSON() ([]byte, error) { - objectMap := make(map[string]interface{}) - if pzlr.Value != nil { - objectMap["value"] = pzlr.Value - } - return json.Marshal(objectMap) -} - -// PrivateZoneListResultIterator provides access to a complete listing of PrivateZone values. -type PrivateZoneListResultIterator struct { - i int - page PrivateZoneListResultPage -} - -// NextWithContext advances to the next value. If there was an error making -// the request the iterator does not advance and the error is returned. -func (iter *PrivateZoneListResultIterator) NextWithContext(ctx context.Context) (err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/PrivateZoneListResultIterator.NextWithContext") - defer func() { - sc := -1 - if iter.Response().Response.Response != nil { - sc = iter.Response().Response.Response.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - iter.i++ - if iter.i < len(iter.page.Values()) { - return nil - } - err = iter.page.NextWithContext(ctx) - if err != nil { - iter.i-- - return err - } - iter.i = 0 - return nil -} - -// Next advances to the next value. If there was an error making -// the request the iterator does not advance and the error is returned. -// Deprecated: Use NextWithContext() instead. -func (iter *PrivateZoneListResultIterator) Next() error { - return iter.NextWithContext(context.Background()) -} - -// NotDone returns true if the enumeration should be started or is not yet complete. -func (iter PrivateZoneListResultIterator) NotDone() bool { - return iter.page.NotDone() && iter.i < len(iter.page.Values()) -} - -// Response returns the raw server response from the last page request. -func (iter PrivateZoneListResultIterator) Response() PrivateZoneListResult { - return iter.page.Response() -} - -// Value returns the current value or a zero-initialized value if the -// iterator has advanced beyond the end of the collection. -func (iter PrivateZoneListResultIterator) Value() PrivateZone { - if !iter.page.NotDone() { - return PrivateZone{} - } - return iter.page.Values()[iter.i] -} - -// Creates a new instance of the PrivateZoneListResultIterator type. -func NewPrivateZoneListResultIterator(page PrivateZoneListResultPage) PrivateZoneListResultIterator { - return PrivateZoneListResultIterator{page: page} -} - -// IsEmpty returns true if the ListResult contains no values. -func (pzlr PrivateZoneListResult) IsEmpty() bool { - return pzlr.Value == nil || len(*pzlr.Value) == 0 -} - -// hasNextLink returns true if the NextLink is not empty. -func (pzlr PrivateZoneListResult) hasNextLink() bool { - return pzlr.NextLink != nil && len(*pzlr.NextLink) != 0 -} - -// privateZoneListResultPreparer prepares a request to retrieve the next set of results. -// It returns nil if no more results exist. -func (pzlr PrivateZoneListResult) privateZoneListResultPreparer(ctx context.Context) (*http.Request, error) { - if !pzlr.hasNextLink() { - return nil, nil - } - return autorest.Prepare((&http.Request{}).WithContext(ctx), - autorest.AsJSON(), - autorest.AsGet(), - autorest.WithBaseURL(to.String(pzlr.NextLink))) -} - -// PrivateZoneListResultPage contains a page of PrivateZone values. -type PrivateZoneListResultPage struct { - fn func(context.Context, PrivateZoneListResult) (PrivateZoneListResult, error) - pzlr PrivateZoneListResult -} - -// NextWithContext advances to the next page of values. If there was an error making -// the request the page does not advance and the error is returned. -func (page *PrivateZoneListResultPage) NextWithContext(ctx context.Context) (err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/PrivateZoneListResultPage.NextWithContext") - defer func() { - sc := -1 - if page.Response().Response.Response != nil { - sc = page.Response().Response.Response.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - for { - next, err := page.fn(ctx, page.pzlr) - if err != nil { - return err - } - page.pzlr = next - if !next.hasNextLink() || !next.IsEmpty() { - break - } - } - return nil -} - -// Next advances to the next page of values. If there was an error making -// the request the page does not advance and the error is returned. -// Deprecated: Use NextWithContext() instead. -func (page *PrivateZoneListResultPage) Next() error { - return page.NextWithContext(context.Background()) -} - -// NotDone returns true if the page enumeration should be started or is not yet complete. -func (page PrivateZoneListResultPage) NotDone() bool { - return !page.pzlr.IsEmpty() -} - -// Response returns the raw server response from the last page request. -func (page PrivateZoneListResultPage) Response() PrivateZoneListResult { - return page.pzlr -} - -// Values returns the slice of values for the current page or nil if there are no values. -func (page PrivateZoneListResultPage) Values() []PrivateZone { - if page.pzlr.IsEmpty() { - return nil - } - return *page.pzlr.Value -} - -// Creates a new instance of the PrivateZoneListResultPage type. -func NewPrivateZoneListResultPage(cur PrivateZoneListResult, getNextPage func(context.Context, PrivateZoneListResult) (PrivateZoneListResult, error)) PrivateZoneListResultPage { - return PrivateZoneListResultPage{ - fn: getNextPage, - pzlr: cur, - } -} - -// PrivateZoneProperties represents the properties of the Private DNS zone. -type PrivateZoneProperties struct { - // MaxNumberOfRecordSets - READ-ONLY; The maximum number of record sets that can be created in this Private DNS zone. This is a read-only property and any attempt to set this value will be ignored. - MaxNumberOfRecordSets *int64 `json:"maxNumberOfRecordSets,omitempty"` - // NumberOfRecordSets - READ-ONLY; The current number of record sets in this Private DNS zone. This is a read-only property and any attempt to set this value will be ignored. - NumberOfRecordSets *int64 `json:"numberOfRecordSets,omitempty"` - // MaxNumberOfVirtualNetworkLinks - READ-ONLY; The maximum number of virtual networks that can be linked to this Private DNS zone. This is a read-only property and any attempt to set this value will be ignored. - MaxNumberOfVirtualNetworkLinks *int64 `json:"maxNumberOfVirtualNetworkLinks,omitempty"` - // NumberOfVirtualNetworkLinks - READ-ONLY; The current number of virtual networks that are linked to this Private DNS zone. This is a read-only property and any attempt to set this value will be ignored. - NumberOfVirtualNetworkLinks *int64 `json:"numberOfVirtualNetworkLinks,omitempty"` - // MaxNumberOfVirtualNetworkLinksWithRegistration - READ-ONLY; The maximum number of virtual networks that can be linked to this Private DNS zone with registration enabled. This is a read-only property and any attempt to set this value will be ignored. - MaxNumberOfVirtualNetworkLinksWithRegistration *int64 `json:"maxNumberOfVirtualNetworkLinksWithRegistration,omitempty"` - // NumberOfVirtualNetworkLinksWithRegistration - READ-ONLY; The current number of virtual networks that are linked to this Private DNS zone with registration enabled. This is a read-only property and any attempt to set this value will be ignored. - NumberOfVirtualNetworkLinksWithRegistration *int64 `json:"numberOfVirtualNetworkLinksWithRegistration,omitempty"` - // ProvisioningState - READ-ONLY; The provisioning state of the resource. This is a read-only property and any attempt to set this value will be ignored. Possible values include: 'Creating', 'Updating', 'Deleting', 'Succeeded', 'Failed', 'Canceled' - ProvisioningState ProvisioningState `json:"provisioningState,omitempty"` - // InternalID - READ-ONLY; Private zone internal Id - InternalID *string `json:"internalId,omitempty"` -} - -// MarshalJSON is the custom marshaler for PrivateZoneProperties. -func (pzp PrivateZoneProperties) MarshalJSON() ([]byte, error) { - objectMap := make(map[string]interface{}) - return json.Marshal(objectMap) -} - -// PrivateZonesCreateOrUpdateFuture an abstraction for monitoring and retrieving the results of a -// long-running operation. -type PrivateZonesCreateOrUpdateFuture struct { - azure.FutureAPI - // Result returns the result of the asynchronous operation. - // If the operation has not completed it will return an error. - Result func(PrivateZonesClient) (PrivateZone, error) -} - -// UnmarshalJSON is the custom unmarshaller for CreateFuture. -func (future *PrivateZonesCreateOrUpdateFuture) UnmarshalJSON(body []byte) error { - var azFuture azure.Future - if err := json.Unmarshal(body, &azFuture); err != nil { - return err - } - future.FutureAPI = &azFuture - future.Result = future.result - return nil -} - -// result is the default implementation for PrivateZonesCreateOrUpdateFuture.Result. -func (future *PrivateZonesCreateOrUpdateFuture) result(client PrivateZonesClient) (pz PrivateZone, err error) { - var done bool - done, err = future.DoneWithContext(context.Background(), client) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.PrivateZonesCreateOrUpdateFuture", "Result", future.Response(), "Polling failure") - return - } - if !done { - pz.Response.Response = future.Response() - err = azure.NewAsyncOpIncompleteError("privatedns.PrivateZonesCreateOrUpdateFuture") - return - } - sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if pz.Response.Response, err = future.GetResult(sender); err == nil && pz.Response.Response.StatusCode != http.StatusNoContent { - pz, err = client.CreateOrUpdateResponder(pz.Response.Response) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.PrivateZonesCreateOrUpdateFuture", "Result", pz.Response.Response, "Failure responding to request") - } - } - return -} - -// PrivateZonesDeleteFuture an abstraction for monitoring and retrieving the results of a long-running -// operation. -type PrivateZonesDeleteFuture struct { - azure.FutureAPI - // Result returns the result of the asynchronous operation. - // If the operation has not completed it will return an error. - Result func(PrivateZonesClient) (autorest.Response, error) -} - -// UnmarshalJSON is the custom unmarshaller for CreateFuture. -func (future *PrivateZonesDeleteFuture) UnmarshalJSON(body []byte) error { - var azFuture azure.Future - if err := json.Unmarshal(body, &azFuture); err != nil { - return err - } - future.FutureAPI = &azFuture - future.Result = future.result - return nil -} - -// result is the default implementation for PrivateZonesDeleteFuture.Result. -func (future *PrivateZonesDeleteFuture) result(client PrivateZonesClient) (ar autorest.Response, err error) { - var done bool - done, err = future.DoneWithContext(context.Background(), client) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.PrivateZonesDeleteFuture", "Result", future.Response(), "Polling failure") - return - } - if !done { - ar.Response = future.Response() - err = azure.NewAsyncOpIncompleteError("privatedns.PrivateZonesDeleteFuture") - return - } - ar.Response = future.Response() - return -} - -// PrivateZonesUpdateFuture an abstraction for monitoring and retrieving the results of a long-running -// operation. -type PrivateZonesUpdateFuture struct { - azure.FutureAPI - // Result returns the result of the asynchronous operation. - // If the operation has not completed it will return an error. - Result func(PrivateZonesClient) (PrivateZone, error) -} - -// UnmarshalJSON is the custom unmarshaller for CreateFuture. -func (future *PrivateZonesUpdateFuture) UnmarshalJSON(body []byte) error { - var azFuture azure.Future - if err := json.Unmarshal(body, &azFuture); err != nil { - return err - } - future.FutureAPI = &azFuture - future.Result = future.result - return nil -} - -// result is the default implementation for PrivateZonesUpdateFuture.Result. -func (future *PrivateZonesUpdateFuture) result(client PrivateZonesClient) (pz PrivateZone, err error) { - var done bool - done, err = future.DoneWithContext(context.Background(), client) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.PrivateZonesUpdateFuture", "Result", future.Response(), "Polling failure") - return - } - if !done { - pz.Response.Response = future.Response() - err = azure.NewAsyncOpIncompleteError("privatedns.PrivateZonesUpdateFuture") - return - } - sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if pz.Response.Response, err = future.GetResult(sender); err == nil && pz.Response.Response.StatusCode != http.StatusNoContent { - pz, err = client.UpdateResponder(pz.Response.Response) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.PrivateZonesUpdateFuture", "Result", pz.Response.Response, "Failure responding to request") - } - } - return -} - -// ProxyResource the resource model definition for an ARM proxy resource. -type ProxyResource struct { - // ID - READ-ONLY; Fully qualified resource Id for the resource. Example - '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/privateDnsZones/{privateDnsZoneName}'. - ID *string `json:"id,omitempty"` - // Name - READ-ONLY; The name of the resource - Name *string `json:"name,omitempty"` - // Type - READ-ONLY; The type of the resource. Example - 'Microsoft.Network/privateDnsZones'. - Type *string `json:"type,omitempty"` -} - -// MarshalJSON is the custom marshaler for ProxyResource. -func (pr ProxyResource) MarshalJSON() ([]byte, error) { - objectMap := make(map[string]interface{}) - return json.Marshal(objectMap) -} - -// PtrRecord a PTR record. -type PtrRecord struct { - // Ptrdname - The PTR target domain name for this PTR record. - Ptrdname *string `json:"ptrdname,omitempty"` -} - -// RecordSet describes a DNS record set (a collection of DNS records with the same name and type) in a -// Private DNS zone. -type RecordSet struct { - autorest.Response `json:"-"` - // Etag - The ETag of the record set. - Etag *string `json:"etag,omitempty"` - // RecordSetProperties - The properties of the record set. - *RecordSetProperties `json:"properties,omitempty"` - // ID - READ-ONLY; Fully qualified resource Id for the resource. Example - '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/privateDnsZones/{privateDnsZoneName}'. - ID *string `json:"id,omitempty"` - // Name - READ-ONLY; The name of the resource - Name *string `json:"name,omitempty"` - // Type - READ-ONLY; The type of the resource. Example - 'Microsoft.Network/privateDnsZones'. - Type *string `json:"type,omitempty"` -} - -// MarshalJSON is the custom marshaler for RecordSet. -func (rs RecordSet) MarshalJSON() ([]byte, error) { - objectMap := make(map[string]interface{}) - if rs.Etag != nil { - objectMap["etag"] = rs.Etag - } - if rs.RecordSetProperties != nil { - objectMap["properties"] = rs.RecordSetProperties - } - return json.Marshal(objectMap) -} - -// UnmarshalJSON is the custom unmarshaler for RecordSet struct. -func (rs *RecordSet) UnmarshalJSON(body []byte) error { - var m map[string]*json.RawMessage - err := json.Unmarshal(body, &m) - if err != nil { - return err - } - for k, v := range m { - switch k { - case "etag": - if v != nil { - var etag string - err = json.Unmarshal(*v, &etag) - if err != nil { - return err - } - rs.Etag = &etag - } - case "properties": - if v != nil { - var recordSetProperties RecordSetProperties - err = json.Unmarshal(*v, &recordSetProperties) - if err != nil { - return err - } - rs.RecordSetProperties = &recordSetProperties - } - case "id": - if v != nil { - var ID string - err = json.Unmarshal(*v, &ID) - if err != nil { - return err - } - rs.ID = &ID - } - case "name": - if v != nil { - var name string - err = json.Unmarshal(*v, &name) - if err != nil { - return err - } - rs.Name = &name - } - case "type": - if v != nil { - var typeVar string - err = json.Unmarshal(*v, &typeVar) - if err != nil { - return err - } - rs.Type = &typeVar - } - } - } - - return nil -} - -// RecordSetListResult the response to a record set list operation. -type RecordSetListResult struct { - autorest.Response `json:"-"` - // Value - Information about the record sets in the response. - Value *[]RecordSet `json:"value,omitempty"` - // NextLink - READ-ONLY; The continuation token for the next page of results. - NextLink *string `json:"nextLink,omitempty"` -} - -// MarshalJSON is the custom marshaler for RecordSetListResult. -func (rslr RecordSetListResult) MarshalJSON() ([]byte, error) { - objectMap := make(map[string]interface{}) - if rslr.Value != nil { - objectMap["value"] = rslr.Value - } - return json.Marshal(objectMap) -} - -// RecordSetListResultIterator provides access to a complete listing of RecordSet values. -type RecordSetListResultIterator struct { - i int - page RecordSetListResultPage -} - -// NextWithContext advances to the next value. If there was an error making -// the request the iterator does not advance and the error is returned. -func (iter *RecordSetListResultIterator) NextWithContext(ctx context.Context) (err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/RecordSetListResultIterator.NextWithContext") - defer func() { - sc := -1 - if iter.Response().Response.Response != nil { - sc = iter.Response().Response.Response.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - iter.i++ - if iter.i < len(iter.page.Values()) { - return nil - } - err = iter.page.NextWithContext(ctx) - if err != nil { - iter.i-- - return err - } - iter.i = 0 - return nil -} - -// Next advances to the next value. If there was an error making -// the request the iterator does not advance and the error is returned. -// Deprecated: Use NextWithContext() instead. -func (iter *RecordSetListResultIterator) Next() error { - return iter.NextWithContext(context.Background()) -} - -// NotDone returns true if the enumeration should be started or is not yet complete. -func (iter RecordSetListResultIterator) NotDone() bool { - return iter.page.NotDone() && iter.i < len(iter.page.Values()) -} - -// Response returns the raw server response from the last page request. -func (iter RecordSetListResultIterator) Response() RecordSetListResult { - return iter.page.Response() -} - -// Value returns the current value or a zero-initialized value if the -// iterator has advanced beyond the end of the collection. -func (iter RecordSetListResultIterator) Value() RecordSet { - if !iter.page.NotDone() { - return RecordSet{} - } - return iter.page.Values()[iter.i] -} - -// Creates a new instance of the RecordSetListResultIterator type. -func NewRecordSetListResultIterator(page RecordSetListResultPage) RecordSetListResultIterator { - return RecordSetListResultIterator{page: page} -} - -// IsEmpty returns true if the ListResult contains no values. -func (rslr RecordSetListResult) IsEmpty() bool { - return rslr.Value == nil || len(*rslr.Value) == 0 -} - -// hasNextLink returns true if the NextLink is not empty. -func (rslr RecordSetListResult) hasNextLink() bool { - return rslr.NextLink != nil && len(*rslr.NextLink) != 0 -} - -// recordSetListResultPreparer prepares a request to retrieve the next set of results. -// It returns nil if no more results exist. -func (rslr RecordSetListResult) recordSetListResultPreparer(ctx context.Context) (*http.Request, error) { - if !rslr.hasNextLink() { - return nil, nil - } - return autorest.Prepare((&http.Request{}).WithContext(ctx), - autorest.AsJSON(), - autorest.AsGet(), - autorest.WithBaseURL(to.String(rslr.NextLink))) -} - -// RecordSetListResultPage contains a page of RecordSet values. -type RecordSetListResultPage struct { - fn func(context.Context, RecordSetListResult) (RecordSetListResult, error) - rslr RecordSetListResult -} - -// NextWithContext advances to the next page of values. If there was an error making -// the request the page does not advance and the error is returned. -func (page *RecordSetListResultPage) NextWithContext(ctx context.Context) (err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/RecordSetListResultPage.NextWithContext") - defer func() { - sc := -1 - if page.Response().Response.Response != nil { - sc = page.Response().Response.Response.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - for { - next, err := page.fn(ctx, page.rslr) - if err != nil { - return err - } - page.rslr = next - if !next.hasNextLink() || !next.IsEmpty() { - break - } - } - return nil -} - -// Next advances to the next page of values. If there was an error making -// the request the page does not advance and the error is returned. -// Deprecated: Use NextWithContext() instead. -func (page *RecordSetListResultPage) Next() error { - return page.NextWithContext(context.Background()) -} - -// NotDone returns true if the page enumeration should be started or is not yet complete. -func (page RecordSetListResultPage) NotDone() bool { - return !page.rslr.IsEmpty() -} - -// Response returns the raw server response from the last page request. -func (page RecordSetListResultPage) Response() RecordSetListResult { - return page.rslr -} - -// Values returns the slice of values for the current page or nil if there are no values. -func (page RecordSetListResultPage) Values() []RecordSet { - if page.rslr.IsEmpty() { - return nil - } - return *page.rslr.Value -} - -// Creates a new instance of the RecordSetListResultPage type. -func NewRecordSetListResultPage(cur RecordSetListResult, getNextPage func(context.Context, RecordSetListResult) (RecordSetListResult, error)) RecordSetListResultPage { - return RecordSetListResultPage{ - fn: getNextPage, - rslr: cur, - } -} - -// RecordSetProperties represents the properties of the records in the record set. -type RecordSetProperties struct { - // Metadata - The metadata attached to the record set. - Metadata map[string]*string `json:"metadata"` - // TTL - The TTL (time-to-live) of the records in the record set. - TTL *int64 `json:"ttl,omitempty"` - // Fqdn - READ-ONLY; Fully qualified domain name of the record set. - Fqdn *string `json:"fqdn,omitempty"` - // IsAutoRegistered - READ-ONLY; Is the record set auto-registered in the Private DNS zone through a virtual network link? - IsAutoRegistered *bool `json:"isAutoRegistered,omitempty"` - // ARecords - The list of A records in the record set. - ARecords *[]ARecord `json:"aRecords,omitempty"` - // AaaaRecords - The list of AAAA records in the record set. - AaaaRecords *[]AaaaRecord `json:"aaaaRecords,omitempty"` - // CnameRecord - The CNAME record in the record set. - CnameRecord *CnameRecord `json:"cnameRecord,omitempty"` - // MxRecords - The list of MX records in the record set. - MxRecords *[]MxRecord `json:"mxRecords,omitempty"` - // PtrRecords - The list of PTR records in the record set. - PtrRecords *[]PtrRecord `json:"ptrRecords,omitempty"` - // SoaRecord - The SOA record in the record set. - SoaRecord *SoaRecord `json:"soaRecord,omitempty"` - // SrvRecords - The list of SRV records in the record set. - SrvRecords *[]SrvRecord `json:"srvRecords,omitempty"` - // TxtRecords - The list of TXT records in the record set. - TxtRecords *[]TxtRecord `json:"txtRecords,omitempty"` -} - -// MarshalJSON is the custom marshaler for RecordSetProperties. -func (rsp RecordSetProperties) MarshalJSON() ([]byte, error) { - objectMap := make(map[string]interface{}) - if rsp.Metadata != nil { - objectMap["metadata"] = rsp.Metadata - } - if rsp.TTL != nil { - objectMap["ttl"] = rsp.TTL - } - if rsp.ARecords != nil { - objectMap["aRecords"] = rsp.ARecords - } - if rsp.AaaaRecords != nil { - objectMap["aaaaRecords"] = rsp.AaaaRecords - } - if rsp.CnameRecord != nil { - objectMap["cnameRecord"] = rsp.CnameRecord - } - if rsp.MxRecords != nil { - objectMap["mxRecords"] = rsp.MxRecords - } - if rsp.PtrRecords != nil { - objectMap["ptrRecords"] = rsp.PtrRecords - } - if rsp.SoaRecord != nil { - objectMap["soaRecord"] = rsp.SoaRecord - } - if rsp.SrvRecords != nil { - objectMap["srvRecords"] = rsp.SrvRecords - } - if rsp.TxtRecords != nil { - objectMap["txtRecords"] = rsp.TxtRecords - } - return json.Marshal(objectMap) -} - -// Resource the core properties of ARM resources -type Resource struct { - // ID - READ-ONLY; Fully qualified resource Id for the resource. Example - '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/privateDnsZones/{privateDnsZoneName}'. - ID *string `json:"id,omitempty"` - // Name - READ-ONLY; The name of the resource - Name *string `json:"name,omitempty"` - // Type - READ-ONLY; The type of the resource. Example - 'Microsoft.Network/privateDnsZones'. - Type *string `json:"type,omitempty"` -} - -// MarshalJSON is the custom marshaler for Resource. -func (r Resource) MarshalJSON() ([]byte, error) { - objectMap := make(map[string]interface{}) - return json.Marshal(objectMap) -} - -// SoaRecord an SOA record. -type SoaRecord struct { - // Host - The domain name of the authoritative name server for this SOA record. - Host *string `json:"host,omitempty"` - // Email - The email contact for this SOA record. - Email *string `json:"email,omitempty"` - // SerialNumber - The serial number for this SOA record. - SerialNumber *int64 `json:"serialNumber,omitempty"` - // RefreshTime - The refresh value for this SOA record. - RefreshTime *int64 `json:"refreshTime,omitempty"` - // RetryTime - The retry time for this SOA record. - RetryTime *int64 `json:"retryTime,omitempty"` - // ExpireTime - The expire time for this SOA record. - ExpireTime *int64 `json:"expireTime,omitempty"` - // MinimumTTL - The minimum value for this SOA record. By convention this is used to determine the negative caching duration. - MinimumTTL *int64 `json:"minimumTtl,omitempty"` -} - -// SrvRecord an SRV record. -type SrvRecord struct { - // Priority - The priority value for this SRV record. - Priority *int32 `json:"priority,omitempty"` - // Weight - The weight value for this SRV record. - Weight *int32 `json:"weight,omitempty"` - // Port - The port value for this SRV record. - Port *int32 `json:"port,omitempty"` - // Target - The target domain name for this SRV record. - Target *string `json:"target,omitempty"` -} - -// SubResource reference to another subresource. -type SubResource struct { - // ID - Resource ID. - ID *string `json:"id,omitempty"` -} - -// TrackedResource the resource model definition for a ARM tracked top level resource -type TrackedResource struct { - // Tags - Resource tags. - Tags map[string]*string `json:"tags"` - // Location - The Azure Region where the resource lives - Location *string `json:"location,omitempty"` - // ID - READ-ONLY; Fully qualified resource Id for the resource. Example - '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/privateDnsZones/{privateDnsZoneName}'. - ID *string `json:"id,omitempty"` - // Name - READ-ONLY; The name of the resource - Name *string `json:"name,omitempty"` - // Type - READ-ONLY; The type of the resource. Example - 'Microsoft.Network/privateDnsZones'. - Type *string `json:"type,omitempty"` -} - -// MarshalJSON is the custom marshaler for TrackedResource. -func (tr TrackedResource) MarshalJSON() ([]byte, error) { - objectMap := make(map[string]interface{}) - if tr.Tags != nil { - objectMap["tags"] = tr.Tags - } - if tr.Location != nil { - objectMap["location"] = tr.Location - } - return json.Marshal(objectMap) -} - -// TxtRecord a TXT record. -type TxtRecord struct { - // Value - The text value of this TXT record. - Value *[]string `json:"value,omitempty"` -} - -// VirtualNetworkLink describes a link to virtual network for a Private DNS zone. -type VirtualNetworkLink struct { - autorest.Response `json:"-"` - // Etag - The ETag of the virtual network link. - Etag *string `json:"etag,omitempty"` - // VirtualNetworkLinkProperties - Properties of the virtual network link to the Private DNS zone. - *VirtualNetworkLinkProperties `json:"properties,omitempty"` - // Tags - Resource tags. - Tags map[string]*string `json:"tags"` - // Location - The Azure Region where the resource lives - Location *string `json:"location,omitempty"` - // ID - READ-ONLY; Fully qualified resource Id for the resource. Example - '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/privateDnsZones/{privateDnsZoneName}'. - ID *string `json:"id,omitempty"` - // Name - READ-ONLY; The name of the resource - Name *string `json:"name,omitempty"` - // Type - READ-ONLY; The type of the resource. Example - 'Microsoft.Network/privateDnsZones'. - Type *string `json:"type,omitempty"` -} - -// MarshalJSON is the custom marshaler for VirtualNetworkLink. -func (vnl VirtualNetworkLink) MarshalJSON() ([]byte, error) { - objectMap := make(map[string]interface{}) - if vnl.Etag != nil { - objectMap["etag"] = vnl.Etag - } - if vnl.VirtualNetworkLinkProperties != nil { - objectMap["properties"] = vnl.VirtualNetworkLinkProperties - } - if vnl.Tags != nil { - objectMap["tags"] = vnl.Tags - } - if vnl.Location != nil { - objectMap["location"] = vnl.Location - } - return json.Marshal(objectMap) -} - -// UnmarshalJSON is the custom unmarshaler for VirtualNetworkLink struct. -func (vnl *VirtualNetworkLink) UnmarshalJSON(body []byte) error { - var m map[string]*json.RawMessage - err := json.Unmarshal(body, &m) - if err != nil { - return err - } - for k, v := range m { - switch k { - case "etag": - if v != nil { - var etag string - err = json.Unmarshal(*v, &etag) - if err != nil { - return err - } - vnl.Etag = &etag - } - case "properties": - if v != nil { - var virtualNetworkLinkProperties VirtualNetworkLinkProperties - err = json.Unmarshal(*v, &virtualNetworkLinkProperties) - if err != nil { - return err - } - vnl.VirtualNetworkLinkProperties = &virtualNetworkLinkProperties - } - case "tags": - if v != nil { - var tags map[string]*string - err = json.Unmarshal(*v, &tags) - if err != nil { - return err - } - vnl.Tags = tags - } - case "location": - if v != nil { - var location string - err = json.Unmarshal(*v, &location) - if err != nil { - return err - } - vnl.Location = &location - } - case "id": - if v != nil { - var ID string - err = json.Unmarshal(*v, &ID) - if err != nil { - return err - } - vnl.ID = &ID - } - case "name": - if v != nil { - var name string - err = json.Unmarshal(*v, &name) - if err != nil { - return err - } - vnl.Name = &name - } - case "type": - if v != nil { - var typeVar string - err = json.Unmarshal(*v, &typeVar) - if err != nil { - return err - } - vnl.Type = &typeVar - } - } - } - - return nil -} - -// VirtualNetworkLinkListResult the response to a list virtual network link to Private DNS zone operation. -type VirtualNetworkLinkListResult struct { - autorest.Response `json:"-"` - // Value - Information about the virtual network links to the Private DNS zones. - Value *[]VirtualNetworkLink `json:"value,omitempty"` - // NextLink - READ-ONLY; The continuation token for the next page of results. - NextLink *string `json:"nextLink,omitempty"` -} - -// MarshalJSON is the custom marshaler for VirtualNetworkLinkListResult. -func (vnllr VirtualNetworkLinkListResult) MarshalJSON() ([]byte, error) { - objectMap := make(map[string]interface{}) - if vnllr.Value != nil { - objectMap["value"] = vnllr.Value - } - return json.Marshal(objectMap) -} - -// VirtualNetworkLinkListResultIterator provides access to a complete listing of VirtualNetworkLink values. -type VirtualNetworkLinkListResultIterator struct { - i int - page VirtualNetworkLinkListResultPage -} - -// NextWithContext advances to the next value. If there was an error making -// the request the iterator does not advance and the error is returned. -func (iter *VirtualNetworkLinkListResultIterator) NextWithContext(ctx context.Context) (err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/VirtualNetworkLinkListResultIterator.NextWithContext") - defer func() { - sc := -1 - if iter.Response().Response.Response != nil { - sc = iter.Response().Response.Response.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - iter.i++ - if iter.i < len(iter.page.Values()) { - return nil - } - err = iter.page.NextWithContext(ctx) - if err != nil { - iter.i-- - return err - } - iter.i = 0 - return nil -} - -// Next advances to the next value. If there was an error making -// the request the iterator does not advance and the error is returned. -// Deprecated: Use NextWithContext() instead. -func (iter *VirtualNetworkLinkListResultIterator) Next() error { - return iter.NextWithContext(context.Background()) -} - -// NotDone returns true if the enumeration should be started or is not yet complete. -func (iter VirtualNetworkLinkListResultIterator) NotDone() bool { - return iter.page.NotDone() && iter.i < len(iter.page.Values()) -} - -// Response returns the raw server response from the last page request. -func (iter VirtualNetworkLinkListResultIterator) Response() VirtualNetworkLinkListResult { - return iter.page.Response() -} - -// Value returns the current value or a zero-initialized value if the -// iterator has advanced beyond the end of the collection. -func (iter VirtualNetworkLinkListResultIterator) Value() VirtualNetworkLink { - if !iter.page.NotDone() { - return VirtualNetworkLink{} - } - return iter.page.Values()[iter.i] -} - -// Creates a new instance of the VirtualNetworkLinkListResultIterator type. -func NewVirtualNetworkLinkListResultIterator(page VirtualNetworkLinkListResultPage) VirtualNetworkLinkListResultIterator { - return VirtualNetworkLinkListResultIterator{page: page} -} - -// IsEmpty returns true if the ListResult contains no values. -func (vnllr VirtualNetworkLinkListResult) IsEmpty() bool { - return vnllr.Value == nil || len(*vnllr.Value) == 0 -} - -// hasNextLink returns true if the NextLink is not empty. -func (vnllr VirtualNetworkLinkListResult) hasNextLink() bool { - return vnllr.NextLink != nil && len(*vnllr.NextLink) != 0 -} - -// virtualNetworkLinkListResultPreparer prepares a request to retrieve the next set of results. -// It returns nil if no more results exist. -func (vnllr VirtualNetworkLinkListResult) virtualNetworkLinkListResultPreparer(ctx context.Context) (*http.Request, error) { - if !vnllr.hasNextLink() { - return nil, nil - } - return autorest.Prepare((&http.Request{}).WithContext(ctx), - autorest.AsJSON(), - autorest.AsGet(), - autorest.WithBaseURL(to.String(vnllr.NextLink))) -} - -// VirtualNetworkLinkListResultPage contains a page of VirtualNetworkLink values. -type VirtualNetworkLinkListResultPage struct { - fn func(context.Context, VirtualNetworkLinkListResult) (VirtualNetworkLinkListResult, error) - vnllr VirtualNetworkLinkListResult -} - -// NextWithContext advances to the next page of values. If there was an error making -// the request the page does not advance and the error is returned. -func (page *VirtualNetworkLinkListResultPage) NextWithContext(ctx context.Context) (err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/VirtualNetworkLinkListResultPage.NextWithContext") - defer func() { - sc := -1 - if page.Response().Response.Response != nil { - sc = page.Response().Response.Response.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - for { - next, err := page.fn(ctx, page.vnllr) - if err != nil { - return err - } - page.vnllr = next - if !next.hasNextLink() || !next.IsEmpty() { - break - } - } - return nil -} - -// Next advances to the next page of values. If there was an error making -// the request the page does not advance and the error is returned. -// Deprecated: Use NextWithContext() instead. -func (page *VirtualNetworkLinkListResultPage) Next() error { - return page.NextWithContext(context.Background()) -} - -// NotDone returns true if the page enumeration should be started or is not yet complete. -func (page VirtualNetworkLinkListResultPage) NotDone() bool { - return !page.vnllr.IsEmpty() -} - -// Response returns the raw server response from the last page request. -func (page VirtualNetworkLinkListResultPage) Response() VirtualNetworkLinkListResult { - return page.vnllr -} - -// Values returns the slice of values for the current page or nil if there are no values. -func (page VirtualNetworkLinkListResultPage) Values() []VirtualNetworkLink { - if page.vnllr.IsEmpty() { - return nil - } - return *page.vnllr.Value -} - -// Creates a new instance of the VirtualNetworkLinkListResultPage type. -func NewVirtualNetworkLinkListResultPage(cur VirtualNetworkLinkListResult, getNextPage func(context.Context, VirtualNetworkLinkListResult) (VirtualNetworkLinkListResult, error)) VirtualNetworkLinkListResultPage { - return VirtualNetworkLinkListResultPage{ - fn: getNextPage, - vnllr: cur, - } -} - -// VirtualNetworkLinkProperties represents the properties of the Private DNS zone. -type VirtualNetworkLinkProperties struct { - // VirtualNetwork - The reference of the virtual network. - VirtualNetwork *SubResource `json:"virtualNetwork,omitempty"` - // RegistrationEnabled - Is auto-registration of virtual machine records in the virtual network in the Private DNS zone enabled? - RegistrationEnabled *bool `json:"registrationEnabled,omitempty"` - // VirtualNetworkLinkState - READ-ONLY; The status of the virtual network link to the Private DNS zone. Possible values are 'InProgress' and 'Done'. This is a read-only property and any attempt to set this value will be ignored. Possible values include: 'InProgress', 'Completed' - VirtualNetworkLinkState VirtualNetworkLinkState `json:"virtualNetworkLinkState,omitempty"` - // ProvisioningState - READ-ONLY; The provisioning state of the resource. This is a read-only property and any attempt to set this value will be ignored. Possible values include: 'Creating', 'Updating', 'Deleting', 'Succeeded', 'Failed', 'Canceled' - ProvisioningState ProvisioningState `json:"provisioningState,omitempty"` -} - -// MarshalJSON is the custom marshaler for VirtualNetworkLinkProperties. -func (vnlp VirtualNetworkLinkProperties) MarshalJSON() ([]byte, error) { - objectMap := make(map[string]interface{}) - if vnlp.VirtualNetwork != nil { - objectMap["virtualNetwork"] = vnlp.VirtualNetwork - } - if vnlp.RegistrationEnabled != nil { - objectMap["registrationEnabled"] = vnlp.RegistrationEnabled - } - return json.Marshal(objectMap) -} - -// VirtualNetworkLinksCreateOrUpdateFuture an abstraction for monitoring and retrieving the results of a -// long-running operation. -type VirtualNetworkLinksCreateOrUpdateFuture struct { - azure.FutureAPI - // Result returns the result of the asynchronous operation. - // If the operation has not completed it will return an error. - Result func(VirtualNetworkLinksClient) (VirtualNetworkLink, error) -} - -// UnmarshalJSON is the custom unmarshaller for CreateFuture. -func (future *VirtualNetworkLinksCreateOrUpdateFuture) UnmarshalJSON(body []byte) error { - var azFuture azure.Future - if err := json.Unmarshal(body, &azFuture); err != nil { - return err - } - future.FutureAPI = &azFuture - future.Result = future.result - return nil -} - -// result is the default implementation for VirtualNetworkLinksCreateOrUpdateFuture.Result. -func (future *VirtualNetworkLinksCreateOrUpdateFuture) result(client VirtualNetworkLinksClient) (vnl VirtualNetworkLink, err error) { - var done bool - done, err = future.DoneWithContext(context.Background(), client) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.VirtualNetworkLinksCreateOrUpdateFuture", "Result", future.Response(), "Polling failure") - return - } - if !done { - vnl.Response.Response = future.Response() - err = azure.NewAsyncOpIncompleteError("privatedns.VirtualNetworkLinksCreateOrUpdateFuture") - return - } - sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if vnl.Response.Response, err = future.GetResult(sender); err == nil && vnl.Response.Response.StatusCode != http.StatusNoContent { - vnl, err = client.CreateOrUpdateResponder(vnl.Response.Response) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.VirtualNetworkLinksCreateOrUpdateFuture", "Result", vnl.Response.Response, "Failure responding to request") - } - } - return -} - -// VirtualNetworkLinksDeleteFuture an abstraction for monitoring and retrieving the results of a -// long-running operation. -type VirtualNetworkLinksDeleteFuture struct { - azure.FutureAPI - // Result returns the result of the asynchronous operation. - // If the operation has not completed it will return an error. - Result func(VirtualNetworkLinksClient) (autorest.Response, error) -} - -// UnmarshalJSON is the custom unmarshaller for CreateFuture. -func (future *VirtualNetworkLinksDeleteFuture) UnmarshalJSON(body []byte) error { - var azFuture azure.Future - if err := json.Unmarshal(body, &azFuture); err != nil { - return err - } - future.FutureAPI = &azFuture - future.Result = future.result - return nil -} - -// result is the default implementation for VirtualNetworkLinksDeleteFuture.Result. -func (future *VirtualNetworkLinksDeleteFuture) result(client VirtualNetworkLinksClient) (ar autorest.Response, err error) { - var done bool - done, err = future.DoneWithContext(context.Background(), client) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.VirtualNetworkLinksDeleteFuture", "Result", future.Response(), "Polling failure") - return - } - if !done { - ar.Response = future.Response() - err = azure.NewAsyncOpIncompleteError("privatedns.VirtualNetworkLinksDeleteFuture") - return - } - ar.Response = future.Response() - return -} - -// VirtualNetworkLinksUpdateFuture an abstraction for monitoring and retrieving the results of a -// long-running operation. -type VirtualNetworkLinksUpdateFuture struct { - azure.FutureAPI - // Result returns the result of the asynchronous operation. - // If the operation has not completed it will return an error. - Result func(VirtualNetworkLinksClient) (VirtualNetworkLink, error) -} - -// UnmarshalJSON is the custom unmarshaller for CreateFuture. -func (future *VirtualNetworkLinksUpdateFuture) UnmarshalJSON(body []byte) error { - var azFuture azure.Future - if err := json.Unmarshal(body, &azFuture); err != nil { - return err - } - future.FutureAPI = &azFuture - future.Result = future.result - return nil -} - -// result is the default implementation for VirtualNetworkLinksUpdateFuture.Result. -func (future *VirtualNetworkLinksUpdateFuture) result(client VirtualNetworkLinksClient) (vnl VirtualNetworkLink, err error) { - var done bool - done, err = future.DoneWithContext(context.Background(), client) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.VirtualNetworkLinksUpdateFuture", "Result", future.Response(), "Polling failure") - return - } - if !done { - vnl.Response.Response = future.Response() - err = azure.NewAsyncOpIncompleteError("privatedns.VirtualNetworkLinksUpdateFuture") - return - } - sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) - if vnl.Response.Response, err = future.GetResult(sender); err == nil && vnl.Response.Response.StatusCode != http.StatusNoContent { - vnl, err = client.UpdateResponder(vnl.Response.Response) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.VirtualNetworkLinksUpdateFuture", "Result", vnl.Response.Response, "Failure responding to request") - } - } - return -} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2020-06-01/privatedns/privatezones.go b/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2020-06-01/privatedns/privatezones.go deleted file mode 100644 index 86960335..00000000 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2020-06-01/privatedns/privatezones.go +++ /dev/null @@ -1,614 +0,0 @@ -package privatedns - -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See License.txt in the project root for license information. -// -// Code generated by Microsoft (R) AutoRest Code Generator. -// Changes may cause incorrect behavior and will be lost if the code is regenerated. - -import ( - "context" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/tracing" - "net/http" -) - -// PrivateZonesClient is the the Private DNS Management Client. -type PrivateZonesClient struct { - BaseClient -} - -// NewPrivateZonesClient creates an instance of the PrivateZonesClient client. -func NewPrivateZonesClient(subscriptionID string) PrivateZonesClient { - return NewPrivateZonesClientWithBaseURI(DefaultBaseURI, subscriptionID) -} - -// NewPrivateZonesClientWithBaseURI creates an instance of the PrivateZonesClient client using a custom endpoint. Use -// this when interacting with an Azure cloud that uses a non-standard base URI (sovereign clouds, Azure stack). -func NewPrivateZonesClientWithBaseURI(baseURI string, subscriptionID string) PrivateZonesClient { - return PrivateZonesClient{NewWithBaseURI(baseURI, subscriptionID)} -} - -// CreateOrUpdate creates or updates a Private DNS zone. Does not modify Links to virtual networks or DNS records -// within the zone. -// Parameters: -// resourceGroupName - the name of the resource group. -// privateZoneName - the name of the Private DNS zone (without a terminating dot). -// parameters - parameters supplied to the CreateOrUpdate operation. -// ifMatch - the ETag of the Private DNS zone. Omit this value to always overwrite the current zone. Specify -// the last-seen ETag value to prevent accidentally overwriting any concurrent changes. -// ifNoneMatch - set to '*' to allow a new Private DNS zone to be created, but to prevent updating an existing -// zone. Other values will be ignored. -func (client PrivateZonesClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, privateZoneName string, parameters PrivateZone, ifMatch string, ifNoneMatch string) (result PrivateZonesCreateOrUpdateFuture, err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/PrivateZonesClient.CreateOrUpdate") - defer func() { - sc := -1 - if result.FutureAPI != nil && result.FutureAPI.Response() != nil { - sc = result.FutureAPI.Response().StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - req, err := client.CreateOrUpdatePreparer(ctx, resourceGroupName, privateZoneName, parameters, ifMatch, ifNoneMatch) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.PrivateZonesClient", "CreateOrUpdate", nil, "Failure preparing request") - return - } - - result, err = client.CreateOrUpdateSender(req) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.PrivateZonesClient", "CreateOrUpdate", result.Response(), "Failure sending request") - return - } - - return -} - -// CreateOrUpdatePreparer prepares the CreateOrUpdate request. -func (client PrivateZonesClient) CreateOrUpdatePreparer(ctx context.Context, resourceGroupName string, privateZoneName string, parameters PrivateZone, ifMatch string, ifNoneMatch string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "privateZoneName": autorest.Encode("path", privateZoneName), - "resourceGroupName": autorest.Encode("path", resourceGroupName), - "subscriptionId": autorest.Encode("path", client.SubscriptionID), - } - - const APIVersion = "2020-06-01" - queryParameters := map[string]interface{}{ - "api-version": APIVersion, - } - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/json; charset=utf-8"), - autorest.AsPut(), - autorest.WithBaseURL(client.BaseURI), - autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/privateDnsZones/{privateZoneName}", pathParameters), - autorest.WithJSON(parameters), - autorest.WithQueryParameters(queryParameters)) - if len(ifMatch) > 0 { - preparer = autorest.DecoratePreparer(preparer, - autorest.WithHeader("If-Match", autorest.String(ifMatch))) - } - if len(ifNoneMatch) > 0 { - preparer = autorest.DecoratePreparer(preparer, - autorest.WithHeader("If-None-Match", autorest.String(ifNoneMatch))) - } - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the -// http.Response Body if it receives an error. -func (client PrivateZonesClient) CreateOrUpdateSender(req *http.Request) (future PrivateZonesCreateOrUpdateFuture, err error) { - var resp *http.Response - future.FutureAPI = &azure.Future{} - resp, err = client.Send(req, azure.DoRetryWithRegistration(client.Client)) - if err != nil { - return - } - var azf azure.Future - azf, err = azure.NewFutureFromResponse(resp) - future.FutureAPI = &azf - future.Result = future.result - return -} - -// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always -// closes the http.Response Body. -func (client PrivateZonesClient) CreateOrUpdateResponder(resp *http.Response) (result PrivateZone, err error) { - err = autorest.Respond( - resp, - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated, http.StatusAccepted), - autorest.ByUnmarshallingJSON(&result), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - return -} - -// Delete deletes a Private DNS zone. WARNING: All DNS records in the zone will also be deleted. This operation cannot -// be undone. Private DNS zone cannot be deleted unless all virtual network links to it are removed. -// Parameters: -// resourceGroupName - the name of the resource group. -// privateZoneName - the name of the Private DNS zone (without a terminating dot). -// ifMatch - the ETag of the Private DNS zone. Omit this value to always delete the current zone. Specify the -// last-seen ETag value to prevent accidentally deleting any concurrent changes. -func (client PrivateZonesClient) Delete(ctx context.Context, resourceGroupName string, privateZoneName string, ifMatch string) (result PrivateZonesDeleteFuture, err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/PrivateZonesClient.Delete") - defer func() { - sc := -1 - if result.FutureAPI != nil && result.FutureAPI.Response() != nil { - sc = result.FutureAPI.Response().StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - req, err := client.DeletePreparer(ctx, resourceGroupName, privateZoneName, ifMatch) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.PrivateZonesClient", "Delete", nil, "Failure preparing request") - return - } - - result, err = client.DeleteSender(req) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.PrivateZonesClient", "Delete", result.Response(), "Failure sending request") - return - } - - return -} - -// DeletePreparer prepares the Delete request. -func (client PrivateZonesClient) DeletePreparer(ctx context.Context, resourceGroupName string, privateZoneName string, ifMatch string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "privateZoneName": autorest.Encode("path", privateZoneName), - "resourceGroupName": autorest.Encode("path", resourceGroupName), - "subscriptionId": autorest.Encode("path", client.SubscriptionID), - } - - const APIVersion = "2020-06-01" - queryParameters := map[string]interface{}{ - "api-version": APIVersion, - } - - preparer := autorest.CreatePreparer( - autorest.AsDelete(), - autorest.WithBaseURL(client.BaseURI), - autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/privateDnsZones/{privateZoneName}", pathParameters), - autorest.WithQueryParameters(queryParameters)) - if len(ifMatch) > 0 { - preparer = autorest.DecoratePreparer(preparer, - autorest.WithHeader("If-Match", autorest.String(ifMatch))) - } - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// DeleteSender sends the Delete request. The method will close the -// http.Response Body if it receives an error. -func (client PrivateZonesClient) DeleteSender(req *http.Request) (future PrivateZonesDeleteFuture, err error) { - var resp *http.Response - future.FutureAPI = &azure.Future{} - resp, err = client.Send(req, azure.DoRetryWithRegistration(client.Client)) - if err != nil { - return - } - var azf azure.Future - azf, err = azure.NewFutureFromResponse(resp) - future.FutureAPI = &azf - future.Result = future.result - return -} - -// DeleteResponder handles the response to the Delete request. The method always -// closes the http.Response Body. -func (client PrivateZonesClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent), - autorest.ByClosing()) - result.Response = resp - return -} - -// Get gets a Private DNS zone. Retrieves the zone properties, but not the virtual networks links or the record sets -// within the zone. -// Parameters: -// resourceGroupName - the name of the resource group. -// privateZoneName - the name of the Private DNS zone (without a terminating dot). -func (client PrivateZonesClient) Get(ctx context.Context, resourceGroupName string, privateZoneName string) (result PrivateZone, err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/PrivateZonesClient.Get") - defer func() { - sc := -1 - if result.Response.Response != nil { - sc = result.Response.Response.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - req, err := client.GetPreparer(ctx, resourceGroupName, privateZoneName) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.PrivateZonesClient", "Get", nil, "Failure preparing request") - return - } - - resp, err := client.GetSender(req) - if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "privatedns.PrivateZonesClient", "Get", resp, "Failure sending request") - return - } - - result, err = client.GetResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.PrivateZonesClient", "Get", resp, "Failure responding to request") - return - } - - return -} - -// GetPreparer prepares the Get request. -func (client PrivateZonesClient) GetPreparer(ctx context.Context, resourceGroupName string, privateZoneName string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "privateZoneName": autorest.Encode("path", privateZoneName), - "resourceGroupName": autorest.Encode("path", resourceGroupName), - "subscriptionId": autorest.Encode("path", client.SubscriptionID), - } - - const APIVersion = "2020-06-01" - queryParameters := map[string]interface{}{ - "api-version": APIVersion, - } - - preparer := autorest.CreatePreparer( - autorest.AsGet(), - autorest.WithBaseURL(client.BaseURI), - autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/privateDnsZones/{privateZoneName}", pathParameters), - autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// GetSender sends the Get request. The method will close the -// http.Response Body if it receives an error. -func (client PrivateZonesClient) GetSender(req *http.Request) (*http.Response, error) { - return client.Send(req, azure.DoRetryWithRegistration(client.Client)) -} - -// GetResponder handles the response to the Get request. The method always -// closes the http.Response Body. -func (client PrivateZonesClient) GetResponder(resp *http.Response) (result PrivateZone, err error) { - err = autorest.Respond( - resp, - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByUnmarshallingJSON(&result), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - return -} - -// List lists the Private DNS zones in all resource groups in a subscription. -// Parameters: -// top - the maximum number of Private DNS zones to return. If not specified, returns up to 100 zones. -func (client PrivateZonesClient) List(ctx context.Context, top *int32) (result PrivateZoneListResultPage, err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/PrivateZonesClient.List") - defer func() { - sc := -1 - if result.pzlr.Response.Response != nil { - sc = result.pzlr.Response.Response.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - result.fn = client.listNextResults - req, err := client.ListPreparer(ctx, top) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.PrivateZonesClient", "List", nil, "Failure preparing request") - return - } - - resp, err := client.ListSender(req) - if err != nil { - result.pzlr.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "privatedns.PrivateZonesClient", "List", resp, "Failure sending request") - return - } - - result.pzlr, err = client.ListResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.PrivateZonesClient", "List", resp, "Failure responding to request") - return - } - if result.pzlr.hasNextLink() && result.pzlr.IsEmpty() { - err = result.NextWithContext(ctx) - return - } - - return -} - -// ListPreparer prepares the List request. -func (client PrivateZonesClient) ListPreparer(ctx context.Context, top *int32) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "subscriptionId": autorest.Encode("path", client.SubscriptionID), - } - - const APIVersion = "2020-06-01" - queryParameters := map[string]interface{}{ - "api-version": APIVersion, - } - if top != nil { - queryParameters["$top"] = autorest.Encode("query", *top) - } - - preparer := autorest.CreatePreparer( - autorest.AsGet(), - autorest.WithBaseURL(client.BaseURI), - autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Network/privateDnsZones", pathParameters), - autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// ListSender sends the List request. The method will close the -// http.Response Body if it receives an error. -func (client PrivateZonesClient) ListSender(req *http.Request) (*http.Response, error) { - return client.Send(req, azure.DoRetryWithRegistration(client.Client)) -} - -// ListResponder handles the response to the List request. The method always -// closes the http.Response Body. -func (client PrivateZonesClient) ListResponder(resp *http.Response) (result PrivateZoneListResult, err error) { - err = autorest.Respond( - resp, - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByUnmarshallingJSON(&result), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - return -} - -// listNextResults retrieves the next set of results, if any. -func (client PrivateZonesClient) listNextResults(ctx context.Context, lastResults PrivateZoneListResult) (result PrivateZoneListResult, err error) { - req, err := lastResults.privateZoneListResultPreparer(ctx) - if err != nil { - return result, autorest.NewErrorWithError(err, "privatedns.PrivateZonesClient", "listNextResults", nil, "Failure preparing next results request") - } - if req == nil { - return - } - resp, err := client.ListSender(req) - if err != nil { - result.Response = autorest.Response{Response: resp} - return result, autorest.NewErrorWithError(err, "privatedns.PrivateZonesClient", "listNextResults", resp, "Failure sending next results request") - } - result, err = client.ListResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.PrivateZonesClient", "listNextResults", resp, "Failure responding to next results request") - } - return -} - -// ListComplete enumerates all values, automatically crossing page boundaries as required. -func (client PrivateZonesClient) ListComplete(ctx context.Context, top *int32) (result PrivateZoneListResultIterator, err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/PrivateZonesClient.List") - defer func() { - sc := -1 - if result.Response().Response.Response != nil { - sc = result.page.Response().Response.Response.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - result.page, err = client.List(ctx, top) - return -} - -// ListByResourceGroup lists the Private DNS zones within a resource group. -// Parameters: -// resourceGroupName - the name of the resource group. -// top - the maximum number of record sets to return. If not specified, returns up to 100 record sets. -func (client PrivateZonesClient) ListByResourceGroup(ctx context.Context, resourceGroupName string, top *int32) (result PrivateZoneListResultPage, err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/PrivateZonesClient.ListByResourceGroup") - defer func() { - sc := -1 - if result.pzlr.Response.Response != nil { - sc = result.pzlr.Response.Response.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - result.fn = client.listByResourceGroupNextResults - req, err := client.ListByResourceGroupPreparer(ctx, resourceGroupName, top) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.PrivateZonesClient", "ListByResourceGroup", nil, "Failure preparing request") - return - } - - resp, err := client.ListByResourceGroupSender(req) - if err != nil { - result.pzlr.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "privatedns.PrivateZonesClient", "ListByResourceGroup", resp, "Failure sending request") - return - } - - result.pzlr, err = client.ListByResourceGroupResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.PrivateZonesClient", "ListByResourceGroup", resp, "Failure responding to request") - return - } - if result.pzlr.hasNextLink() && result.pzlr.IsEmpty() { - err = result.NextWithContext(ctx) - return - } - - return -} - -// ListByResourceGroupPreparer prepares the ListByResourceGroup request. -func (client PrivateZonesClient) ListByResourceGroupPreparer(ctx context.Context, resourceGroupName string, top *int32) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "resourceGroupName": autorest.Encode("path", resourceGroupName), - "subscriptionId": autorest.Encode("path", client.SubscriptionID), - } - - const APIVersion = "2020-06-01" - queryParameters := map[string]interface{}{ - "api-version": APIVersion, - } - if top != nil { - queryParameters["$top"] = autorest.Encode("query", *top) - } - - preparer := autorest.CreatePreparer( - autorest.AsGet(), - autorest.WithBaseURL(client.BaseURI), - autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/privateDnsZones", pathParameters), - autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// ListByResourceGroupSender sends the ListByResourceGroup request. The method will close the -// http.Response Body if it receives an error. -func (client PrivateZonesClient) ListByResourceGroupSender(req *http.Request) (*http.Response, error) { - return client.Send(req, azure.DoRetryWithRegistration(client.Client)) -} - -// ListByResourceGroupResponder handles the response to the ListByResourceGroup request. The method always -// closes the http.Response Body. -func (client PrivateZonesClient) ListByResourceGroupResponder(resp *http.Response) (result PrivateZoneListResult, err error) { - err = autorest.Respond( - resp, - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByUnmarshallingJSON(&result), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - return -} - -// listByResourceGroupNextResults retrieves the next set of results, if any. -func (client PrivateZonesClient) listByResourceGroupNextResults(ctx context.Context, lastResults PrivateZoneListResult) (result PrivateZoneListResult, err error) { - req, err := lastResults.privateZoneListResultPreparer(ctx) - if err != nil { - return result, autorest.NewErrorWithError(err, "privatedns.PrivateZonesClient", "listByResourceGroupNextResults", nil, "Failure preparing next results request") - } - if req == nil { - return - } - resp, err := client.ListByResourceGroupSender(req) - if err != nil { - result.Response = autorest.Response{Response: resp} - return result, autorest.NewErrorWithError(err, "privatedns.PrivateZonesClient", "listByResourceGroupNextResults", resp, "Failure sending next results request") - } - result, err = client.ListByResourceGroupResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.PrivateZonesClient", "listByResourceGroupNextResults", resp, "Failure responding to next results request") - } - return -} - -// ListByResourceGroupComplete enumerates all values, automatically crossing page boundaries as required. -func (client PrivateZonesClient) ListByResourceGroupComplete(ctx context.Context, resourceGroupName string, top *int32) (result PrivateZoneListResultIterator, err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/PrivateZonesClient.ListByResourceGroup") - defer func() { - sc := -1 - if result.Response().Response.Response != nil { - sc = result.page.Response().Response.Response.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - result.page, err = client.ListByResourceGroup(ctx, resourceGroupName, top) - return -} - -// Update updates a Private DNS zone. Does not modify virtual network links or DNS records within the zone. -// Parameters: -// resourceGroupName - the name of the resource group. -// privateZoneName - the name of the Private DNS zone (without a terminating dot). -// parameters - parameters supplied to the Update operation. -// ifMatch - the ETag of the Private DNS zone. Omit this value to always overwrite the current zone. Specify -// the last-seen ETag value to prevent accidentally overwriting any concurrent changes. -func (client PrivateZonesClient) Update(ctx context.Context, resourceGroupName string, privateZoneName string, parameters PrivateZone, ifMatch string) (result PrivateZonesUpdateFuture, err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/PrivateZonesClient.Update") - defer func() { - sc := -1 - if result.FutureAPI != nil && result.FutureAPI.Response() != nil { - sc = result.FutureAPI.Response().StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - req, err := client.UpdatePreparer(ctx, resourceGroupName, privateZoneName, parameters, ifMatch) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.PrivateZonesClient", "Update", nil, "Failure preparing request") - return - } - - result, err = client.UpdateSender(req) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.PrivateZonesClient", "Update", result.Response(), "Failure sending request") - return - } - - return -} - -// UpdatePreparer prepares the Update request. -func (client PrivateZonesClient) UpdatePreparer(ctx context.Context, resourceGroupName string, privateZoneName string, parameters PrivateZone, ifMatch string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "privateZoneName": autorest.Encode("path", privateZoneName), - "resourceGroupName": autorest.Encode("path", resourceGroupName), - "subscriptionId": autorest.Encode("path", client.SubscriptionID), - } - - const APIVersion = "2020-06-01" - queryParameters := map[string]interface{}{ - "api-version": APIVersion, - } - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/json; charset=utf-8"), - autorest.AsPatch(), - autorest.WithBaseURL(client.BaseURI), - autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/privateDnsZones/{privateZoneName}", pathParameters), - autorest.WithJSON(parameters), - autorest.WithQueryParameters(queryParameters)) - if len(ifMatch) > 0 { - preparer = autorest.DecoratePreparer(preparer, - autorest.WithHeader("If-Match", autorest.String(ifMatch))) - } - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// UpdateSender sends the Update request. The method will close the -// http.Response Body if it receives an error. -func (client PrivateZonesClient) UpdateSender(req *http.Request) (future PrivateZonesUpdateFuture, err error) { - var resp *http.Response - future.FutureAPI = &azure.Future{} - resp, err = client.Send(req, azure.DoRetryWithRegistration(client.Client)) - if err != nil { - return - } - var azf azure.Future - azf, err = azure.NewFutureFromResponse(resp) - future.FutureAPI = &azf - future.Result = future.result - return -} - -// UpdateResponder handles the response to the Update request. The method always -// closes the http.Response Body. -func (client PrivateZonesClient) UpdateResponder(resp *http.Response) (result PrivateZone, err error) { - err = autorest.Respond( - resp, - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), - autorest.ByUnmarshallingJSON(&result), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - return -} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2020-06-01/privatedns/recordsets.go b/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2020-06-01/privatedns/recordsets.go deleted file mode 100644 index e1f39bb0..00000000 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2020-06-01/privatedns/recordsets.go +++ /dev/null @@ -1,640 +0,0 @@ -package privatedns - -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See License.txt in the project root for license information. -// -// Code generated by Microsoft (R) AutoRest Code Generator. -// Changes may cause incorrect behavior and will be lost if the code is regenerated. - -import ( - "context" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/tracing" - "net/http" -) - -// RecordSetsClient is the the Private DNS Management Client. -type RecordSetsClient struct { - BaseClient -} - -// NewRecordSetsClient creates an instance of the RecordSetsClient client. -func NewRecordSetsClient(subscriptionID string) RecordSetsClient { - return NewRecordSetsClientWithBaseURI(DefaultBaseURI, subscriptionID) -} - -// NewRecordSetsClientWithBaseURI creates an instance of the RecordSetsClient client using a custom endpoint. Use this -// when interacting with an Azure cloud that uses a non-standard base URI (sovereign clouds, Azure stack). -func NewRecordSetsClientWithBaseURI(baseURI string, subscriptionID string) RecordSetsClient { - return RecordSetsClient{NewWithBaseURI(baseURI, subscriptionID)} -} - -// CreateOrUpdate creates or updates a record set within a Private DNS zone. -// Parameters: -// resourceGroupName - the name of the resource group. -// privateZoneName - the name of the Private DNS zone (without a terminating dot). -// recordType - the type of DNS record in this record set. Record sets of type SOA can be updated but not -// created (they are created when the Private DNS zone is created). -// relativeRecordSetName - the name of the record set, relative to the name of the zone. -// parameters - parameters supplied to the CreateOrUpdate operation. -// ifMatch - the ETag of the record set. Omit this value to always overwrite the current record set. Specify -// the last-seen ETag value to prevent accidentally overwriting any concurrent changes. -// ifNoneMatch - set to '*' to allow a new record set to be created, but to prevent updating an existing record -// set. Other values will be ignored. -func (client RecordSetsClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, privateZoneName string, recordType RecordType, relativeRecordSetName string, parameters RecordSet, ifMatch string, ifNoneMatch string) (result RecordSet, err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/RecordSetsClient.CreateOrUpdate") - defer func() { - sc := -1 - if result.Response.Response != nil { - sc = result.Response.Response.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - req, err := client.CreateOrUpdatePreparer(ctx, resourceGroupName, privateZoneName, recordType, relativeRecordSetName, parameters, ifMatch, ifNoneMatch) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "CreateOrUpdate", nil, "Failure preparing request") - return - } - - resp, err := client.CreateOrUpdateSender(req) - if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "CreateOrUpdate", resp, "Failure sending request") - return - } - - result, err = client.CreateOrUpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "CreateOrUpdate", resp, "Failure responding to request") - return - } - - return -} - -// CreateOrUpdatePreparer prepares the CreateOrUpdate request. -func (client RecordSetsClient) CreateOrUpdatePreparer(ctx context.Context, resourceGroupName string, privateZoneName string, recordType RecordType, relativeRecordSetName string, parameters RecordSet, ifMatch string, ifNoneMatch string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "privateZoneName": autorest.Encode("path", privateZoneName), - "recordType": autorest.Encode("path", recordType), - "relativeRecordSetName": relativeRecordSetName, - "resourceGroupName": autorest.Encode("path", resourceGroupName), - "subscriptionId": autorest.Encode("path", client.SubscriptionID), - } - - const APIVersion = "2020-06-01" - queryParameters := map[string]interface{}{ - "api-version": APIVersion, - } - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/json; charset=utf-8"), - autorest.AsPut(), - autorest.WithBaseURL(client.BaseURI), - autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/privateDnsZones/{privateZoneName}/{recordType}/{relativeRecordSetName}", pathParameters), - autorest.WithJSON(parameters), - autorest.WithQueryParameters(queryParameters)) - if len(ifMatch) > 0 { - preparer = autorest.DecoratePreparer(preparer, - autorest.WithHeader("If-Match", autorest.String(ifMatch))) - } - if len(ifNoneMatch) > 0 { - preparer = autorest.DecoratePreparer(preparer, - autorest.WithHeader("If-None-Match", autorest.String(ifNoneMatch))) - } - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the -// http.Response Body if it receives an error. -func (client RecordSetsClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { - return client.Send(req, azure.DoRetryWithRegistration(client.Client)) -} - -// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always -// closes the http.Response Body. -func (client RecordSetsClient) CreateOrUpdateResponder(resp *http.Response) (result RecordSet, err error) { - err = autorest.Respond( - resp, - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated), - autorest.ByUnmarshallingJSON(&result), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - return -} - -// Delete deletes a record set from a Private DNS zone. This operation cannot be undone. -// Parameters: -// resourceGroupName - the name of the resource group. -// privateZoneName - the name of the Private DNS zone (without a terminating dot). -// recordType - the type of DNS record in this record set. Record sets of type SOA cannot be deleted (they are -// deleted when the Private DNS zone is deleted). -// relativeRecordSetName - the name of the record set, relative to the name of the zone. -// ifMatch - the ETag of the record set. Omit this value to always delete the current record set. Specify the -// last-seen ETag value to prevent accidentally deleting any concurrent changes. -func (client RecordSetsClient) Delete(ctx context.Context, resourceGroupName string, privateZoneName string, recordType RecordType, relativeRecordSetName string, ifMatch string) (result autorest.Response, err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/RecordSetsClient.Delete") - defer func() { - sc := -1 - if result.Response != nil { - sc = result.Response.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - req, err := client.DeletePreparer(ctx, resourceGroupName, privateZoneName, recordType, relativeRecordSetName, ifMatch) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "Delete", nil, "Failure preparing request") - return - } - - resp, err := client.DeleteSender(req) - if err != nil { - result.Response = resp - err = autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "Delete", resp, "Failure sending request") - return - } - - result, err = client.DeleteResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "Delete", resp, "Failure responding to request") - return - } - - return -} - -// DeletePreparer prepares the Delete request. -func (client RecordSetsClient) DeletePreparer(ctx context.Context, resourceGroupName string, privateZoneName string, recordType RecordType, relativeRecordSetName string, ifMatch string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "privateZoneName": autorest.Encode("path", privateZoneName), - "recordType": autorest.Encode("path", recordType), - "relativeRecordSetName": relativeRecordSetName, - "resourceGroupName": autorest.Encode("path", resourceGroupName), - "subscriptionId": autorest.Encode("path", client.SubscriptionID), - } - - const APIVersion = "2020-06-01" - queryParameters := map[string]interface{}{ - "api-version": APIVersion, - } - - preparer := autorest.CreatePreparer( - autorest.AsDelete(), - autorest.WithBaseURL(client.BaseURI), - autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/privateDnsZones/{privateZoneName}/{recordType}/{relativeRecordSetName}", pathParameters), - autorest.WithQueryParameters(queryParameters)) - if len(ifMatch) > 0 { - preparer = autorest.DecoratePreparer(preparer, - autorest.WithHeader("If-Match", autorest.String(ifMatch))) - } - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// DeleteSender sends the Delete request. The method will close the -// http.Response Body if it receives an error. -func (client RecordSetsClient) DeleteSender(req *http.Request) (*http.Response, error) { - return client.Send(req, azure.DoRetryWithRegistration(client.Client)) -} - -// DeleteResponder handles the response to the Delete request. The method always -// closes the http.Response Body. -func (client RecordSetsClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNoContent), - autorest.ByClosing()) - result.Response = resp - return -} - -// Get gets a record set. -// Parameters: -// resourceGroupName - the name of the resource group. -// privateZoneName - the name of the Private DNS zone (without a terminating dot). -// recordType - the type of DNS record in this record set. -// relativeRecordSetName - the name of the record set, relative to the name of the zone. -func (client RecordSetsClient) Get(ctx context.Context, resourceGroupName string, privateZoneName string, recordType RecordType, relativeRecordSetName string) (result RecordSet, err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/RecordSetsClient.Get") - defer func() { - sc := -1 - if result.Response.Response != nil { - sc = result.Response.Response.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - req, err := client.GetPreparer(ctx, resourceGroupName, privateZoneName, recordType, relativeRecordSetName) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "Get", nil, "Failure preparing request") - return - } - - resp, err := client.GetSender(req) - if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "Get", resp, "Failure sending request") - return - } - - result, err = client.GetResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "Get", resp, "Failure responding to request") - return - } - - return -} - -// GetPreparer prepares the Get request. -func (client RecordSetsClient) GetPreparer(ctx context.Context, resourceGroupName string, privateZoneName string, recordType RecordType, relativeRecordSetName string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "privateZoneName": autorest.Encode("path", privateZoneName), - "recordType": autorest.Encode("path", recordType), - "relativeRecordSetName": relativeRecordSetName, - "resourceGroupName": autorest.Encode("path", resourceGroupName), - "subscriptionId": autorest.Encode("path", client.SubscriptionID), - } - - const APIVersion = "2020-06-01" - queryParameters := map[string]interface{}{ - "api-version": APIVersion, - } - - preparer := autorest.CreatePreparer( - autorest.AsGet(), - autorest.WithBaseURL(client.BaseURI), - autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/privateDnsZones/{privateZoneName}/{recordType}/{relativeRecordSetName}", pathParameters), - autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// GetSender sends the Get request. The method will close the -// http.Response Body if it receives an error. -func (client RecordSetsClient) GetSender(req *http.Request) (*http.Response, error) { - return client.Send(req, azure.DoRetryWithRegistration(client.Client)) -} - -// GetResponder handles the response to the Get request. The method always -// closes the http.Response Body. -func (client RecordSetsClient) GetResponder(resp *http.Response) (result RecordSet, err error) { - err = autorest.Respond( - resp, - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByUnmarshallingJSON(&result), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - return -} - -// List lists all record sets in a Private DNS zone. -// Parameters: -// resourceGroupName - the name of the resource group. -// privateZoneName - the name of the Private DNS zone (without a terminating dot). -// top - the maximum number of record sets to return. If not specified, returns up to 100 record sets. -// recordsetnamesuffix - the suffix label of the record set name to be used to filter the record set -// enumeration. If this parameter is specified, the returned enumeration will only contain records that end -// with ".". -func (client RecordSetsClient) List(ctx context.Context, resourceGroupName string, privateZoneName string, top *int32, recordsetnamesuffix string) (result RecordSetListResultPage, err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/RecordSetsClient.List") - defer func() { - sc := -1 - if result.rslr.Response.Response != nil { - sc = result.rslr.Response.Response.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - result.fn = client.listNextResults - req, err := client.ListPreparer(ctx, resourceGroupName, privateZoneName, top, recordsetnamesuffix) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "List", nil, "Failure preparing request") - return - } - - resp, err := client.ListSender(req) - if err != nil { - result.rslr.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "List", resp, "Failure sending request") - return - } - - result.rslr, err = client.ListResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "List", resp, "Failure responding to request") - return - } - if result.rslr.hasNextLink() && result.rslr.IsEmpty() { - err = result.NextWithContext(ctx) - return - } - - return -} - -// ListPreparer prepares the List request. -func (client RecordSetsClient) ListPreparer(ctx context.Context, resourceGroupName string, privateZoneName string, top *int32, recordsetnamesuffix string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "privateZoneName": autorest.Encode("path", privateZoneName), - "resourceGroupName": autorest.Encode("path", resourceGroupName), - "subscriptionId": autorest.Encode("path", client.SubscriptionID), - } - - const APIVersion = "2020-06-01" - queryParameters := map[string]interface{}{ - "api-version": APIVersion, - } - if top != nil { - queryParameters["$top"] = autorest.Encode("query", *top) - } - if len(recordsetnamesuffix) > 0 { - queryParameters["$recordsetnamesuffix"] = autorest.Encode("query", recordsetnamesuffix) - } - - preparer := autorest.CreatePreparer( - autorest.AsGet(), - autorest.WithBaseURL(client.BaseURI), - autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/privateDnsZones/{privateZoneName}/ALL", pathParameters), - autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// ListSender sends the List request. The method will close the -// http.Response Body if it receives an error. -func (client RecordSetsClient) ListSender(req *http.Request) (*http.Response, error) { - return client.Send(req, azure.DoRetryWithRegistration(client.Client)) -} - -// ListResponder handles the response to the List request. The method always -// closes the http.Response Body. -func (client RecordSetsClient) ListResponder(resp *http.Response) (result RecordSetListResult, err error) { - err = autorest.Respond( - resp, - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByUnmarshallingJSON(&result), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - return -} - -// listNextResults retrieves the next set of results, if any. -func (client RecordSetsClient) listNextResults(ctx context.Context, lastResults RecordSetListResult) (result RecordSetListResult, err error) { - req, err := lastResults.recordSetListResultPreparer(ctx) - if err != nil { - return result, autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "listNextResults", nil, "Failure preparing next results request") - } - if req == nil { - return - } - resp, err := client.ListSender(req) - if err != nil { - result.Response = autorest.Response{Response: resp} - return result, autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "listNextResults", resp, "Failure sending next results request") - } - result, err = client.ListResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "listNextResults", resp, "Failure responding to next results request") - } - return -} - -// ListComplete enumerates all values, automatically crossing page boundaries as required. -func (client RecordSetsClient) ListComplete(ctx context.Context, resourceGroupName string, privateZoneName string, top *int32, recordsetnamesuffix string) (result RecordSetListResultIterator, err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/RecordSetsClient.List") - defer func() { - sc := -1 - if result.Response().Response.Response != nil { - sc = result.page.Response().Response.Response.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - result.page, err = client.List(ctx, resourceGroupName, privateZoneName, top, recordsetnamesuffix) - return -} - -// ListByType lists the record sets of a specified type in a Private DNS zone. -// Parameters: -// resourceGroupName - the name of the resource group. -// privateZoneName - the name of the Private DNS zone (without a terminating dot). -// recordType - the type of record sets to enumerate. -// top - the maximum number of record sets to return. If not specified, returns up to 100 record sets. -// recordsetnamesuffix - the suffix label of the record set name to be used to filter the record set -// enumeration. If this parameter is specified, the returned enumeration will only contain records that end -// with ".". -func (client RecordSetsClient) ListByType(ctx context.Context, resourceGroupName string, privateZoneName string, recordType RecordType, top *int32, recordsetnamesuffix string) (result RecordSetListResultPage, err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/RecordSetsClient.ListByType") - defer func() { - sc := -1 - if result.rslr.Response.Response != nil { - sc = result.rslr.Response.Response.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - result.fn = client.listByTypeNextResults - req, err := client.ListByTypePreparer(ctx, resourceGroupName, privateZoneName, recordType, top, recordsetnamesuffix) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "ListByType", nil, "Failure preparing request") - return - } - - resp, err := client.ListByTypeSender(req) - if err != nil { - result.rslr.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "ListByType", resp, "Failure sending request") - return - } - - result.rslr, err = client.ListByTypeResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "ListByType", resp, "Failure responding to request") - return - } - if result.rslr.hasNextLink() && result.rslr.IsEmpty() { - err = result.NextWithContext(ctx) - return - } - - return -} - -// ListByTypePreparer prepares the ListByType request. -func (client RecordSetsClient) ListByTypePreparer(ctx context.Context, resourceGroupName string, privateZoneName string, recordType RecordType, top *int32, recordsetnamesuffix string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "privateZoneName": autorest.Encode("path", privateZoneName), - "recordType": autorest.Encode("path", recordType), - "resourceGroupName": autorest.Encode("path", resourceGroupName), - "subscriptionId": autorest.Encode("path", client.SubscriptionID), - } - - const APIVersion = "2020-06-01" - queryParameters := map[string]interface{}{ - "api-version": APIVersion, - } - if top != nil { - queryParameters["$top"] = autorest.Encode("query", *top) - } - if len(recordsetnamesuffix) > 0 { - queryParameters["$recordsetnamesuffix"] = autorest.Encode("query", recordsetnamesuffix) - } - - preparer := autorest.CreatePreparer( - autorest.AsGet(), - autorest.WithBaseURL(client.BaseURI), - autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/privateDnsZones/{privateZoneName}/{recordType}", pathParameters), - autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// ListByTypeSender sends the ListByType request. The method will close the -// http.Response Body if it receives an error. -func (client RecordSetsClient) ListByTypeSender(req *http.Request) (*http.Response, error) { - return client.Send(req, azure.DoRetryWithRegistration(client.Client)) -} - -// ListByTypeResponder handles the response to the ListByType request. The method always -// closes the http.Response Body. -func (client RecordSetsClient) ListByTypeResponder(resp *http.Response) (result RecordSetListResult, err error) { - err = autorest.Respond( - resp, - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByUnmarshallingJSON(&result), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - return -} - -// listByTypeNextResults retrieves the next set of results, if any. -func (client RecordSetsClient) listByTypeNextResults(ctx context.Context, lastResults RecordSetListResult) (result RecordSetListResult, err error) { - req, err := lastResults.recordSetListResultPreparer(ctx) - if err != nil { - return result, autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "listByTypeNextResults", nil, "Failure preparing next results request") - } - if req == nil { - return - } - resp, err := client.ListByTypeSender(req) - if err != nil { - result.Response = autorest.Response{Response: resp} - return result, autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "listByTypeNextResults", resp, "Failure sending next results request") - } - result, err = client.ListByTypeResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "listByTypeNextResults", resp, "Failure responding to next results request") - } - return -} - -// ListByTypeComplete enumerates all values, automatically crossing page boundaries as required. -func (client RecordSetsClient) ListByTypeComplete(ctx context.Context, resourceGroupName string, privateZoneName string, recordType RecordType, top *int32, recordsetnamesuffix string) (result RecordSetListResultIterator, err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/RecordSetsClient.ListByType") - defer func() { - sc := -1 - if result.Response().Response.Response != nil { - sc = result.page.Response().Response.Response.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - result.page, err = client.ListByType(ctx, resourceGroupName, privateZoneName, recordType, top, recordsetnamesuffix) - return -} - -// Update updates a record set within a Private DNS zone. -// Parameters: -// resourceGroupName - the name of the resource group. -// privateZoneName - the name of the Private DNS zone (without a terminating dot). -// recordType - the type of DNS record in this record set. -// relativeRecordSetName - the name of the record set, relative to the name of the zone. -// parameters - parameters supplied to the Update operation. -// ifMatch - the ETag of the record set. Omit this value to always overwrite the current record set. Specify -// the last-seen ETag value to prevent accidentally overwriting concurrent changes. -func (client RecordSetsClient) Update(ctx context.Context, resourceGroupName string, privateZoneName string, recordType RecordType, relativeRecordSetName string, parameters RecordSet, ifMatch string) (result RecordSet, err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/RecordSetsClient.Update") - defer func() { - sc := -1 - if result.Response.Response != nil { - sc = result.Response.Response.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - req, err := client.UpdatePreparer(ctx, resourceGroupName, privateZoneName, recordType, relativeRecordSetName, parameters, ifMatch) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "Update", nil, "Failure preparing request") - return - } - - resp, err := client.UpdateSender(req) - if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "Update", resp, "Failure sending request") - return - } - - result, err = client.UpdateResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "Update", resp, "Failure responding to request") - return - } - - return -} - -// UpdatePreparer prepares the Update request. -func (client RecordSetsClient) UpdatePreparer(ctx context.Context, resourceGroupName string, privateZoneName string, recordType RecordType, relativeRecordSetName string, parameters RecordSet, ifMatch string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "privateZoneName": autorest.Encode("path", privateZoneName), - "recordType": autorest.Encode("path", recordType), - "relativeRecordSetName": relativeRecordSetName, - "resourceGroupName": autorest.Encode("path", resourceGroupName), - "subscriptionId": autorest.Encode("path", client.SubscriptionID), - } - - const APIVersion = "2020-06-01" - queryParameters := map[string]interface{}{ - "api-version": APIVersion, - } - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/json; charset=utf-8"), - autorest.AsPatch(), - autorest.WithBaseURL(client.BaseURI), - autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/privateDnsZones/{privateZoneName}/{recordType}/{relativeRecordSetName}", pathParameters), - autorest.WithJSON(parameters), - autorest.WithQueryParameters(queryParameters)) - if len(ifMatch) > 0 { - preparer = autorest.DecoratePreparer(preparer, - autorest.WithHeader("If-Match", autorest.String(ifMatch))) - } - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// UpdateSender sends the Update request. The method will close the -// http.Response Body if it receives an error. -func (client RecordSetsClient) UpdateSender(req *http.Request) (*http.Response, error) { - return client.Send(req, azure.DoRetryWithRegistration(client.Client)) -} - -// UpdateResponder handles the response to the Update request. The method always -// closes the http.Response Body. -func (client RecordSetsClient) UpdateResponder(resp *http.Response) (result RecordSet, err error) { - err = autorest.Respond( - resp, - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByUnmarshallingJSON(&result), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - return -} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2020-06-01/privatedns/version.go b/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2020-06-01/privatedns/version.go deleted file mode 100644 index 1e43b22d..00000000 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2020-06-01/privatedns/version.go +++ /dev/null @@ -1,19 +0,0 @@ -package privatedns - -import "github.com/Azure/azure-sdk-for-go/version" - -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See License.txt in the project root for license information. -// -// Code generated by Microsoft (R) AutoRest Code Generator. -// Changes may cause incorrect behavior and will be lost if the code is regenerated. - -// UserAgent returns the UserAgent string to use when sending http.Requests. -func UserAgent() string { - return "Azure-SDK-For-Go/" + Version() + " privatedns/2020-06-01" -} - -// Version returns the semantic version (see http://semver.org) of the client. -func Version() string { - return version.Number -} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2020-06-01/privatedns/virtualnetworklinks.go b/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2020-06-01/privatedns/virtualnetworklinks.go deleted file mode 100644 index 03e60692..00000000 --- a/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2020-06-01/privatedns/virtualnetworklinks.go +++ /dev/null @@ -1,509 +0,0 @@ -package privatedns - -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See License.txt in the project root for license information. -// -// Code generated by Microsoft (R) AutoRest Code Generator. -// Changes may cause incorrect behavior and will be lost if the code is regenerated. - -import ( - "context" - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/tracing" - "net/http" -) - -// VirtualNetworkLinksClient is the the Private DNS Management Client. -type VirtualNetworkLinksClient struct { - BaseClient -} - -// NewVirtualNetworkLinksClient creates an instance of the VirtualNetworkLinksClient client. -func NewVirtualNetworkLinksClient(subscriptionID string) VirtualNetworkLinksClient { - return NewVirtualNetworkLinksClientWithBaseURI(DefaultBaseURI, subscriptionID) -} - -// NewVirtualNetworkLinksClientWithBaseURI creates an instance of the VirtualNetworkLinksClient client using a custom -// endpoint. Use this when interacting with an Azure cloud that uses a non-standard base URI (sovereign clouds, Azure -// stack). -func NewVirtualNetworkLinksClientWithBaseURI(baseURI string, subscriptionID string) VirtualNetworkLinksClient { - return VirtualNetworkLinksClient{NewWithBaseURI(baseURI, subscriptionID)} -} - -// CreateOrUpdate creates or updates a virtual network link to the specified Private DNS zone. -// Parameters: -// resourceGroupName - the name of the resource group. -// privateZoneName - the name of the Private DNS zone (without a terminating dot). -// virtualNetworkLinkName - the name of the virtual network link. -// parameters - parameters supplied to the CreateOrUpdate operation. -// ifMatch - the ETag of the virtual network link to the Private DNS zone. Omit this value to always overwrite -// the current virtual network link. Specify the last-seen ETag value to prevent accidentally overwriting any -// concurrent changes. -// ifNoneMatch - set to '*' to allow a new virtual network link to the Private DNS zone to be created, but to -// prevent updating an existing link. Other values will be ignored. -func (client VirtualNetworkLinksClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, privateZoneName string, virtualNetworkLinkName string, parameters VirtualNetworkLink, ifMatch string, ifNoneMatch string) (result VirtualNetworkLinksCreateOrUpdateFuture, err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/VirtualNetworkLinksClient.CreateOrUpdate") - defer func() { - sc := -1 - if result.FutureAPI != nil && result.FutureAPI.Response() != nil { - sc = result.FutureAPI.Response().StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - req, err := client.CreateOrUpdatePreparer(ctx, resourceGroupName, privateZoneName, virtualNetworkLinkName, parameters, ifMatch, ifNoneMatch) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.VirtualNetworkLinksClient", "CreateOrUpdate", nil, "Failure preparing request") - return - } - - result, err = client.CreateOrUpdateSender(req) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.VirtualNetworkLinksClient", "CreateOrUpdate", result.Response(), "Failure sending request") - return - } - - return -} - -// CreateOrUpdatePreparer prepares the CreateOrUpdate request. -func (client VirtualNetworkLinksClient) CreateOrUpdatePreparer(ctx context.Context, resourceGroupName string, privateZoneName string, virtualNetworkLinkName string, parameters VirtualNetworkLink, ifMatch string, ifNoneMatch string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "privateZoneName": autorest.Encode("path", privateZoneName), - "resourceGroupName": autorest.Encode("path", resourceGroupName), - "subscriptionId": autorest.Encode("path", client.SubscriptionID), - "virtualNetworkLinkName": autorest.Encode("path", virtualNetworkLinkName), - } - - const APIVersion = "2020-06-01" - queryParameters := map[string]interface{}{ - "api-version": APIVersion, - } - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/json; charset=utf-8"), - autorest.AsPut(), - autorest.WithBaseURL(client.BaseURI), - autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/privateDnsZones/{privateZoneName}/virtualNetworkLinks/{virtualNetworkLinkName}", pathParameters), - autorest.WithJSON(parameters), - autorest.WithQueryParameters(queryParameters)) - if len(ifMatch) > 0 { - preparer = autorest.DecoratePreparer(preparer, - autorest.WithHeader("If-Match", autorest.String(ifMatch))) - } - if len(ifNoneMatch) > 0 { - preparer = autorest.DecoratePreparer(preparer, - autorest.WithHeader("If-None-Match", autorest.String(ifNoneMatch))) - } - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the -// http.Response Body if it receives an error. -func (client VirtualNetworkLinksClient) CreateOrUpdateSender(req *http.Request) (future VirtualNetworkLinksCreateOrUpdateFuture, err error) { - var resp *http.Response - future.FutureAPI = &azure.Future{} - resp, err = client.Send(req, azure.DoRetryWithRegistration(client.Client)) - if err != nil { - return - } - var azf azure.Future - azf, err = azure.NewFutureFromResponse(resp) - future.FutureAPI = &azf - future.Result = future.result - return -} - -// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always -// closes the http.Response Body. -func (client VirtualNetworkLinksClient) CreateOrUpdateResponder(resp *http.Response) (result VirtualNetworkLink, err error) { - err = autorest.Respond( - resp, - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated, http.StatusAccepted), - autorest.ByUnmarshallingJSON(&result), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - return -} - -// Delete deletes a virtual network link to the specified Private DNS zone. WARNING: In case of a registration virtual -// network, all auto-registered DNS records in the zone for the virtual network will also be deleted. This operation -// cannot be undone. -// Parameters: -// resourceGroupName - the name of the resource group. -// privateZoneName - the name of the Private DNS zone (without a terminating dot). -// virtualNetworkLinkName - the name of the virtual network link. -// ifMatch - the ETag of the virtual network link to the Private DNS zone. Omit this value to always delete the -// current zone. Specify the last-seen ETag value to prevent accidentally deleting any concurrent changes. -func (client VirtualNetworkLinksClient) Delete(ctx context.Context, resourceGroupName string, privateZoneName string, virtualNetworkLinkName string, ifMatch string) (result VirtualNetworkLinksDeleteFuture, err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/VirtualNetworkLinksClient.Delete") - defer func() { - sc := -1 - if result.FutureAPI != nil && result.FutureAPI.Response() != nil { - sc = result.FutureAPI.Response().StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - req, err := client.DeletePreparer(ctx, resourceGroupName, privateZoneName, virtualNetworkLinkName, ifMatch) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.VirtualNetworkLinksClient", "Delete", nil, "Failure preparing request") - return - } - - result, err = client.DeleteSender(req) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.VirtualNetworkLinksClient", "Delete", result.Response(), "Failure sending request") - return - } - - return -} - -// DeletePreparer prepares the Delete request. -func (client VirtualNetworkLinksClient) DeletePreparer(ctx context.Context, resourceGroupName string, privateZoneName string, virtualNetworkLinkName string, ifMatch string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "privateZoneName": autorest.Encode("path", privateZoneName), - "resourceGroupName": autorest.Encode("path", resourceGroupName), - "subscriptionId": autorest.Encode("path", client.SubscriptionID), - "virtualNetworkLinkName": autorest.Encode("path", virtualNetworkLinkName), - } - - const APIVersion = "2020-06-01" - queryParameters := map[string]interface{}{ - "api-version": APIVersion, - } - - preparer := autorest.CreatePreparer( - autorest.AsDelete(), - autorest.WithBaseURL(client.BaseURI), - autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/privateDnsZones/{privateZoneName}/virtualNetworkLinks/{virtualNetworkLinkName}", pathParameters), - autorest.WithQueryParameters(queryParameters)) - if len(ifMatch) > 0 { - preparer = autorest.DecoratePreparer(preparer, - autorest.WithHeader("If-Match", autorest.String(ifMatch))) - } - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// DeleteSender sends the Delete request. The method will close the -// http.Response Body if it receives an error. -func (client VirtualNetworkLinksClient) DeleteSender(req *http.Request) (future VirtualNetworkLinksDeleteFuture, err error) { - var resp *http.Response - future.FutureAPI = &azure.Future{} - resp, err = client.Send(req, azure.DoRetryWithRegistration(client.Client)) - if err != nil { - return - } - var azf azure.Future - azf, err = azure.NewFutureFromResponse(resp) - future.FutureAPI = &azf - future.Result = future.result - return -} - -// DeleteResponder handles the response to the Delete request. The method always -// closes the http.Response Body. -func (client VirtualNetworkLinksClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { - err = autorest.Respond( - resp, - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent), - autorest.ByClosing()) - result.Response = resp - return -} - -// Get gets a virtual network link to the specified Private DNS zone. -// Parameters: -// resourceGroupName - the name of the resource group. -// privateZoneName - the name of the Private DNS zone (without a terminating dot). -// virtualNetworkLinkName - the name of the virtual network link. -func (client VirtualNetworkLinksClient) Get(ctx context.Context, resourceGroupName string, privateZoneName string, virtualNetworkLinkName string) (result VirtualNetworkLink, err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/VirtualNetworkLinksClient.Get") - defer func() { - sc := -1 - if result.Response.Response != nil { - sc = result.Response.Response.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - req, err := client.GetPreparer(ctx, resourceGroupName, privateZoneName, virtualNetworkLinkName) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.VirtualNetworkLinksClient", "Get", nil, "Failure preparing request") - return - } - - resp, err := client.GetSender(req) - if err != nil { - result.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "privatedns.VirtualNetworkLinksClient", "Get", resp, "Failure sending request") - return - } - - result, err = client.GetResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.VirtualNetworkLinksClient", "Get", resp, "Failure responding to request") - return - } - - return -} - -// GetPreparer prepares the Get request. -func (client VirtualNetworkLinksClient) GetPreparer(ctx context.Context, resourceGroupName string, privateZoneName string, virtualNetworkLinkName string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "privateZoneName": autorest.Encode("path", privateZoneName), - "resourceGroupName": autorest.Encode("path", resourceGroupName), - "subscriptionId": autorest.Encode("path", client.SubscriptionID), - "virtualNetworkLinkName": autorest.Encode("path", virtualNetworkLinkName), - } - - const APIVersion = "2020-06-01" - queryParameters := map[string]interface{}{ - "api-version": APIVersion, - } - - preparer := autorest.CreatePreparer( - autorest.AsGet(), - autorest.WithBaseURL(client.BaseURI), - autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/privateDnsZones/{privateZoneName}/virtualNetworkLinks/{virtualNetworkLinkName}", pathParameters), - autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// GetSender sends the Get request. The method will close the -// http.Response Body if it receives an error. -func (client VirtualNetworkLinksClient) GetSender(req *http.Request) (*http.Response, error) { - return client.Send(req, azure.DoRetryWithRegistration(client.Client)) -} - -// GetResponder handles the response to the Get request. The method always -// closes the http.Response Body. -func (client VirtualNetworkLinksClient) GetResponder(resp *http.Response) (result VirtualNetworkLink, err error) { - err = autorest.Respond( - resp, - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByUnmarshallingJSON(&result), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - return -} - -// List lists the virtual network links to the specified Private DNS zone. -// Parameters: -// resourceGroupName - the name of the resource group. -// privateZoneName - the name of the Private DNS zone (without a terminating dot). -// top - the maximum number of virtual network links to return. If not specified, returns up to 100 virtual -// network links. -func (client VirtualNetworkLinksClient) List(ctx context.Context, resourceGroupName string, privateZoneName string, top *int32) (result VirtualNetworkLinkListResultPage, err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/VirtualNetworkLinksClient.List") - defer func() { - sc := -1 - if result.vnllr.Response.Response != nil { - sc = result.vnllr.Response.Response.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - result.fn = client.listNextResults - req, err := client.ListPreparer(ctx, resourceGroupName, privateZoneName, top) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.VirtualNetworkLinksClient", "List", nil, "Failure preparing request") - return - } - - resp, err := client.ListSender(req) - if err != nil { - result.vnllr.Response = autorest.Response{Response: resp} - err = autorest.NewErrorWithError(err, "privatedns.VirtualNetworkLinksClient", "List", resp, "Failure sending request") - return - } - - result.vnllr, err = client.ListResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.VirtualNetworkLinksClient", "List", resp, "Failure responding to request") - return - } - if result.vnllr.hasNextLink() && result.vnllr.IsEmpty() { - err = result.NextWithContext(ctx) - return - } - - return -} - -// ListPreparer prepares the List request. -func (client VirtualNetworkLinksClient) ListPreparer(ctx context.Context, resourceGroupName string, privateZoneName string, top *int32) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "privateZoneName": autorest.Encode("path", privateZoneName), - "resourceGroupName": autorest.Encode("path", resourceGroupName), - "subscriptionId": autorest.Encode("path", client.SubscriptionID), - } - - const APIVersion = "2020-06-01" - queryParameters := map[string]interface{}{ - "api-version": APIVersion, - } - if top != nil { - queryParameters["$top"] = autorest.Encode("query", *top) - } - - preparer := autorest.CreatePreparer( - autorest.AsGet(), - autorest.WithBaseURL(client.BaseURI), - autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/privateDnsZones/{privateZoneName}/virtualNetworkLinks", pathParameters), - autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// ListSender sends the List request. The method will close the -// http.Response Body if it receives an error. -func (client VirtualNetworkLinksClient) ListSender(req *http.Request) (*http.Response, error) { - return client.Send(req, azure.DoRetryWithRegistration(client.Client)) -} - -// ListResponder handles the response to the List request. The method always -// closes the http.Response Body. -func (client VirtualNetworkLinksClient) ListResponder(resp *http.Response) (result VirtualNetworkLinkListResult, err error) { - err = autorest.Respond( - resp, - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByUnmarshallingJSON(&result), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - return -} - -// listNextResults retrieves the next set of results, if any. -func (client VirtualNetworkLinksClient) listNextResults(ctx context.Context, lastResults VirtualNetworkLinkListResult) (result VirtualNetworkLinkListResult, err error) { - req, err := lastResults.virtualNetworkLinkListResultPreparer(ctx) - if err != nil { - return result, autorest.NewErrorWithError(err, "privatedns.VirtualNetworkLinksClient", "listNextResults", nil, "Failure preparing next results request") - } - if req == nil { - return - } - resp, err := client.ListSender(req) - if err != nil { - result.Response = autorest.Response{Response: resp} - return result, autorest.NewErrorWithError(err, "privatedns.VirtualNetworkLinksClient", "listNextResults", resp, "Failure sending next results request") - } - result, err = client.ListResponder(resp) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.VirtualNetworkLinksClient", "listNextResults", resp, "Failure responding to next results request") - } - return -} - -// ListComplete enumerates all values, automatically crossing page boundaries as required. -func (client VirtualNetworkLinksClient) ListComplete(ctx context.Context, resourceGroupName string, privateZoneName string, top *int32) (result VirtualNetworkLinkListResultIterator, err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/VirtualNetworkLinksClient.List") - defer func() { - sc := -1 - if result.Response().Response.Response != nil { - sc = result.page.Response().Response.Response.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - result.page, err = client.List(ctx, resourceGroupName, privateZoneName, top) - return -} - -// Update updates a virtual network link to the specified Private DNS zone. -// Parameters: -// resourceGroupName - the name of the resource group. -// privateZoneName - the name of the Private DNS zone (without a terminating dot). -// virtualNetworkLinkName - the name of the virtual network link. -// parameters - parameters supplied to the Update operation. -// ifMatch - the ETag of the virtual network link to the Private DNS zone. Omit this value to always overwrite -// the current virtual network link. Specify the last-seen ETag value to prevent accidentally overwriting any -// concurrent changes. -func (client VirtualNetworkLinksClient) Update(ctx context.Context, resourceGroupName string, privateZoneName string, virtualNetworkLinkName string, parameters VirtualNetworkLink, ifMatch string) (result VirtualNetworkLinksUpdateFuture, err error) { - if tracing.IsEnabled() { - ctx = tracing.StartSpan(ctx, fqdn+"/VirtualNetworkLinksClient.Update") - defer func() { - sc := -1 - if result.FutureAPI != nil && result.FutureAPI.Response() != nil { - sc = result.FutureAPI.Response().StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - } - req, err := client.UpdatePreparer(ctx, resourceGroupName, privateZoneName, virtualNetworkLinkName, parameters, ifMatch) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.VirtualNetworkLinksClient", "Update", nil, "Failure preparing request") - return - } - - result, err = client.UpdateSender(req) - if err != nil { - err = autorest.NewErrorWithError(err, "privatedns.VirtualNetworkLinksClient", "Update", result.Response(), "Failure sending request") - return - } - - return -} - -// UpdatePreparer prepares the Update request. -func (client VirtualNetworkLinksClient) UpdatePreparer(ctx context.Context, resourceGroupName string, privateZoneName string, virtualNetworkLinkName string, parameters VirtualNetworkLink, ifMatch string) (*http.Request, error) { - pathParameters := map[string]interface{}{ - "privateZoneName": autorest.Encode("path", privateZoneName), - "resourceGroupName": autorest.Encode("path", resourceGroupName), - "subscriptionId": autorest.Encode("path", client.SubscriptionID), - "virtualNetworkLinkName": autorest.Encode("path", virtualNetworkLinkName), - } - - const APIVersion = "2020-06-01" - queryParameters := map[string]interface{}{ - "api-version": APIVersion, - } - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/json; charset=utf-8"), - autorest.AsPatch(), - autorest.WithBaseURL(client.BaseURI), - autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/privateDnsZones/{privateZoneName}/virtualNetworkLinks/{virtualNetworkLinkName}", pathParameters), - autorest.WithJSON(parameters), - autorest.WithQueryParameters(queryParameters)) - if len(ifMatch) > 0 { - preparer = autorest.DecoratePreparer(preparer, - autorest.WithHeader("If-Match", autorest.String(ifMatch))) - } - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// UpdateSender sends the Update request. The method will close the -// http.Response Body if it receives an error. -func (client VirtualNetworkLinksClient) UpdateSender(req *http.Request) (future VirtualNetworkLinksUpdateFuture, err error) { - var resp *http.Response - future.FutureAPI = &azure.Future{} - resp, err = client.Send(req, azure.DoRetryWithRegistration(client.Client)) - if err != nil { - return - } - var azf azure.Future - azf, err = azure.NewFutureFromResponse(resp) - future.FutureAPI = &azf - future.Result = future.result - return -} - -// UpdateResponder handles the response to the Update request. The method always -// closes the http.Response Body. -func (client VirtualNetworkLinksClient) UpdateResponder(resp *http.Response) (result VirtualNetworkLink, err error) { - err = autorest.Respond( - resp, - azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), - autorest.ByUnmarshallingJSON(&result), - autorest.ByClosing()) - result.Response = autorest.Response{Response: resp} - return -} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/version/version.go b/vendor/github.com/Azure/azure-sdk-for-go/version/version.go deleted file mode 100644 index bcfbb15c..00000000 --- a/vendor/github.com/Azure/azure-sdk-for-go/version/version.go +++ /dev/null @@ -1,7 +0,0 @@ -package version - -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See License.txt in the project root for license information. - -// Number contains the semantic version of this SDK. -const Number = "v68.0.0" diff --git a/vendor/github.com/Azure/go-autorest/.gitignore b/vendor/github.com/Azure/go-autorest/.gitignore deleted file mode 100644 index 3350aaf7..00000000 --- a/vendor/github.com/Azure/go-autorest/.gitignore +++ /dev/null @@ -1,32 +0,0 @@ -# The standard Go .gitignore file follows. (Sourced from: github.com/github/gitignore/master/Go.gitignore) -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test -.DS_Store -.idea/ -.vscode/ - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe -*.test -*.prof - -# go-autorest specific -vendor/ -autorest/azure/example/example diff --git a/vendor/github.com/Azure/go-autorest/CHANGELOG.md b/vendor/github.com/Azure/go-autorest/CHANGELOG.md deleted file mode 100644 index d1f596bf..00000000 --- a/vendor/github.com/Azure/go-autorest/CHANGELOG.md +++ /dev/null @@ -1,1004 +0,0 @@ -# CHANGELOG - -## v14.2.0 - -- Added package comment to make `github.com/Azure/go-autorest` importable. - -## v14.1.1 - -### Bug Fixes - -- Change `x-ms-authorization-auxiliary` header value separator to comma. - -## v14.1.0 - -### New Features - -- Added `azure.SetEnvironment()` that will update the global environments map with the specified values. - -## v14.0.1 - -### Bug Fixes - -- Fix race condition when refreshing token. -- Fixed some tests to work with Go 1.14. - -## v14.0.0 - -## Breaking Changes - -- By default, the `DoRetryForStatusCodes` functions will no longer infinitely retry a request when the response returns an HTTP status code of 429 (StatusTooManyRequests). To opt in to the old behavior set `autorest.Count429AsRetry` to `false`. - -## New Features - -- Variable `autorest.Max429Delay` can be used to control the maximum delay between retries when a 429 is received with no `Retry-After` header. The default is zero which means there is no cap. - -## v13.4.0 - -## New Features - -- Added field `SendDecorators` to the `Client` type. This can be used to specify a custom chain of SendDecorators per client. -- Added method `Client.Send()` which includes logic for selecting the preferred chain of SendDecorators. - -## v13.3.3 - -### Bug Fixes - -- Fixed connection leak when retrying requests. -- Enabled exponential back-off with a 2-minute cap when retrying on 429. -- Fixed some cases where errors were inadvertently dropped. - -## v13.3.2 - -### Bug Fixes - -- Updated `autorest.AsStringSlice()` to convert slice elements to their string representation. - -## v13.3.1 - -- Updated external dependencies. - -### Bug Fixes - -## v13.3.0 - -### New Features - -- Added support for shared key and shared access signature token authorization. - - `autorest.NewSharedKeyAuthorizer()` and dependent types. - - `autorest.NewSASTokenAuthorizer()` and dependent types. -- Added `ServicePrincipalToken.SetCustomRefresh()` so a custom refresh function can be invoked when a token has expired. - -### Bug Fixes - -- Fixed `cli.AccessTokensPath()` to respect `AZURE_CONFIG_DIR` when set. -- Support parsing error messages in XML responses. - -## v13.2.0 - -### New Features - -- Added the following functions to replace their versions that don't take a context. - - `adal.InitiateDeviceAuthWithContext()` - - `adal.CheckForUserCompletionWithContext()` - - `adal.WaitForUserCompletionWithContext()` - -## v13.1.0 - -### New Features - -- Added support for MSI authentication on Azure App Service and Azure Functions. - -## v13.0.2 - -### Bug Fixes - -- Always retry a request even if the sender returns a non-nil error. - -## v13.0.1 - -## Bug Fixes - -- Fixed `autorest.WithQueryParameters()` so that it properly encodes multi-value query parameters. - -## v13.0.0 - -## Breaking Changes - -The `tracing` package has been rewritten to provide a common interface for consumers to wire in the tracing package of their choice. -What this means is that by default no tracing provider will be compiled into your program and setting the `AZURE_SDK_TRACING_ENABLED` -environment variable will have no effect. To enable this previous behavior you must now add the following import to your source file. -```go - import _ "github.com/Azure/go-autorest/tracing/opencensus" -``` -The APIs required by autorest-generated code have remained but some APIs have been removed and new ones added. -The following APIs and variables have been removed (the majority of them were moved to the `opencensus` package). -- tracing.Transport -- tracing.Enable() -- tracing.EnableWithAIForwarding() -- tracing.Disable() - -The following APIs and types have been added -- tracing.Tracer -- tracing.Register() - -To hook up a tracer simply call `tracing.Register()` passing in a type that satisfies the `tracing.Tracer` interface. - -## v12.4.3 - -### Bug Fixes - -- `autorest.MultiTenantServicePrincipalTokenAuthorizer` will now properly add its auxiliary bearer tokens. - -## v12.4.2 - -### Bug Fixes - -- Improvements to the fixes made in v12.4.1. - - Remove `override` stanza from Gopkg.toml and `replace` directive from go.mod as they don't apply when being consumed as a dependency. - - Switched to latest version of `ocagent` that still depends on protobuf v1.2. - - Add indirect dependencies to the `required` clause with matching `constraint` stanzas so that `dep` dependencies match go.sum. - -## v12.4.1 - -### Bug Fixes - -- Updated OpenCensus and OCAgent versions to versions that don't depend on v1.3+ of protobuf as it was breaking kubernetes. -- Pinned opencensus-proto to a version that's compatible with our versions of OpenCensus and OCAgent. - -## v12.4.0 - -### New Features - -- Added `autorest.WithPrepareDecorators` and `autorest.GetPrepareDecorators` for adding and retrieving a custom chain of PrepareDecorators to the provided context. - -## v12.3.0 - -### New Features - -- Support for multi-tenant via x-ms-authorization-auxiliary header has been added for client credentials with - secret scenario; this basically bundles multiple OAuthConfig and ServicePrincipalToken types into corresponding - MultiTenant* types along with a new authorizer that adds the primary and auxiliary token headers to the reqest. - The authenticaion helpers have been updated to support this scenario; if environment var AZURE_AUXILIARY_TENANT_IDS - is set with a semicolon delimited list of tenants the multi-tenant codepath will kick in to create the appropriate authorizer. - See `adal.NewMultiTenantOAuthConfig`, `adal.NewMultiTenantServicePrincipalToken` and `autorest.NewMultiTenantServicePrincipalTokenAuthorizer` - along with their supporting types and methods. -- Added `autorest.WithSendDecorators` and `autorest.GetSendDecorators` for adding and retrieving a custom chain of SendDecorators to the provided context. -- Added `autorest.DoRetryForStatusCodesWithCap` and `autorest.DelayForBackoffWithCap` to enforce an upper bound on the duration between retries. - -## v12.2.0 - -### New Features - -- Added `autorest.WithXML`, `autorest.AsMerge`, `autorest.WithBytes` preparer decorators. -- Added `autorest.ByUnmarshallingBytes` response decorator. -- Added `Response.IsHTTPStatus` and `Response.HasHTTPStatus` helper methods for inspecting HTTP status code in `autorest.Response` types. - -### Bug Fixes - -- `autorest.DelayWithRetryAfter` now supports HTTP-Dates in the `Retry-After` header and is not limited to just 429 status codes. - -## v12.1.0 - -### New Features - -- Added `to.ByteSlicePtr()`. -- Added blob/queue storage resource ID to `azure.ResourceIdentifier`. - -## v12.0.0 - -### Breaking Changes - -In preparation for modules the following deprecated content has been removed. - - - async.NewFuture() - - async.Future.Done() - - async.Future.WaitForCompletion() - - async.DoPollForAsynchronous() - - The `utils` package - - validation.NewErrorWithValidationError() - - The `version` package - -## v11.9.0 - -### New Features - -- Add `ResourceIdentifiers` field to `azure.Environment` containing resource IDs for public and sovereign clouds. - -## v11.8.0 - -### New Features - -- Added `autorest.NewClientWithOptions()` to support endpoints that require free renegotiation. - -## v11.7.1 - -### Bug Fixes - -- Fix missing support for http(s) proxy when using the default sender. - -## v11.7.0 - -### New Features - -- Added methods to obtain a ServicePrincipalToken on the various credential configuration types in the `auth` package. - -## v11.6.1 - -### Bug Fixes - -- Fix ACR DNS endpoint for government clouds. -- Add Cosmos DB DNS endpoints. -- Update dependencies to resolve build breaks in OpenCensus. - -## v11.6.0 - -### New Features - -- Added type `autorest.BasicAuthorizer` to support Basic authentication. - -## v11.5.2 - -### Bug Fixes - -- Fixed `GetTokenFromCLI` did not work with zsh. - -## v11.5.1 - -### Bug Fixes - -- In `Client.sender()` set the minimum TLS version on HTTP clients to 1.2. - -## v11.5.0 - -### New Features - -- The `auth` package has been refactored so that the environment and file settings are now available. -- The methods used in `auth.NewAuthorizerFromEnvironment()` are now exported so that custom authorization chains can be created. -- Added support for certificate authorization for file-based config. - -## v11.4.0 - -### New Features - -- Added `adal.AddToUserAgent()` so callers can append custom data to the user-agent header used for ADAL requests. -- Exported `adal.UserAgent()` for parity with `autorest.Client`. - -## v11.3.2 - -### Bug Fixes - -- In `Future.WaitForCompletionRef()` if the provided context has a deadline don't add the default deadline. - -## v11.3.1 - -### Bug Fixes - -- For an LRO PUT operation the final GET URL was incorrectly set to the Location polling header in some cases. - -## v11.3.0 - -### New Features - -- Added method `ServicePrincipalToken()` to `DeviceFlowConfig` type. - -## v11.2.8 - -### Bug Fixes - -- Deprecate content in the `version` package. The functionality has been superseded by content in the `autorest` package. - -## v11.2.7 - -### Bug Fixes - -- Fix environment variable name for enabling tracing from `AZURE_SDK_TRACING_ENABELD` to `AZURE_SDK_TRACING_ENABLED`. - Note that for backward compatibility reasons, both will work until the next major version release of the package. - -## v11.2.6 - -### Bug Fixes - -- If zero bytes are read from a polling response body don't attempt to unmarshal them. - -## v11.2.5 - -### Bug Fixes - -- Removed race condition in `autorest.DoRetryForStatusCodes`. - -## v11.2.4 - -### Bug Fixes - -- Function `cli.ProfilePath` now respects environment `AZURE_CONFIG_DIR` if available. - -## v11.2.1 - -NOTE: Versions of Go prior to 1.10 have been removed from CI as they no -longer work with golint. - -### Bug Fixes - -- Method `MSIConfig.Authorizer` now supports user-assigned identities. -- The adal package now reports its own user-agent string. - -## v11.2.0 - -### New Features - -- Added `tracing` package that enables instrumentation of HTTP and API calls. - Setting the env variable `AZURE_SDK_TRACING_ENABLED` or calling `tracing.Enable` - will start instrumenting the code for metrics and traces. - Additionally, setting the env variable `OCAGENT_TRACE_EXPORTER_ENDPOINT` or - calling `tracing.EnableWithAIForwarding` will start the instrumentation and connect to an - App Insights Local Forwarder that is needs to be running. Note that if the - AI Local Forwarder is not running tracking will still be enabled. - By default, instrumentation is disabled. Once enabled, instrumentation can also - be programatically disabled by calling `Disable`. -- Added `DoneWithContext` call for checking LRO status. `Done` has been deprecated. - -### Bug Fixes - -- Don't use the initial request's context for LRO polling. -- Don't override the `refreshLock` and the `http.Client` when unmarshalling `ServicePrincipalToken` if - it is already set. - -## v11.1.1 - -### Bug Fixes - -- When creating a future always include the polling tracker even if there's a failure; this allows the underlying response to be obtained by the caller. - -## v11.1.0 - -### New Features - -- Added `auth.NewAuthorizerFromCLI` to create an authorizer configured from the Azure 2.0 CLI. -- Added `adal.NewOAuthConfigWithAPIVersion` to create an OAuthConfig with the specified API version. - -## v11.0.1 - -### New Features - -- Added `x5c` header to client assertion for certificate Issuer+Subject Name authentication. - -## v11.0.0 - -### Breaking Changes - -- To handle differences between ADFS and AAD the following fields have had their types changed from `string` to `json.Number` - - ExpiresIn - - ExpiresOn - - NotBefore - -### New Features - -- Added `auth.NewAuthorizerFromFileWithResource` to create an authorizer from the config file with the specified resource. -- Setting a client's `PollingDuration` to zero will use the provided context to control a LRO's polling duration. - -## v10.15.5 - -### Bug Fixes - -- In `DoRetryForStatusCodes`, if a request's context is cancelled return the last response. - -## v10.15.4 - -### Bug Fixes - -- If a polling operation returns a failure status code return the associated error. - -## v10.15.3 - -### Bug Fixes - -- Initialize the polling URL and method for an LRO tracker on each iteration, favoring the Azure-AsyncOperation header. - -## v10.15.2 - -### Bug Fixes - -- Use fmt.Fprint when printing request/response so that any escape sequences aren't treated as format specifiers. - -## v10.15.1 - -### Bug Fixes - -- If an LRO API returns a `Failed` provisioning state in the initial response return an error at that point so the caller doesn't have to poll. -- For failed LROs without an OData v4 error include the response body in the error's `AdditionalInfo` field to aid in diagnosing the failure. - -## v10.15.0 - -### New Features - -- Add initial support for request/response logging via setting environment variables. - Setting `AZURE_GO_SDK_LOG_LEVEL` to `LogInfo` will log request/response - without their bodies. To include the bodies set the log level to `LogDebug`. - By default the logger writes to strerr, however it can also write to stdout or a file - if specified in `AZURE_GO_SDK_LOG_FILE`. Note that if the specified file - already exists it will be truncated. - IMPORTANT: by default the logger will redact the Authorization and Ocp-Apim-Subscription-Key - headers. Any other secrets will _not_ be redacted. - -## v10.14.0 - -### New Features - -- Added package version that contains version constants and user-agent data. - -### Bug Fixes - -- Add the user-agent to token requests. - -## v10.13.0 - -- Added support for additionalInfo in ServiceError type. - -## v10.12.0 - -### New Features - -- Added field ServicePrincipalToken.MaxMSIRefreshAttempts to configure the maximun number of attempts to refresh an MSI token. - -## v10.11.4 - -### Bug Fixes - -- If an LRO returns http.StatusOK on the initial response with no async headers return the response body from Future.GetResult(). -- If there is no "final GET URL" return an error from Future.GetResult(). - -## v10.11.3 - -### Bug Fixes - -- In IMDS retry logic, if we don't receive a response don't retry. - - Renamed the retry function so it's clear it's meant for IMDS only. -- For error response bodies that aren't OData-v4 compliant stick the raw JSON in the ServiceError.Details field so the information isn't lost. - - Also add the raw HTTP response to the DetailedResponse. -- Removed superfluous wrapping of response error in azure.DoRetryWithRegistration(). - -## v10.11.2 - -### Bug Fixes - -- Validation for integers handles int and int64 types. - -## v10.11.1 - -### Bug Fixes - -- Adding User information to authorization config as parsed from CLI cache. - -## v10.11.0 - -### New Features - -- Added NewServicePrincipalTokenFromManualTokenSecret for creating a new SPT using a manual token and secret -- Added method ServicePrincipalToken.MarshalTokenJSON() to marshall the inner Token - -## v10.10.0 - -### New Features - -- Most ServicePrincipalTokens can now be marshalled/unmarshall to/from JSON (ServicePrincipalCertificateSecret and ServicePrincipalMSISecret are not supported). -- Added method ServicePrincipalToken.SetRefreshCallbacks(). - -## v10.9.2 - -### Bug Fixes - -- Refreshing a refresh token obtained from a web app authorization code now works. - -## v10.9.1 - -### Bug Fixes - -- The retry logic for MSI token requests now uses exponential backoff per the guidelines. -- IsTemporaryNetworkError() will return true for errors that don't implement the net.Error interface. - -## v10.9.0 - -### Deprecated Methods - -| Old Method | New Method | -| -------------------------: | :---------------------------: | -| azure.NewFuture() | azure.NewFutureFromResponse() | -| Future.WaitForCompletion() | Future.WaitForCompletionRef() | - -### New Features - -- Added azure.NewFutureFromResponse() for creating a Future from the initial response from an async operation. -- Added Future.GetResult() for making the final GET call to retrieve the result from an async operation. - -### Bug Fixes - -- Some futures failed to return their results, this should now be fixed. - -## v10.8.2 - -### Bug Fixes - -- Add nil-gaurd to token retry logic. - -## v10.8.1 - -### Bug Fixes - -- Return a TokenRefreshError if the sender fails on the initial request. -- Don't retry on non-temporary network errors. - -## v10.8.0 - -- Added NewAuthorizerFromEnvironmentWithResource() helper function. - -## v10.7.0 - -### New Features - -- Added \*WithContext() methods to ADAL token refresh operations. - -## v10.6.2 - -- Fixed a bug on device authentication. - -## v10.6.1 - -- Added retries to MSI token get request. - -## v10.6.0 - -- Changed MSI token implementation. Now, the token endpoint is the IMDS endpoint. - -## v10.5.1 - -### Bug Fixes - -- `DeviceFlowConfig.Authorizer()` now prints the device code message when running `go test`. `-v` flag is required. - -## v10.5.0 - -### New Features - -- Added NewPollingRequestWithContext() for use with polling asynchronous operations. - -### Bug Fixes - -- Make retry logic use the request's context instead of the deprecated Cancel object. - -## v10.4.0 - -### New Features - -- Added helper for parsing Azure Resource ID's. -- Added deprecation message to utils.GetEnvVarOrExit() - -## v10.3.0 - -### New Features - -- Added EnvironmentFromURL method to load an Environment from a given URL. This function is particularly useful in the private and hybrid Cloud model, where one may define their own endpoints -- Added TokenAudience endpoint to Environment structure. This is useful in private and hybrid cloud models where TokenAudience endpoint can be different from ResourceManagerEndpoint - -## v10.2.0 - -### New Features - -- Added endpoints for batch management. - -## v10.1.3 - -### Bug Fixes - -- In Client.Do() invoke WithInspection() last so that it will inspect WithAuthorization(). -- Fixed authorization methods to invoke p.Prepare() first, aligning them with the other preparers. - -## v10.1.2 - -- Corrected comment for auth.NewAuthorizerFromFile() function. - -## v10.1.1 - -- Updated version number to match current release. - -## v10.1.0 - -### New Features - -- Expose the polling URL for futures. - -### Bug Fixes - -- Add validation.NewErrorWithValidationError back to prevent breaking changes (it is deprecated). - -## v10.0.0 - -### New Features - -- Added target and innererror fields to ServiceError to comply with OData v4 spec. -- The Done() method on futures will now return a ServiceError object when available (it used to return a partial value of such errors). -- Added helper methods for obtaining authorizers. -- Expose the polling URL for futures. - -### Bug Fixes - -- Switched from glide to dep for dependency management. -- Fixed unmarshaling of ServiceError for JSON bodies that don't conform to the OData spec. -- Fixed a race condition in token refresh. - -### Breaking Changes - -- The ServiceError.Details field type has been changed to match the OData v4 spec. -- Go v1.7 has been dropped from CI. -- API parameter validation failures will now return a unique error type validation.Error. -- The adal.Token type has been decomposed from adal.ServicePrincipalToken (this was necessary in order to fix the token refresh race). - -## v9.10.0 - -- Fix the Service Bus suffix in Azure public env -- Add Service Bus Endpoint (AAD ResourceURI) for use in [Azure Service Bus RBAC Preview](https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-role-based-access-control) - -## v9.9.0 - -### New Features - -- Added EventGridKeyAuthorizer for key authorization with event grid topics. - -### Bug Fixes - -- Fixed race condition when auto-refreshing service principal tokens. - -## v9.8.1 - -### Bug Fixes - -- Added http.StatusNoContent (204) to the list of expected status codes for long-running operations. -- Updated runtime version info so it's current. - -## v9.8.0 - -### New Features - -- Added type azure.AsyncOpIncompleteError to be returned from a future's Result() method when the operation has not completed. - -## v9.7.1 - -### Bug Fixes - -- Use correct AAD and Graph endpoints for US Gov environment. - -## v9.7.0 - -### New Features - -- Added support for application/octet-stream MIME types. - -## v9.6.1 - -### Bug Fixes - -- Ensure Authorization header is added to request when polling for registration status. - -## v9.6.0 - -### New Features - -- Added support for acquiring tokens via MSI with a user assigned identity. - -## v9.5.3 - -### Bug Fixes - -- Don't remove encoding of existing URL Query parameters when calling autorest.WithQueryParameters. -- Set correct Content Type when using autorest.WithFormData. - -## v9.5.2 - -### Bug Fixes - -- Check for nil \*http.Response before dereferencing it. - -## v9.5.1 - -### Bug Fixes - -- Don't count http.StatusTooManyRequests (429) against the retry cap. -- Use retry logic when SkipResourceProviderRegistration is set to true. - -## v9.5.0 - -### New Features - -- Added support for username + password, API key, authoriazation code and cognitive services authentication. -- Added field SkipResourceProviderRegistration to clients to provide a way to skip auto-registration of RPs. -- Added utility function AsStringSlice() to convert its parameters to a string slice. - -### Bug Fixes - -- When checking for authentication failures look at the error type not the status code as it could vary. - -## v9.4.2 - -### Bug Fixes - -- Validate parameters when creating credentials. -- Don't retry requests if the returned status is a 401 (http.StatusUnauthorized) as it will never succeed. - -## v9.4.1 - -### Bug Fixes - -- Update the AccessTokensPath() to read access tokens path through AZURE_ACCESS_TOKEN_FILE. If this - environment variable is not set, it will fall back to use default path set by Azure CLI. -- Use case-insensitive string comparison for polling states. - -## v9.4.0 - -### New Features - -- Added WaitForCompletion() to Future as a default polling implementation. - -### Bug Fixes - -- Method Future.Done() shouldn't update polling status for unexpected HTTP status codes. - -## v9.3.1 - -### Bug Fixes - -- DoRetryForStatusCodes will retry if sender.Do returns a non-nil error. - -## v9.3.0 - -### New Features - -- Added PollingMethod() to Future so callers know what kind of polling mechanism is used. -- Added azure.ChangeToGet() which transforms an http.Request into a GET (to be used with LROs). - -## v9.2.0 - -### New Features - -- Added support for custom Azure Stack endpoints. -- Added type azure.Future used to track the status of long-running operations. - -### Bug Fixes - -- Preserve the original error in DoRetryWithRegistration when registration fails. - -## v9.1.1 - -- Fixes a bug regarding the cookie jar on `autorest.Client.Sender`. - -## v9.1.0 - -### New Features - -- In cases where there is a non-empty error from the service, attempt to unmarshal it instead of uniformly calling it an "Unknown" error. -- Support for loading Azure CLI Authentication files. -- Automatically register your subscription with the Azure Resource Provider if it hadn't been previously. - -### Bug Fixes - -- RetriableRequest can now tolerate a ReadSeekable body being read but not reset. -- Adding missing Apache Headers - -## v9.0.0 - -> **IMPORTANT:** This release was intially labeled incorrectly as `v8.4.0`. From the time it was released, it should have been marked `v9.0.0` because it contains breaking changes to the MSI packages. We appologize for any inconvenience this causes. - -Adding MSI Endpoint Support and CLI token rehydration. - -## v8.3.1 - -Pick up bug fix in adal for MSI support. - -## v8.3.0 - -Updates to Error string formats for clarity. Also, adding a copy of the http.Response to errors for an improved debugging experience. - -## v8.2.0 - -### New Features - -- Add support for bearer authentication callbacks -- Support 429 response codes that include "Retry-After" header -- Support validation constraint "Pattern" for map keys - -### Bug Fixes - -- Make RetriableRequest work with multiple versions of Go - -## v8.1.1 - -Updates the RetriableRequest to take advantage of GetBody() added in Go 1.8. - -## v8.1.0 - -Adds RetriableRequest type for more efficient handling of retrying HTTP requests. - -## v8.0.0 - -ADAL refactored into its own package. -Support for UNIX time. - -## v7.3.1 - -- Version Testing now removed from production bits that are shipped with the library. - -## v7.3.0 - -- Exposing new `RespondDecorator`, `ByDiscardingBody`. This allows operations - to acknowledge that they do not need either the entire or a trailing portion - of accepts response body. In doing so, Go's http library can reuse HTTP - connections more readily. -- Adding `PrepareDecorator` to target custom BaseURLs. -- Adding ACR suffix to public cloud environment. -- Updating Glide dependencies. - -## v7.2.5 - -- Fixed the Active Directory endpoint for the China cloud. -- Removes UTF-8 BOM if present in response payload. -- Added telemetry. - -## v7.2.3 - -- Fixing bug in calls to `DelayForBackoff` that caused doubling of delay - duration. - -## v7.2.2 - -- autorest/azure: added ASM and ARM VM DNS suffixes. - -## v7.2.1 - -- fixed parsing of UTC times that are not RFC3339 conformant. - -## v7.2.0 - -- autorest/validation: Reformat validation error for better error message. - -## v7.1.0 - -- preparer: Added support for multipart formdata - WithMultiPartFormdata() -- preparer: Added support for sending file in request body - WithFile -- client: Added RetryDuration parameter. -- autorest/validation: new package for validation code for Azure Go SDK. - -## v7.0.7 - -- Add trailing / to endpoint -- azure: add EnvironmentFromName - -## v7.0.6 - -- Add retry logic for 408, 500, 502, 503 and 504 status codes. -- Change url path and query encoding logic. -- Fix DelayForBackoff for proper exponential delay. -- Add CookieJar in Client. - -## v7.0.5 - -- Add check to start polling only when status is in [200,201,202]. -- Refactoring for unchecked errors. -- azure/persist changes. -- Fix 'file in use' issue in renewing token in deviceflow. -- Store header RetryAfter for subsequent requests in polling. -- Add attribute details in service error. - -## v7.0.4 - -- Better error messages for long running operation failures - -## v7.0.3 - -- Corrected DoPollForAsynchronous to properly handle the initial response - -## v7.0.2 - -- Corrected DoPollForAsynchronous to continue using the polling method first discovered - -## v7.0.1 - -- Fixed empty JSON input error in ByUnmarshallingJSON -- Fixed polling support for GET calls -- Changed format name from TimeRfc1123 to TimeRFC1123 - -## v7.0.0 - -- Added ByCopying responder with supporting TeeReadCloser -- Rewrote Azure asynchronous handling -- Reverted to only unmarshalling JSON -- Corrected handling of RFC3339 time strings and added support for Rfc1123 time format - -The `json.Decoder` does not catch bad data as thoroughly as `json.Unmarshal`. Since -`encoding/json` successfully deserializes all core types, and extended types normally provide -their custom JSON serialization handlers, the code has been reverted back to using -`json.Unmarshal`. The original change to use `json.Decode` was made to reduce duplicate -code; there is no loss of function, and there is a gain in accuracy, by reverting. - -Additionally, Azure services indicate requests to be polled by multiple means. The existing code -only checked for one of those (that is, the presence of the `Azure-AsyncOperation` header). -The new code correctly covers all cases and aligns with the other Azure SDKs. - -## v6.1.0 - -- Introduced `date.ByUnmarshallingJSONDate` and `date.ByUnmarshallingJSONTime` to enable JSON encoded values. - -## v6.0.0 - -- Completely reworked the handling of polled and asynchronous requests -- Removed unnecessary routines -- Reworked `mocks.Sender` to replay a series of `http.Response` objects -- Added `PrepareDecorators` for primitive types (e.g., bool, int32) - -Handling polled and asynchronous requests is no longer part of `Client#Send`. Instead new -`SendDecorators` implement different styles of polled behavior. See`autorest.DoPollForStatusCodes` -and `azure.DoPollForAsynchronous` for examples. - -## v5.0.0 - -- Added new RespondDecorators unmarshalling primitive types -- Corrected application of inspection and authorization PrependDecorators - -## v4.0.0 - -- Added support for Azure long-running operations. -- Added cancelation support to all decorators and functions that may delay. -- Breaking: `DelayForBackoff` now accepts a channel, which may be nil. - -## v3.1.0 - -- Add support for OAuth Device Flow authorization. -- Add support for ServicePrincipalTokens that are backed by an existing token, rather than other secret material. -- Add helpers for persisting and restoring Tokens. -- Increased code coverage in the github.com/Azure/autorest/azure package - -## v3.0.0 - -- Breaking: `NewErrorWithError` no longer takes `statusCode int`. -- Breaking: `NewErrorWithStatusCode` is replaced with `NewErrorWithResponse`. -- Breaking: `Client#Send()` no longer takes `codes ...int` argument. -- Add: XML unmarshaling support with `ByUnmarshallingXML()` -- Stopped vending dependencies locally and switched to [Glide](https://github.com/Masterminds/glide). - Applications using this library should either use Glide or vendor dependencies locally some other way. -- Add: `azure.WithErrorUnlessStatusCode()` decorator to handle Azure errors. -- Fix: use `net/http.DefaultClient` as base client. -- Fix: Missing inspection for polling responses added. -- Add: CopyAndDecode helpers. -- Improved `./autorest/to` with `[]string` helpers. -- Removed golint suppressions in .travis.yml. - -## v2.1.0 - -- Added `StatusCode` to `Error` for more easily obtaining the HTTP Reponse StatusCode (if any) - -## v2.0.0 - -- Changed `to.StringMapPtr` method signature to return a pointer -- Changed `ServicePrincipalCertificateSecret` and `NewServicePrincipalTokenFromCertificate` to support generic certificate and private keys - -## v1.0.0 - -- Added Logging inspectors to trace http.Request / Response -- Added support for User-Agent header -- Changed WithHeader PrepareDecorator to use set vs. add -- Added JSON to error when unmarshalling fails -- Added Client#Send method -- Corrected case of "Azure" in package paths -- Added "to" helpers, Azure helpers, and improved ease-of-use -- Corrected golint issues - -## v1.0.1 - -- Added CHANGELOG.md - -## v1.1.0 - -- Added mechanism to retrieve a ServicePrincipalToken using a certificate-signed JWT -- Added an example of creating a certificate-based ServicePrincipal and retrieving an OAuth token using the certificate - -## v1.1.1 - -- Introduce godeps and vendor dependencies introduced in v1.1.1 diff --git a/vendor/github.com/Azure/go-autorest/GNUmakefile b/vendor/github.com/Azure/go-autorest/GNUmakefile deleted file mode 100644 index a434e73a..00000000 --- a/vendor/github.com/Azure/go-autorest/GNUmakefile +++ /dev/null @@ -1,23 +0,0 @@ -DIR?=./autorest/ - -default: build - -build: fmt - go install $(DIR) - -test: - go test $(DIR) || exit 1 - -vet: - @echo "go vet ." - @go vet $(DIR)... ; if [ $$? -eq 1 ]; then \ - echo ""; \ - echo "Vet found suspicious constructs. Please check the reported constructs"; \ - echo "and fix them if necessary before submitting the code for review."; \ - exit 1; \ - fi - -fmt: - gofmt -w $(DIR) - -.PHONY: build test vet fmt diff --git a/vendor/github.com/Azure/go-autorest/Gopkg.lock b/vendor/github.com/Azure/go-autorest/Gopkg.lock deleted file mode 100644 index dc6e3e63..00000000 --- a/vendor/github.com/Azure/go-autorest/Gopkg.lock +++ /dev/null @@ -1,324 +0,0 @@ -# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. - - -[[projects]] - digest = "1:892e39e5c083d0943f1e80ab8351690f183c6a5ab24e1d280adcad424c26255e" - name = "contrib.go.opencensus.io/exporter/ocagent" - packages = ["."] - pruneopts = "UT" - revision = "a8a6f458bbc1d5042322ad1f9b65eeb0b69be9ea" - version = "v0.6.0" - -[[projects]] - digest = "1:8f5acd4d4462b5136af644d25101f0968a7a94ee90fcb2059cec5b7cc42e0b20" - name = "github.com/census-instrumentation/opencensus-proto" - packages = [ - "gen-go/agent/common/v1", - "gen-go/agent/metrics/v1", - "gen-go/agent/trace/v1", - "gen-go/metrics/v1", - "gen-go/resource/v1", - "gen-go/trace/v1", - ] - pruneopts = "UT" - revision = "d89fa54de508111353cb0b06403c00569be780d8" - version = "v0.2.1" - -[[projects]] - digest = "1:ffe9824d294da03b391f44e1ae8281281b4afc1bdaa9588c9097785e3af10cec" - name = "github.com/davecgh/go-spew" - packages = ["spew"] - pruneopts = "UT" - revision = "8991bc29aa16c548c550c7ff78260e27b9ab7c73" - version = "v1.1.1" - -[[projects]] - digest = "1:76dc72490af7174349349838f2fe118996381b31ea83243812a97e5a0fd5ed55" - name = "github.com/dgrijalva/jwt-go" - packages = ["."] - pruneopts = "UT" - revision = "06ea1031745cb8b3dab3f6a236daf2b0aa468b7e" - version = "v3.2.0" - -[[projects]] - digest = "1:cf0d2e435fd4ce45b789e93ef24b5f08e86be0e9807a16beb3694e2d8c9af965" - name = "github.com/dimchansky/utfbom" - packages = ["."] - pruneopts = "UT" - revision = "d2133a1ce379ef6fa992b0514a77146c60db9d1c" - version = "v1.1.0" - -[[projects]] - branch = "master" - digest = "1:b7cb6054d3dff43b38ad2e92492f220f57ae6087ee797dca298139776749ace8" - name = "github.com/golang/groupcache" - packages = ["lru"] - pruneopts = "UT" - revision = "611e8accdfc92c4187d399e95ce826046d4c8d73" - -[[projects]] - digest = "1:e3839df32927e8d3403cd5aa7253d966e8ff80fc8f10e2e35d146461cd83fcfa" - name = "github.com/golang/protobuf" - packages = [ - "descriptor", - "jsonpb", - "proto", - "protoc-gen-go/descriptor", - "ptypes", - "ptypes/any", - "ptypes/duration", - "ptypes/struct", - "ptypes/timestamp", - "ptypes/wrappers", - ] - pruneopts = "UT" - revision = "6c65a5562fc06764971b7c5d05c76c75e84bdbf7" - version = "v1.3.2" - -[[projects]] - digest = "1:c560cd79300fac84f124b96225181a637a70b60155919a3c36db50b7cca6b806" - name = "github.com/grpc-ecosystem/grpc-gateway" - packages = [ - "internal", - "runtime", - "utilities", - ] - pruneopts = "UT" - revision = "f7120437bb4f6c71f7f5076ad65a45310de2c009" - version = "v1.12.1" - -[[projects]] - digest = "1:5d231480e1c64a726869bc4142d270184c419749d34f167646baa21008eb0a79" - name = "github.com/mitchellh/go-homedir" - packages = ["."] - pruneopts = "UT" - revision = "af06845cf3004701891bf4fdb884bfe4920b3727" - version = "v1.1.0" - -[[projects]] - digest = "1:0028cb19b2e4c3112225cd871870f2d9cf49b9b4276531f03438a88e94be86fe" - name = "github.com/pmezard/go-difflib" - packages = ["difflib"] - pruneopts = "UT" - revision = "792786c7400a136282c1664665ae0a8db921c6c2" - version = "v1.0.0" - -[[projects]] - digest = "1:99d32780e5238c2621fff621123997c3e3cca96db8be13179013aea77dfab551" - name = "github.com/stretchr/testify" - packages = [ - "assert", - "require", - ] - pruneopts = "UT" - revision = "221dbe5ed46703ee255b1da0dec05086f5035f62" - version = "v1.4.0" - -[[projects]] - digest = "1:7c5e00383399fe13de0b4b65c9fdde16275407ce8ac02d867eafeaa916edcc71" - name = "go.opencensus.io" - packages = [ - ".", - "internal", - "internal/tagencoding", - "metric/metricdata", - "metric/metricproducer", - "plugin/ocgrpc", - "plugin/ochttp", - "plugin/ochttp/propagation/b3", - "plugin/ochttp/propagation/tracecontext", - "resource", - "stats", - "stats/internal", - "stats/view", - "tag", - "trace", - "trace/internal", - "trace/propagation", - "trace/tracestate", - ] - pruneopts = "UT" - revision = "aad2c527c5defcf89b5afab7f37274304195a6b2" - version = "v0.22.2" - -[[projects]] - branch = "master" - digest = "1:f604f5e2ee721b6757d962dfe7bab4f28aae50c456e39cfb2f3819762a44a6ae" - name = "golang.org/x/crypto" - packages = [ - "pkcs12", - "pkcs12/internal/rc2", - ] - pruneopts = "UT" - revision = "e9b2fee46413994441b28dfca259d911d963dfed" - -[[projects]] - branch = "master" - digest = "1:334b27eac455cb6567ea28cd424230b07b1a64334a2f861a8075ac26ce10af43" - name = "golang.org/x/lint" - packages = [ - ".", - "golint", - ] - pruneopts = "UT" - revision = "fdd1cda4f05fd1fd86124f0ef9ce31a0b72c8448" - -[[projects]] - branch = "master" - digest = "1:257a75d024975428ab9192bfc334c3490882f8cb21322ea5784ca8eca000a910" - name = "golang.org/x/net" - packages = [ - "http/httpguts", - "http2", - "http2/hpack", - "idna", - "internal/timeseries", - "trace", - ] - pruneopts = "UT" - revision = "1ddd1de85cb0337b623b740a609d35817d516a8d" - -[[projects]] - branch = "master" - digest = "1:382bb5a7fb4034db3b6a2d19e5a4a6bcf52f4750530603c01ca18a172fa3089b" - name = "golang.org/x/sync" - packages = ["semaphore"] - pruneopts = "UT" - revision = "cd5d95a43a6e21273425c7ae415d3df9ea832eeb" - -[[projects]] - branch = "master" - digest = "1:4da420ceda5f68e8d748aa2169d0ed44ffadb1bbd6537cf778a49563104189b8" - name = "golang.org/x/sys" - packages = ["unix"] - pruneopts = "UT" - revision = "ce4227a45e2eb77e5c847278dcc6a626742e2945" - -[[projects]] - digest = "1:8d8faad6b12a3a4c819a3f9618cb6ee1fa1cfc33253abeeea8b55336721e3405" - name = "golang.org/x/text" - packages = [ - "collate", - "collate/build", - "internal/colltab", - "internal/gen", - "internal/language", - "internal/language/compact", - "internal/tag", - "internal/triegen", - "internal/ucd", - "language", - "secure/bidirule", - "transform", - "unicode/bidi", - "unicode/cldr", - "unicode/norm", - "unicode/rangetable", - ] - pruneopts = "UT" - revision = "342b2e1fbaa52c93f31447ad2c6abc048c63e475" - version = "v0.3.2" - -[[projects]] - branch = "master" - digest = "1:4eb5ea8395fb60212dd58b92c9db80bab59d5e99c7435f9a6a0a528c373b60e7" - name = "golang.org/x/tools" - packages = [ - "go/ast/astutil", - "go/gcexportdata", - "go/internal/gcimporter", - "go/types/typeutil", - ] - pruneopts = "UT" - revision = "259af5ff87bdcd4abf2ecda8edc3f13f04f26a42" - -[[projects]] - digest = "1:964bb30febc27fabfbec4759fa530c6ec35e77a7c85fed90b9317ea39a054877" - name = "google.golang.org/api" - packages = ["support/bundler"] - pruneopts = "UT" - revision = "8a410c21381766a810817fd6200fce8838ecb277" - version = "v0.14.0" - -[[projects]] - branch = "master" - digest = "1:a8d5c2c6e746b3485e36908ab2a9e3d77b86b81f8156d88403c7d2b462431dfd" - name = "google.golang.org/genproto" - packages = [ - "googleapis/api/httpbody", - "googleapis/rpc/status", - "protobuf/field_mask", - ] - pruneopts = "UT" - revision = "51378566eb590fa106d1025ea12835a4416dda84" - -[[projects]] - digest = "1:b59ce3ddb11daeeccccc9cb3183b58ebf8e9a779f1c853308cd91612e817a301" - name = "google.golang.org/grpc" - packages = [ - ".", - "backoff", - "balancer", - "balancer/base", - "balancer/roundrobin", - "binarylog/grpc_binarylog_v1", - "codes", - "connectivity", - "credentials", - "credentials/internal", - "encoding", - "encoding/proto", - "grpclog", - "internal", - "internal/backoff", - "internal/balancerload", - "internal/binarylog", - "internal/buffer", - "internal/channelz", - "internal/envconfig", - "internal/grpcrand", - "internal/grpcsync", - "internal/resolver/dns", - "internal/resolver/passthrough", - "internal/syscall", - "internal/transport", - "keepalive", - "metadata", - "naming", - "peer", - "resolver", - "serviceconfig", - "stats", - "status", - "tap", - ] - pruneopts = "UT" - revision = "1a3960e4bd028ac0cec0a2afd27d7d8e67c11514" - version = "v1.25.1" - -[[projects]] - digest = "1:b75b3deb2bce8bc079e16bb2aecfe01eb80098f5650f9e93e5643ca8b7b73737" - name = "gopkg.in/yaml.v2" - packages = ["."] - pruneopts = "UT" - revision = "1f64d6156d11335c3f22d9330b0ad14fc1e789ce" - version = "v2.2.7" - -[solve-meta] - analyzer-name = "dep" - analyzer-version = 1 - input-imports = [ - "contrib.go.opencensus.io/exporter/ocagent", - "github.com/dgrijalva/jwt-go", - "github.com/dimchansky/utfbom", - "github.com/mitchellh/go-homedir", - "github.com/stretchr/testify/require", - "go.opencensus.io/plugin/ochttp", - "go.opencensus.io/plugin/ochttp/propagation/tracecontext", - "go.opencensus.io/stats/view", - "go.opencensus.io/trace", - "golang.org/x/crypto/pkcs12", - "golang.org/x/lint/golint", - ] - solver-name = "gps-cdcl" - solver-version = 1 diff --git a/vendor/github.com/Azure/go-autorest/Gopkg.toml b/vendor/github.com/Azure/go-autorest/Gopkg.toml deleted file mode 100644 index 1fc28659..00000000 --- a/vendor/github.com/Azure/go-autorest/Gopkg.toml +++ /dev/null @@ -1,59 +0,0 @@ -# Gopkg.toml example -# -# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html -# for detailed Gopkg.toml documentation. -# -# required = ["github.com/user/thing/cmd/thing"] -# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] -# -# [[constraint]] -# name = "github.com/user/project" -# version = "1.0.0" -# -# [[constraint]] -# name = "github.com/user/project2" -# branch = "dev" -# source = "github.com/myfork/project2" -# -# [[override]] -# name = "github.com/x/y" -# version = "2.4.0" -# -# [prune] -# non-go = false -# go-tests = true -# unused-packages = true - -required = ["golang.org/x/lint/golint"] - -[prune] - go-tests = true - unused-packages = true - -[[constraint]] - name = "contrib.go.opencensus.io/exporter/ocagent" - version = "0.6.0" - -[[constraint]] - name = "github.com/dgrijalva/jwt-go" - version = "3.2.0" - -[[constraint]] - name = "github.com/dimchansky/utfbom" - version = "1.1.0" - -[[constraint]] - name = "github.com/mitchellh/go-homedir" - version = "1.1.0" - -[[constraint]] - name = "github.com/stretchr/testify" - version = "1.3.0" - -[[constraint]] - name = "go.opencensus.io" - version = "0.22.0" - -[[constraint]] - branch = "master" - name = "golang.org/x/crypto" diff --git a/vendor/github.com/Azure/go-autorest/LICENSE b/vendor/github.com/Azure/go-autorest/LICENSE deleted file mode 100644 index b9d6a27e..00000000 --- a/vendor/github.com/Azure/go-autorest/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2015 Microsoft Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/Azure/go-autorest/README.md b/vendor/github.com/Azure/go-autorest/README.md deleted file mode 100644 index de1e19a4..00000000 --- a/vendor/github.com/Azure/go-autorest/README.md +++ /dev/null @@ -1,165 +0,0 @@ -# go-autorest - -[![GoDoc](https://godoc.org/github.com/Azure/go-autorest/autorest?status.png)](https://godoc.org/github.com/Azure/go-autorest/autorest) -[![Build Status](https://dev.azure.com/azure-sdk/public/_apis/build/status/go/Azure.go-autorest?branchName=master)](https://dev.azure.com/azure-sdk/public/_build/latest?definitionId=625&branchName=master) -[![Go Report Card](https://goreportcard.com/badge/Azure/go-autorest)](https://goreportcard.com/report/Azure/go-autorest) - -Package go-autorest provides an HTTP request client for use with [Autorest](https://github.com/Azure/autorest.go)-generated API client packages. - -An authentication client tested with Azure Active Directory (AAD) is also -provided in this repo in the package -`github.com/Azure/go-autorest/autorest/adal`. Despite its name, this package -is maintained only as part of the Azure Go SDK and is not related to other -"ADAL" libraries in [github.com/AzureAD](https://github.com/AzureAD). - -## Overview - -Package go-autorest implements an HTTP request pipeline suitable for use across -multiple goroutines and provides the shared routines used by packages generated -by [Autorest](https://github.com/Azure/autorest.go). - -The package breaks sending and responding to HTTP requests into three phases: Preparing, Sending, -and Responding. A typical pattern is: - -```go - req, err := Prepare(&http.Request{}, - token.WithAuthorization()) - - resp, err := Send(req, - WithLogging(logger), - DoErrorIfStatusCode(http.StatusInternalServerError), - DoCloseIfError(), - DoRetryForAttempts(5, time.Second)) - - err = Respond(resp, - ByDiscardingBody(), - ByClosing()) -``` - -Each phase relies on decorators to modify and / or manage processing. Decorators may first modify -and then pass the data along, pass the data first and then modify the result, or wrap themselves -around passing the data (such as a logger might do). Decorators run in the order provided. For -example, the following: - -```go - req, err := Prepare(&http.Request{}, - WithBaseURL("https://microsoft.com/"), - WithPath("a"), - WithPath("b"), - WithPath("c")) -``` - -will set the URL to: - -``` - https://microsoft.com/a/b/c -``` - -Preparers and Responders may be shared and re-used (assuming the underlying decorators support -sharing and re-use). Performant use is obtained by creating one or more Preparers and Responders -shared among multiple go-routines, and a single Sender shared among multiple sending go-routines, -all bound together by means of input / output channels. - -Decorators hold their passed state within a closure (such as the path components in the example -above). Be careful to share Preparers and Responders only in a context where such held state -applies. For example, it may not make sense to share a Preparer that applies a query string from a -fixed set of values. Similarly, sharing a Responder that reads the response body into a passed -struct (e.g., `ByUnmarshallingJson`) is likely incorrect. - -Errors raised by autorest objects and methods will conform to the `autorest.Error` interface. - -See the included examples for more detail. For details on the suggested use of this package by -generated clients, see the Client described below. - -## Helpers - -### Handling Swagger Dates - -The Swagger specification (https://swagger.io) that drives AutoRest -(https://github.com/Azure/autorest/) precisely defines two date forms: date and date-time. The -github.com/Azure/go-autorest/autorest/date package provides time.Time derivations to ensure correct -parsing and formatting. - -### Handling Empty Values - -In JSON, missing values have different semantics than empty values. This is especially true for -services using the HTTP PATCH verb. The JSON submitted with a PATCH request generally contains -only those values to modify. Missing values are to be left unchanged. Developers, then, require a -means to both specify an empty value and to leave the value out of the submitted JSON. - -The Go JSON package (`encoding/json`) supports the `omitempty` tag. When specified, it omits -empty values from the rendered JSON. Since Go defines default values for all base types (such as "" -for string and 0 for int) and provides no means to mark a value as actually empty, the JSON package -treats default values as meaning empty, omitting them from the rendered JSON. This means that, using -the Go base types encoded through the default JSON package, it is not possible to create JSON to -clear a value at the server. - -The workaround within the Go community is to use pointers to base types in lieu of base types within -structures that map to JSON. For example, instead of a value of type `string`, the workaround uses -`*string`. While this enables distinguishing empty values from those to be unchanged, creating -pointers to a base type (notably constant, in-line values) requires additional variables. This, for -example, - -```go - s := struct { - S *string - }{ S: &"foo" } -``` -fails, while, this - -```go - v := "foo" - s := struct { - S *string - }{ S: &v } -``` -succeeds. - -To ease using pointers, the subpackage `to` contains helpers that convert to and from pointers for -Go base types which have Swagger analogs. It also provides a helper that converts between -`map[string]string` and `map[string]*string`, enabling the JSON to specify that the value -associated with a key should be cleared. With the helpers, the previous example becomes - -```go - s := struct { - S *string - }{ S: to.StringPtr("foo") } -``` - -## Install - -```bash -go get github.com/Azure/go-autorest/autorest -go get github.com/Azure/go-autorest/autorest/azure -go get github.com/Azure/go-autorest/autorest/date -go get github.com/Azure/go-autorest/autorest/to -``` - -### Using with Go Modules -In [v12.0.1](https://github.com/Azure/go-autorest/pull/386), this repository introduced the following modules. - -- autorest/adal -- autorest/azure/auth -- autorest/azure/cli -- autorest/date -- autorest/mocks -- autorest/to -- autorest/validation -- autorest -- logger -- tracing - -Tagging cumulative SDK releases as a whole (e.g. `v12.3.0`) is still enabled to support consumers of this repo that have not yet migrated to modules. - -## License - -See LICENSE file. - ------ - -This project has adopted the [Microsoft Open Source Code of -Conduct](https://opensource.microsoft.com/codeofconduct/). For more information -see the [Code of Conduct -FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact -[opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional -questions or comments. diff --git a/vendor/github.com/Azure/go-autorest/autorest/LICENSE b/vendor/github.com/Azure/go-autorest/autorest/LICENSE deleted file mode 100644 index b9d6a27e..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2015 Microsoft Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/LICENSE b/vendor/github.com/Azure/go-autorest/autorest/adal/LICENSE deleted file mode 100644 index b9d6a27e..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/adal/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2015 Microsoft Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/README.md b/vendor/github.com/Azure/go-autorest/autorest/adal/README.md deleted file mode 100644 index b11eb078..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/adal/README.md +++ /dev/null @@ -1,294 +0,0 @@ -# NOTE: This module will go out of support by March 31, 2023. For authenticating with Azure AD, use module [azidentity](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity) instead. For help migrating from `adal` to `azidentiy` please consult the [migration guide](https://aka.ms/azsdk/go/identity/migration). General information about the retirement of this and other legacy modules can be found [here](https://azure.microsoft.com/updates/support-for-azure-sdk-libraries-that-do-not-conform-to-our-current-azure-sdk-guidelines-will-be-retired-as-of-31-march-2023/). - -# Azure Active Directory authentication for Go - -This is a standalone package for authenticating with Azure Active -Directory from other Go libraries and applications, in particular the [Azure SDK -for Go](https://github.com/Azure/azure-sdk-for-go). - -Note: Despite the package's name it is not related to other "ADAL" libraries -maintained in the [github.com/AzureAD](https://github.com/AzureAD) org. Issues -should be opened in [this repo's](https://github.com/Azure/go-autorest/issues) -or [the SDK's](https://github.com/Azure/azure-sdk-for-go/issues) issue -trackers. - -## Install - -```bash -go get -u github.com/Azure/go-autorest/autorest/adal -``` - -## Usage - -An Active Directory application is required in order to use this library. An application can be registered in the [Azure Portal](https://portal.azure.com/) by following these [guidelines](https://docs.microsoft.com/azure/active-directory/develop/active-directory-integrating-applications) or using the [Azure CLI](https://github.com/Azure/azure-cli). - -### Register an Azure AD Application with secret - - -1. Register a new application with a `secret` credential - - ``` - az ad app create \ - --display-name example-app \ - --homepage https://example-app/home \ - --identifier-uris https://example-app/app \ - --password secret - ``` - -2. Create a service principal using the `Application ID` from previous step - - ``` - az ad sp create --id "Application ID" - ``` - - * Replace `Application ID` with `appId` from step 1. - -### Register an Azure AD Application with certificate - -1. Create a private key - - ``` - openssl genrsa -out "example-app.key" 2048 - ``` - -2. Create the certificate - - ``` - openssl req -new -key "example-app.key" -subj "/CN=example-app" -out "example-app.csr" - openssl x509 -req -in "example-app.csr" -signkey "example-app.key" -out "example-app.crt" -days 10000 - ``` - -3. Create the PKCS12 version of the certificate containing also the private key - - ``` - openssl pkcs12 -export -out "example-app.pfx" -inkey "example-app.key" -in "example-app.crt" -passout pass: - - ``` - -4. Register a new application with the certificate content form `example-app.crt` - - ``` - certificateContents="$(tail -n+2 "example-app.crt" | head -n-1)" - - az ad app create \ - --display-name example-app \ - --homepage https://example-app/home \ - --identifier-uris https://example-app/app \ - --key-usage Verify --end-date 2018-01-01 \ - --key-value "${certificateContents}" - ``` - -5. Create a service principal using the `Application ID` from previous step - - ``` - az ad sp create --id "APPLICATION_ID" - ``` - - * Replace `APPLICATION_ID` with `appId` from step 4. - - -### Grant the necessary permissions - -Azure relies on a Role-Based Access Control (RBAC) model to manage the access to resources at a fine-grained -level. There is a set of [pre-defined roles](https://docs.microsoft.com/azure/active-directory/role-based-access-built-in-roles) -which can be assigned to a service principal of an Azure AD application depending of your needs. - -``` -az role assignment create --assigner "SERVICE_PRINCIPAL_ID" --role "ROLE_NAME" -``` - -* Replace the `SERVICE_PRINCIPAL_ID` with the `appId` from previous step. -* Replace the `ROLE_NAME` with a role name of your choice. - -It is also possible to define custom role definitions. - -``` -az role definition create --role-definition role-definition.json -``` - -* Check [custom roles](https://docs.microsoft.com/azure/active-directory/role-based-access-control-custom-roles) for more details regarding the content of `role-definition.json` file. - - -### Acquire Access Token - -The common configuration used by all flows: - -```Go -const activeDirectoryEndpoint = "https://login.microsoftonline.com/" -tenantID := "TENANT_ID" -oauthConfig, err := adal.NewOAuthConfig(activeDirectoryEndpoint, tenantID) - -applicationID := "APPLICATION_ID" - -callback := func(token adal.Token) error { - // This is called after the token is acquired -} - -// The resource for which the token is acquired -resource := "https://management.core.windows.net/" -``` - -* Replace the `TENANT_ID` with your tenant ID. -* Replace the `APPLICATION_ID` with the value from previous section. - -#### Client Credentials - -```Go -applicationSecret := "APPLICATION_SECRET" - -spt, err := adal.NewServicePrincipalToken( - *oauthConfig, - appliationID, - applicationSecret, - resource, - callbacks...) -if err != nil { - return nil, err -} - -// Acquire a new access token -err = spt.Refresh() -if (err == nil) { - token := spt.Token -} -``` - -* Replace the `APPLICATION_SECRET` with the `password` value from previous section. - -#### Client Certificate - -```Go -certificatePath := "./example-app.pfx" - -certData, err := ioutil.ReadFile(certificatePath) -if err != nil { - return nil, fmt.Errorf("failed to read the certificate file (%s): %v", certificatePath, err) -} - -// Get the certificate and private key from pfx file -certificate, rsaPrivateKey, err := decodePkcs12(certData, "") -if err != nil { - return nil, fmt.Errorf("failed to decode pkcs12 certificate while creating spt: %v", err) -} - -spt, err := adal.NewServicePrincipalTokenFromCertificate( - *oauthConfig, - applicationID, - certificate, - rsaPrivateKey, - resource, - callbacks...) - -// Acquire a new access token -err = spt.Refresh() -if (err == nil) { - token := spt.Token -} -``` - -* Update the certificate path to point to the example-app.pfx file which was created in previous section. - - -#### Device Code - -```Go -oauthClient := &http.Client{} - -// Acquire the device code -deviceCode, err := adal.InitiateDeviceAuth( - oauthClient, - *oauthConfig, - applicationID, - resource) -if err != nil { - return nil, fmt.Errorf("Failed to start device auth flow: %s", err) -} - -// Display the authentication message -fmt.Println(*deviceCode.Message) - -// Wait here until the user is authenticated -token, err := adal.WaitForUserCompletion(oauthClient, deviceCode) -if err != nil { - return nil, fmt.Errorf("Failed to finish device auth flow: %s", err) -} - -spt, err := adal.NewServicePrincipalTokenFromManualToken( - *oauthConfig, - applicationID, - resource, - *token, - callbacks...) - -if (err == nil) { - token := spt.Token -} -``` - -#### Username password authenticate - -```Go -spt, err := adal.NewServicePrincipalTokenFromUsernamePassword( - *oauthConfig, - applicationID, - username, - password, - resource, - callbacks...) - -if (err == nil) { - token := spt.Token -} -``` - -#### Authorization code authenticate - -``` Go -spt, err := adal.NewServicePrincipalTokenFromAuthorizationCode( - *oauthConfig, - applicationID, - clientSecret, - authorizationCode, - redirectURI, - resource, - callbacks...) - -err = spt.Refresh() -if (err == nil) { - token := spt.Token -} -``` - -### Command Line Tool - -A command line tool is available in `cmd/adal.go` that can acquire a token for a given resource. It supports all flows mentioned above. - -``` -adal -h - -Usage of ./adal: - -applicationId string - application id - -certificatePath string - path to pk12/PFC application certificate - -mode string - authentication mode (device, secret, cert, refresh) (default "device") - -resource string - resource for which the token is requested - -secret string - application secret - -tenantId string - tenant id - -tokenCachePath string - location of oath token cache (default "/home/cgc/.adal/accessToken.json") -``` - -Example acquire a token for `https://management.core.windows.net/` using device code flow: - -``` -adal -mode device \ - -applicationId "APPLICATION_ID" \ - -tenantId "TENANT_ID" \ - -resource https://management.core.windows.net/ - -``` diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/config.go b/vendor/github.com/Azure/go-autorest/autorest/adal/config.go deleted file mode 100644 index fa596474..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/adal/config.go +++ /dev/null @@ -1,151 +0,0 @@ -package adal - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import ( - "errors" - "fmt" - "net/url" -) - -const ( - activeDirectoryEndpointTemplate = "%s/oauth2/%s%s" -) - -// OAuthConfig represents the endpoints needed -// in OAuth operations -type OAuthConfig struct { - AuthorityEndpoint url.URL `json:"authorityEndpoint"` - AuthorizeEndpoint url.URL `json:"authorizeEndpoint"` - TokenEndpoint url.URL `json:"tokenEndpoint"` - DeviceCodeEndpoint url.URL `json:"deviceCodeEndpoint"` -} - -// IsZero returns true if the OAuthConfig object is zero-initialized. -func (oac OAuthConfig) IsZero() bool { - return oac == OAuthConfig{} -} - -func validateStringParam(param, name string) error { - if len(param) == 0 { - return fmt.Errorf("parameter '" + name + "' cannot be empty") - } - return nil -} - -// NewOAuthConfig returns an OAuthConfig with tenant specific urls -func NewOAuthConfig(activeDirectoryEndpoint, tenantID string) (*OAuthConfig, error) { - apiVer := "1.0" - return NewOAuthConfigWithAPIVersion(activeDirectoryEndpoint, tenantID, &apiVer) -} - -// NewOAuthConfigWithAPIVersion returns an OAuthConfig with tenant specific urls. -// If apiVersion is not nil the "api-version" query parameter will be appended to the endpoint URLs with the specified value. -func NewOAuthConfigWithAPIVersion(activeDirectoryEndpoint, tenantID string, apiVersion *string) (*OAuthConfig, error) { - if err := validateStringParam(activeDirectoryEndpoint, "activeDirectoryEndpoint"); err != nil { - return nil, err - } - api := "" - // it's legal for tenantID to be empty so don't validate it - if apiVersion != nil { - if err := validateStringParam(*apiVersion, "apiVersion"); err != nil { - return nil, err - } - api = fmt.Sprintf("?api-version=%s", *apiVersion) - } - u, err := url.Parse(activeDirectoryEndpoint) - if err != nil { - return nil, err - } - authorityURL, err := u.Parse(tenantID) - if err != nil { - return nil, err - } - authorizeURL, err := u.Parse(fmt.Sprintf(activeDirectoryEndpointTemplate, tenantID, "authorize", api)) - if err != nil { - return nil, err - } - tokenURL, err := u.Parse(fmt.Sprintf(activeDirectoryEndpointTemplate, tenantID, "token", api)) - if err != nil { - return nil, err - } - deviceCodeURL, err := u.Parse(fmt.Sprintf(activeDirectoryEndpointTemplate, tenantID, "devicecode", api)) - if err != nil { - return nil, err - } - - return &OAuthConfig{ - AuthorityEndpoint: *authorityURL, - AuthorizeEndpoint: *authorizeURL, - TokenEndpoint: *tokenURL, - DeviceCodeEndpoint: *deviceCodeURL, - }, nil -} - -// MultiTenantOAuthConfig provides endpoints for primary and aulixiary tenant IDs. -type MultiTenantOAuthConfig interface { - PrimaryTenant() *OAuthConfig - AuxiliaryTenants() []*OAuthConfig -} - -// OAuthOptions contains optional OAuthConfig creation arguments. -type OAuthOptions struct { - APIVersion string -} - -func (c OAuthOptions) apiVersion() string { - if c.APIVersion != "" { - return fmt.Sprintf("?api-version=%s", c.APIVersion) - } - return "1.0" -} - -// NewMultiTenantOAuthConfig creates an object that support multitenant OAuth configuration. -// See https://docs.microsoft.com/en-us/azure/azure-resource-manager/authenticate-multi-tenant for more information. -func NewMultiTenantOAuthConfig(activeDirectoryEndpoint, primaryTenantID string, auxiliaryTenantIDs []string, options OAuthOptions) (MultiTenantOAuthConfig, error) { - if len(auxiliaryTenantIDs) == 0 || len(auxiliaryTenantIDs) > 3 { - return nil, errors.New("must specify one to three auxiliary tenants") - } - mtCfg := multiTenantOAuthConfig{ - cfgs: make([]*OAuthConfig, len(auxiliaryTenantIDs)+1), - } - apiVer := options.apiVersion() - pri, err := NewOAuthConfigWithAPIVersion(activeDirectoryEndpoint, primaryTenantID, &apiVer) - if err != nil { - return nil, fmt.Errorf("failed to create OAuthConfig for primary tenant: %v", err) - } - mtCfg.cfgs[0] = pri - for i := range auxiliaryTenantIDs { - aux, err := NewOAuthConfig(activeDirectoryEndpoint, auxiliaryTenantIDs[i]) - if err != nil { - return nil, fmt.Errorf("failed to create OAuthConfig for tenant '%s': %v", auxiliaryTenantIDs[i], err) - } - mtCfg.cfgs[i+1] = aux - } - return mtCfg, nil -} - -type multiTenantOAuthConfig struct { - // first config in the slice is the primary tenant - cfgs []*OAuthConfig -} - -func (m multiTenantOAuthConfig) PrimaryTenant() *OAuthConfig { - return m.cfgs[0] -} - -func (m multiTenantOAuthConfig) AuxiliaryTenants() []*OAuthConfig { - return m.cfgs[1:] -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/devicetoken.go b/vendor/github.com/Azure/go-autorest/autorest/adal/devicetoken.go deleted file mode 100644 index 9daa4b58..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/adal/devicetoken.go +++ /dev/null @@ -1,273 +0,0 @@ -package adal - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/* - This file is largely based on rjw57/oauth2device's code, with the follow differences: - * scope -> resource, and only allow a single one - * receive "Message" in the DeviceCode struct and show it to users as the prompt - * azure-xplat-cli has the following behavior that this emulates: - - does not send client_secret during the token exchange - - sends resource again in the token exchange request -*/ - -import ( - "context" - "encoding/json" - "fmt" - "io/ioutil" - "net/http" - "net/url" - "strings" - "time" -) - -const ( - logPrefix = "autorest/adal/devicetoken:" -) - -var ( - // ErrDeviceGeneric represents an unknown error from the token endpoint when using device flow - ErrDeviceGeneric = fmt.Errorf("%s Error while retrieving OAuth token: Unknown Error", logPrefix) - - // ErrDeviceAccessDenied represents an access denied error from the token endpoint when using device flow - ErrDeviceAccessDenied = fmt.Errorf("%s Error while retrieving OAuth token: Access Denied", logPrefix) - - // ErrDeviceAuthorizationPending represents the server waiting on the user to complete the device flow - ErrDeviceAuthorizationPending = fmt.Errorf("%s Error while retrieving OAuth token: Authorization Pending", logPrefix) - - // ErrDeviceCodeExpired represents the server timing out and expiring the code during device flow - ErrDeviceCodeExpired = fmt.Errorf("%s Error while retrieving OAuth token: Code Expired", logPrefix) - - // ErrDeviceSlowDown represents the service telling us we're polling too often during device flow - ErrDeviceSlowDown = fmt.Errorf("%s Error while retrieving OAuth token: Slow Down", logPrefix) - - // ErrDeviceCodeEmpty represents an empty device code from the device endpoint while using device flow - ErrDeviceCodeEmpty = fmt.Errorf("%s Error while retrieving device code: Device Code Empty", logPrefix) - - // ErrOAuthTokenEmpty represents an empty OAuth token from the token endpoint when using device flow - ErrOAuthTokenEmpty = fmt.Errorf("%s Error while retrieving OAuth token: Token Empty", logPrefix) - - errCodeSendingFails = "Error occurred while sending request for Device Authorization Code" - errCodeHandlingFails = "Error occurred while handling response from the Device Endpoint" - errTokenSendingFails = "Error occurred while sending request with device code for a token" - errTokenHandlingFails = "Error occurred while handling response from the Token Endpoint (during device flow)" - errStatusNotOK = "Error HTTP status != 200" -) - -// DeviceCode is the object returned by the device auth endpoint -// It contains information to instruct the user to complete the auth flow -type DeviceCode struct { - DeviceCode *string `json:"device_code,omitempty"` - UserCode *string `json:"user_code,omitempty"` - VerificationURL *string `json:"verification_url,omitempty"` - ExpiresIn *int64 `json:"expires_in,string,omitempty"` - Interval *int64 `json:"interval,string,omitempty"` - - Message *string `json:"message"` // Azure specific - Resource string // store the following, stored when initiating, used when exchanging - OAuthConfig OAuthConfig - ClientID string -} - -// TokenError is the object returned by the token exchange endpoint -// when something is amiss -type TokenError struct { - Error *string `json:"error,omitempty"` - ErrorCodes []int `json:"error_codes,omitempty"` - ErrorDescription *string `json:"error_description,omitempty"` - Timestamp *string `json:"timestamp,omitempty"` - TraceID *string `json:"trace_id,omitempty"` -} - -// DeviceToken is the object return by the token exchange endpoint -// It can either look like a Token or an ErrorToken, so put both here -// and check for presence of "Error" to know if we are in error state -type deviceToken struct { - Token - TokenError -} - -// InitiateDeviceAuth initiates a device auth flow. It returns a DeviceCode -// that can be used with CheckForUserCompletion or WaitForUserCompletion. -// Deprecated: use InitiateDeviceAuthWithContext() instead. -func InitiateDeviceAuth(sender Sender, oauthConfig OAuthConfig, clientID, resource string) (*DeviceCode, error) { - return InitiateDeviceAuthWithContext(context.Background(), sender, oauthConfig, clientID, resource) -} - -// InitiateDeviceAuthWithContext initiates a device auth flow. It returns a DeviceCode -// that can be used with CheckForUserCompletion or WaitForUserCompletion. -func InitiateDeviceAuthWithContext(ctx context.Context, sender Sender, oauthConfig OAuthConfig, clientID, resource string) (*DeviceCode, error) { - v := url.Values{ - "client_id": []string{clientID}, - "resource": []string{resource}, - } - - s := v.Encode() - body := ioutil.NopCloser(strings.NewReader(s)) - - req, err := http.NewRequest(http.MethodPost, oauthConfig.DeviceCodeEndpoint.String(), body) - if err != nil { - return nil, fmt.Errorf("%s %s: %s", logPrefix, errCodeSendingFails, err.Error()) - } - - req.ContentLength = int64(len(s)) - req.Header.Set(contentType, mimeTypeFormPost) - resp, err := sender.Do(req.WithContext(ctx)) - if err != nil { - return nil, fmt.Errorf("%s %s: %s", logPrefix, errCodeSendingFails, err.Error()) - } - defer resp.Body.Close() - - rb, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, fmt.Errorf("%s %s: %s", logPrefix, errCodeHandlingFails, err.Error()) - } - - if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("%s %s: %s", logPrefix, errCodeHandlingFails, errStatusNotOK) - } - - if len(strings.Trim(string(rb), " ")) == 0 { - return nil, ErrDeviceCodeEmpty - } - - var code DeviceCode - err = json.Unmarshal(rb, &code) - if err != nil { - return nil, fmt.Errorf("%s %s: %s", logPrefix, errCodeHandlingFails, err.Error()) - } - - code.ClientID = clientID - code.Resource = resource - code.OAuthConfig = oauthConfig - - return &code, nil -} - -// CheckForUserCompletion takes a DeviceCode and checks with the Azure AD OAuth endpoint -// to see if the device flow has: been completed, timed out, or otherwise failed -// Deprecated: use CheckForUserCompletionWithContext() instead. -func CheckForUserCompletion(sender Sender, code *DeviceCode) (*Token, error) { - return CheckForUserCompletionWithContext(context.Background(), sender, code) -} - -// CheckForUserCompletionWithContext takes a DeviceCode and checks with the Azure AD OAuth endpoint -// to see if the device flow has: been completed, timed out, or otherwise failed -func CheckForUserCompletionWithContext(ctx context.Context, sender Sender, code *DeviceCode) (*Token, error) { - v := url.Values{ - "client_id": []string{code.ClientID}, - "code": []string{*code.DeviceCode}, - "grant_type": []string{OAuthGrantTypeDeviceCode}, - "resource": []string{code.Resource}, - } - - s := v.Encode() - body := ioutil.NopCloser(strings.NewReader(s)) - - req, err := http.NewRequest(http.MethodPost, code.OAuthConfig.TokenEndpoint.String(), body) - if err != nil { - return nil, fmt.Errorf("%s %s: %s", logPrefix, errTokenSendingFails, err.Error()) - } - - req.ContentLength = int64(len(s)) - req.Header.Set(contentType, mimeTypeFormPost) - resp, err := sender.Do(req.WithContext(ctx)) - if err != nil { - return nil, fmt.Errorf("%s %s: %s", logPrefix, errTokenSendingFails, err.Error()) - } - defer resp.Body.Close() - - rb, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, fmt.Errorf("%s %s: %s", logPrefix, errTokenHandlingFails, err.Error()) - } - - if resp.StatusCode != http.StatusOK && len(strings.Trim(string(rb), " ")) == 0 { - return nil, fmt.Errorf("%s %s: %s", logPrefix, errTokenHandlingFails, errStatusNotOK) - } - if len(strings.Trim(string(rb), " ")) == 0 { - return nil, ErrOAuthTokenEmpty - } - - var token deviceToken - err = json.Unmarshal(rb, &token) - if err != nil { - return nil, fmt.Errorf("%s %s: %s", logPrefix, errTokenHandlingFails, err.Error()) - } - - if token.Error == nil { - return &token.Token, nil - } - - switch *token.Error { - case "authorization_pending": - return nil, ErrDeviceAuthorizationPending - case "slow_down": - return nil, ErrDeviceSlowDown - case "access_denied": - return nil, ErrDeviceAccessDenied - case "code_expired": - return nil, ErrDeviceCodeExpired - default: - // return a more meaningful error message if available - if token.ErrorDescription != nil { - return nil, fmt.Errorf("%s %s: %s", logPrefix, *token.Error, *token.ErrorDescription) - } - return nil, ErrDeviceGeneric - } -} - -// WaitForUserCompletion calls CheckForUserCompletion repeatedly until a token is granted or an error state occurs. -// This prevents the user from looping and checking against 'ErrDeviceAuthorizationPending'. -// Deprecated: use WaitForUserCompletionWithContext() instead. -func WaitForUserCompletion(sender Sender, code *DeviceCode) (*Token, error) { - return WaitForUserCompletionWithContext(context.Background(), sender, code) -} - -// WaitForUserCompletionWithContext calls CheckForUserCompletion repeatedly until a token is granted or an error -// state occurs. This prevents the user from looping and checking against 'ErrDeviceAuthorizationPending'. -func WaitForUserCompletionWithContext(ctx context.Context, sender Sender, code *DeviceCode) (*Token, error) { - intervalDuration := time.Duration(*code.Interval) * time.Second - waitDuration := intervalDuration - - for { - token, err := CheckForUserCompletionWithContext(ctx, sender, code) - - if err == nil { - return token, nil - } - - switch err { - case ErrDeviceSlowDown: - waitDuration += waitDuration - case ErrDeviceAuthorizationPending: - // noop - default: // everything else is "fatal" to us - return nil, err - } - - if waitDuration > (intervalDuration * 3) { - return nil, fmt.Errorf("%s Error waiting for user to complete device flow. Server told us to slow_down too much", logPrefix) - } - - select { - case <-time.After(waitDuration): - // noop - case <-ctx.Done(): - return nil, ctx.Err() - } - } -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/go_mod_tidy_hack.go b/vendor/github.com/Azure/go-autorest/autorest/adal/go_mod_tidy_hack.go deleted file mode 100644 index 647a61bb..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/adal/go_mod_tidy_hack.go +++ /dev/null @@ -1,25 +0,0 @@ -//go:build modhack -// +build modhack - -package adal - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// This file, and the github.com/Azure/go-autorest import, won't actually become part of -// the resultant binary. - -// Necessary for safely adding multi-module repo. -// See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository -import _ "github.com/Azure/go-autorest" diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/persist.go b/vendor/github.com/Azure/go-autorest/autorest/adal/persist.go deleted file mode 100644 index 2a974a39..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/adal/persist.go +++ /dev/null @@ -1,135 +0,0 @@ -package adal - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import ( - "crypto/rsa" - "crypto/x509" - "encoding/json" - "errors" - "fmt" - "io/ioutil" - "os" - "path/filepath" - - "golang.org/x/crypto/pkcs12" -) - -var ( - // ErrMissingCertificate is returned when no local certificate is found in the provided PFX data. - ErrMissingCertificate = errors.New("adal: certificate missing") - - // ErrMissingPrivateKey is returned when no private key is found in the provided PFX data. - ErrMissingPrivateKey = errors.New("adal: private key missing") -) - -// LoadToken restores a Token object from a file located at 'path'. -func LoadToken(path string) (*Token, error) { - file, err := os.Open(path) - if err != nil { - return nil, fmt.Errorf("failed to open file (%s) while loading token: %v", path, err) - } - defer file.Close() - - var token Token - - dec := json.NewDecoder(file) - if err = dec.Decode(&token); err != nil { - return nil, fmt.Errorf("failed to decode contents of file (%s) into Token representation: %v", path, err) - } - return &token, nil -} - -// SaveToken persists an oauth token at the given location on disk. -// It moves the new file into place so it can safely be used to replace an existing file -// that maybe accessed by multiple processes. -func SaveToken(path string, mode os.FileMode, token Token) error { - dir := filepath.Dir(path) - err := os.MkdirAll(dir, os.ModePerm) - if err != nil { - return fmt.Errorf("failed to create directory (%s) to store token in: %v", dir, err) - } - - newFile, err := ioutil.TempFile(dir, "token") - if err != nil { - return fmt.Errorf("failed to create the temp file to write the token: %v", err) - } - tempPath := newFile.Name() - - if err := json.NewEncoder(newFile).Encode(token); err != nil { - return fmt.Errorf("failed to encode token to file (%s) while saving token: %v", tempPath, err) - } - if err := newFile.Close(); err != nil { - return fmt.Errorf("failed to close temp file %s: %v", tempPath, err) - } - - // Atomic replace to avoid multi-writer file corruptions - if err := os.Rename(tempPath, path); err != nil { - return fmt.Errorf("failed to move temporary token to desired output location. src=%s dst=%s: %v", tempPath, path, err) - } - if err := os.Chmod(path, mode); err != nil { - return fmt.Errorf("failed to chmod the token file %s: %v", path, err) - } - return nil -} - -// DecodePfxCertificateData extracts the x509 certificate and RSA private key from the provided PFX data. -// The PFX data must contain a private key along with a certificate whose public key matches that of the -// private key or an error is returned. -// If the private key is not password protected pass the empty string for password. -func DecodePfxCertificateData(pfxData []byte, password string) (*x509.Certificate, *rsa.PrivateKey, error) { - blocks, err := pkcs12.ToPEM(pfxData, password) - if err != nil { - return nil, nil, err - } - // first extract the private key - var priv *rsa.PrivateKey - for _, block := range blocks { - if block.Type == "PRIVATE KEY" { - priv, err = x509.ParsePKCS1PrivateKey(block.Bytes) - if err != nil { - return nil, nil, err - } - break - } - } - if priv == nil { - return nil, nil, ErrMissingPrivateKey - } - // now find the certificate with the matching public key of our private key - var cert *x509.Certificate - for _, block := range blocks { - if block.Type == "CERTIFICATE" { - pcert, err := x509.ParseCertificate(block.Bytes) - if err != nil { - return nil, nil, err - } - certKey, ok := pcert.PublicKey.(*rsa.PublicKey) - if !ok { - // keep looking - continue - } - if priv.E == certKey.E && priv.N.Cmp(certKey.N) == 0 { - // found a match - cert = pcert - break - } - } - } - if cert == nil { - return nil, nil, ErrMissingCertificate - } - return cert, priv, nil -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/sender.go b/vendor/github.com/Azure/go-autorest/autorest/adal/sender.go deleted file mode 100644 index eb649bce..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/adal/sender.go +++ /dev/null @@ -1,101 +0,0 @@ -package adal - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import ( - "crypto/tls" - "net" - "net/http" - "net/http/cookiejar" - "sync" - "time" - - "github.com/Azure/go-autorest/tracing" -) - -const ( - contentType = "Content-Type" - mimeTypeFormPost = "application/x-www-form-urlencoded" -) - -// DO NOT ACCESS THIS DIRECTLY. go through sender() -var defaultSender Sender -var defaultSenderInit = &sync.Once{} - -// Sender is the interface that wraps the Do method to send HTTP requests. -// -// The standard http.Client conforms to this interface. -type Sender interface { - Do(*http.Request) (*http.Response, error) -} - -// SenderFunc is a method that implements the Sender interface. -type SenderFunc func(*http.Request) (*http.Response, error) - -// Do implements the Sender interface on SenderFunc. -func (sf SenderFunc) Do(r *http.Request) (*http.Response, error) { - return sf(r) -} - -// SendDecorator takes and possibly decorates, by wrapping, a Sender. Decorators may affect the -// http.Request and pass it along or, first, pass the http.Request along then react to the -// http.Response result. -type SendDecorator func(Sender) Sender - -// CreateSender creates, decorates, and returns, as a Sender, the default http.Client. -func CreateSender(decorators ...SendDecorator) Sender { - return DecorateSender(sender(), decorators...) -} - -// DecorateSender accepts a Sender and a, possibly empty, set of SendDecorators, which is applies to -// the Sender. Decorators are applied in the order received, but their affect upon the request -// depends on whether they are a pre-decorator (change the http.Request and then pass it along) or a -// post-decorator (pass the http.Request along and react to the results in http.Response). -func DecorateSender(s Sender, decorators ...SendDecorator) Sender { - for _, decorate := range decorators { - s = decorate(s) - } - return s -} - -func sender() Sender { - // note that we can't init defaultSender in init() since it will - // execute before calling code has had a chance to enable tracing - defaultSenderInit.Do(func() { - // copied from http.DefaultTransport with a TLS minimum version. - transport := &http.Transport{ - Proxy: http.ProxyFromEnvironment, - DialContext: (&net.Dialer{ - Timeout: 30 * time.Second, - KeepAlive: 30 * time.Second, - }).DialContext, - ForceAttemptHTTP2: true, - MaxIdleConns: 100, - IdleConnTimeout: 90 * time.Second, - TLSHandshakeTimeout: 10 * time.Second, - ExpectContinueTimeout: 1 * time.Second, - TLSClientConfig: &tls.Config{ - MinVersion: tls.VersionTLS12, - }, - } - var roundTripper http.RoundTripper = transport - if tracing.IsEnabled() { - roundTripper = tracing.NewTransport(transport) - } - j, _ := cookiejar.New(nil) - defaultSender = &http.Client{Jar: j, Transport: roundTripper} - }) - return defaultSender -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/token.go b/vendor/github.com/Azure/go-autorest/autorest/adal/token.go deleted file mode 100644 index 2a24ab80..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/adal/token.go +++ /dev/null @@ -1,1430 +0,0 @@ -package adal - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import ( - "context" - "crypto/rand" - "crypto/rsa" - "crypto/sha1" - "crypto/x509" - "encoding/base64" - "encoding/json" - "errors" - "fmt" - "io" - "io/ioutil" - "math" - "net/http" - "net/url" - "os" - "strconv" - "strings" - "sync" - "time" - - "github.com/Azure/go-autorest/autorest/date" - "github.com/Azure/go-autorest/logger" - "github.com/golang-jwt/jwt/v4" -) - -const ( - defaultRefresh = 5 * time.Minute - - // OAuthGrantTypeDeviceCode is the "grant_type" identifier used in device flow - OAuthGrantTypeDeviceCode = "device_code" - - // OAuthGrantTypeClientCredentials is the "grant_type" identifier used in credential flows - OAuthGrantTypeClientCredentials = "client_credentials" - - // OAuthGrantTypeUserPass is the "grant_type" identifier used in username and password auth flows - OAuthGrantTypeUserPass = "password" - - // OAuthGrantTypeRefreshToken is the "grant_type" identifier used in refresh token flows - OAuthGrantTypeRefreshToken = "refresh_token" - - // OAuthGrantTypeAuthorizationCode is the "grant_type" identifier used in authorization code flows - OAuthGrantTypeAuthorizationCode = "authorization_code" - - // metadataHeader is the header required by MSI extension - metadataHeader = "Metadata" - - // msiEndpoint is the well known endpoint for getting MSI authentications tokens - msiEndpoint = "http://169.254.169.254/metadata/identity/oauth2/token" - - // the API version to use for the MSI endpoint - msiAPIVersion = "2018-02-01" - - // the default number of attempts to refresh an MSI authentication token - defaultMaxMSIRefreshAttempts = 5 - - // asMSIEndpointEnv is the environment variable used to store the endpoint on App Service and Functions - msiEndpointEnv = "MSI_ENDPOINT" - - // asMSISecretEnv is the environment variable used to store the request secret on App Service and Functions - msiSecretEnv = "MSI_SECRET" - - // the API version to use for the legacy App Service MSI endpoint - appServiceAPIVersion2017 = "2017-09-01" - - // secret header used when authenticating against app service MSI endpoint - secretHeader = "Secret" - - // the format for expires_on in UTC with AM/PM - expiresOnDateFormatPM = "1/2/2006 15:04:05 PM +00:00" - - // the format for expires_on in UTC without AM/PM - expiresOnDateFormat = "1/2/2006 15:04:05 +00:00" -) - -// OAuthTokenProvider is an interface which should be implemented by an access token retriever -type OAuthTokenProvider interface { - OAuthToken() string -} - -// MultitenantOAuthTokenProvider provides tokens used for multi-tenant authorization. -type MultitenantOAuthTokenProvider interface { - PrimaryOAuthToken() string - AuxiliaryOAuthTokens() []string -} - -// TokenRefreshError is an interface used by errors returned during token refresh. -type TokenRefreshError interface { - error - Response() *http.Response -} - -// Refresher is an interface for token refresh functionality -type Refresher interface { - Refresh() error - RefreshExchange(resource string) error - EnsureFresh() error -} - -// RefresherWithContext is an interface for token refresh functionality -type RefresherWithContext interface { - RefreshWithContext(ctx context.Context) error - RefreshExchangeWithContext(ctx context.Context, resource string) error - EnsureFreshWithContext(ctx context.Context) error -} - -// TokenRefreshCallback is the type representing callbacks that will be called after -// a successful token refresh -type TokenRefreshCallback func(Token) error - -// TokenRefresh is a type representing a custom callback to refresh a token -type TokenRefresh func(ctx context.Context, resource string) (*Token, error) - -// JWTCallback is the type representing callback that will be called to get the federated OIDC JWT -type JWTCallback func() (string, error) - -// Token encapsulates the access token used to authorize Azure requests. -// https://docs.microsoft.com/en-us/azure/active-directory/develop/v1-oauth2-client-creds-grant-flow#service-to-service-access-token-response -type Token struct { - AccessToken string `json:"access_token"` - RefreshToken string `json:"refresh_token"` - - ExpiresIn json.Number `json:"expires_in"` - ExpiresOn json.Number `json:"expires_on"` - NotBefore json.Number `json:"not_before"` - - Resource string `json:"resource"` - Type string `json:"token_type"` -} - -func newToken() Token { - return Token{ - ExpiresIn: "0", - ExpiresOn: "0", - NotBefore: "0", - } -} - -// IsZero returns true if the token object is zero-initialized. -func (t Token) IsZero() bool { - return t == Token{} -} - -// Expires returns the time.Time when the Token expires. -func (t Token) Expires() time.Time { - s, err := t.ExpiresOn.Float64() - if err != nil { - s = -3600 - } - - expiration := date.NewUnixTimeFromSeconds(s) - - return time.Time(expiration).UTC() -} - -// IsExpired returns true if the Token is expired, false otherwise. -func (t Token) IsExpired() bool { - return t.WillExpireIn(0) -} - -// WillExpireIn returns true if the Token will expire after the passed time.Duration interval -// from now, false otherwise. -func (t Token) WillExpireIn(d time.Duration) bool { - return !t.Expires().After(time.Now().Add(d)) -} - -// OAuthToken return the current access token -func (t *Token) OAuthToken() string { - return t.AccessToken -} - -// ServicePrincipalSecret is an interface that allows various secret mechanism to fill the form -// that is submitted when acquiring an oAuth token. -type ServicePrincipalSecret interface { - SetAuthenticationValues(spt *ServicePrincipalToken, values *url.Values) error -} - -// ServicePrincipalNoSecret represents a secret type that contains no secret -// meaning it is not valid for fetching a fresh token. This is used by Manual -type ServicePrincipalNoSecret struct { -} - -// SetAuthenticationValues is a method of the interface ServicePrincipalSecret -// It only returns an error for the ServicePrincipalNoSecret type -func (noSecret *ServicePrincipalNoSecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error { - return fmt.Errorf("Manually created ServicePrincipalToken does not contain secret material to retrieve a new access token") -} - -// MarshalJSON implements the json.Marshaler interface. -func (noSecret ServicePrincipalNoSecret) MarshalJSON() ([]byte, error) { - type tokenType struct { - Type string `json:"type"` - } - return json.Marshal(tokenType{ - Type: "ServicePrincipalNoSecret", - }) -} - -// ServicePrincipalTokenSecret implements ServicePrincipalSecret for client_secret type authorization. -type ServicePrincipalTokenSecret struct { - ClientSecret string `json:"value"` -} - -// SetAuthenticationValues is a method of the interface ServicePrincipalSecret. -// It will populate the form submitted during oAuth Token Acquisition using the client_secret. -func (tokenSecret *ServicePrincipalTokenSecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error { - v.Set("client_secret", tokenSecret.ClientSecret) - return nil -} - -// MarshalJSON implements the json.Marshaler interface. -func (tokenSecret ServicePrincipalTokenSecret) MarshalJSON() ([]byte, error) { - type tokenType struct { - Type string `json:"type"` - Value string `json:"value"` - } - return json.Marshal(tokenType{ - Type: "ServicePrincipalTokenSecret", - Value: tokenSecret.ClientSecret, - }) -} - -// ServicePrincipalCertificateSecret implements ServicePrincipalSecret for generic RSA cert auth with signed JWTs. -type ServicePrincipalCertificateSecret struct { - Certificate *x509.Certificate - PrivateKey *rsa.PrivateKey -} - -// SignJwt returns the JWT signed with the certificate's private key. -func (secret *ServicePrincipalCertificateSecret) SignJwt(spt *ServicePrincipalToken) (string, error) { - hasher := sha1.New() - _, err := hasher.Write(secret.Certificate.Raw) - if err != nil { - return "", err - } - - thumbprint := base64.URLEncoding.EncodeToString(hasher.Sum(nil)) - - // The jti (JWT ID) claim provides a unique identifier for the JWT. - jti := make([]byte, 20) - _, err = rand.Read(jti) - if err != nil { - return "", err - } - - token := jwt.New(jwt.SigningMethodRS256) - token.Header["x5t"] = thumbprint - x5c := []string{base64.StdEncoding.EncodeToString(secret.Certificate.Raw)} - token.Header["x5c"] = x5c - token.Claims = jwt.MapClaims{ - "aud": spt.inner.OauthConfig.TokenEndpoint.String(), - "iss": spt.inner.ClientID, - "sub": spt.inner.ClientID, - "jti": base64.URLEncoding.EncodeToString(jti), - "nbf": time.Now().Unix(), - "exp": time.Now().Add(24 * time.Hour).Unix(), - } - - signedString, err := token.SignedString(secret.PrivateKey) - return signedString, err -} - -// SetAuthenticationValues is a method of the interface ServicePrincipalSecret. -// It will populate the form submitted during oAuth Token Acquisition using a JWT signed with a certificate. -func (secret *ServicePrincipalCertificateSecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error { - jwt, err := secret.SignJwt(spt) - if err != nil { - return err - } - - v.Set("client_assertion", jwt) - v.Set("client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer") - return nil -} - -// MarshalJSON implements the json.Marshaler interface. -func (secret ServicePrincipalCertificateSecret) MarshalJSON() ([]byte, error) { - return nil, errors.New("marshalling ServicePrincipalCertificateSecret is not supported") -} - -// ServicePrincipalMSISecret implements ServicePrincipalSecret for machines running the MSI Extension. -type ServicePrincipalMSISecret struct { - msiType msiType - clientResourceID string -} - -// SetAuthenticationValues is a method of the interface ServicePrincipalSecret. -func (msiSecret *ServicePrincipalMSISecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error { - return nil -} - -// MarshalJSON implements the json.Marshaler interface. -func (msiSecret ServicePrincipalMSISecret) MarshalJSON() ([]byte, error) { - return nil, errors.New("marshalling ServicePrincipalMSISecret is not supported") -} - -// ServicePrincipalUsernamePasswordSecret implements ServicePrincipalSecret for username and password auth. -type ServicePrincipalUsernamePasswordSecret struct { - Username string `json:"username"` - Password string `json:"password"` -} - -// SetAuthenticationValues is a method of the interface ServicePrincipalSecret. -func (secret *ServicePrincipalUsernamePasswordSecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error { - v.Set("username", secret.Username) - v.Set("password", secret.Password) - return nil -} - -// MarshalJSON implements the json.Marshaler interface. -func (secret ServicePrincipalUsernamePasswordSecret) MarshalJSON() ([]byte, error) { - type tokenType struct { - Type string `json:"type"` - Username string `json:"username"` - Password string `json:"password"` - } - return json.Marshal(tokenType{ - Type: "ServicePrincipalUsernamePasswordSecret", - Username: secret.Username, - Password: secret.Password, - }) -} - -// ServicePrincipalAuthorizationCodeSecret implements ServicePrincipalSecret for authorization code auth. -type ServicePrincipalAuthorizationCodeSecret struct { - ClientSecret string `json:"value"` - AuthorizationCode string `json:"authCode"` - RedirectURI string `json:"redirect"` -} - -// SetAuthenticationValues is a method of the interface ServicePrincipalSecret. -func (secret *ServicePrincipalAuthorizationCodeSecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error { - v.Set("code", secret.AuthorizationCode) - v.Set("client_secret", secret.ClientSecret) - v.Set("redirect_uri", secret.RedirectURI) - return nil -} - -// MarshalJSON implements the json.Marshaler interface. -func (secret ServicePrincipalAuthorizationCodeSecret) MarshalJSON() ([]byte, error) { - type tokenType struct { - Type string `json:"type"` - Value string `json:"value"` - AuthCode string `json:"authCode"` - Redirect string `json:"redirect"` - } - return json.Marshal(tokenType{ - Type: "ServicePrincipalAuthorizationCodeSecret", - Value: secret.ClientSecret, - AuthCode: secret.AuthorizationCode, - Redirect: secret.RedirectURI, - }) -} - -// ServicePrincipalFederatedSecret implements ServicePrincipalSecret for Federated JWTs. -type ServicePrincipalFederatedSecret struct { - jwtCallback JWTCallback -} - -// SetAuthenticationValues is a method of the interface ServicePrincipalSecret. -// It will populate the form submitted during OAuth Token Acquisition using a JWT signed by an OIDC issuer. -func (secret *ServicePrincipalFederatedSecret) SetAuthenticationValues(_ *ServicePrincipalToken, v *url.Values) error { - jwt, err := secret.jwtCallback() - if err != nil { - return err - } - - v.Set("client_assertion", jwt) - v.Set("client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer") - return nil -} - -// MarshalJSON implements the json.Marshaler interface. -func (secret ServicePrincipalFederatedSecret) MarshalJSON() ([]byte, error) { - return nil, errors.New("marshalling ServicePrincipalFederatedSecret is not supported") -} - -// ServicePrincipalToken encapsulates a Token created for a Service Principal. -type ServicePrincipalToken struct { - inner servicePrincipalToken - refreshLock *sync.RWMutex - sender Sender - customRefreshFunc TokenRefresh - refreshCallbacks []TokenRefreshCallback - // MaxMSIRefreshAttempts is the maximum number of attempts to refresh an MSI token. - // Settings this to a value less than 1 will use the default value. - MaxMSIRefreshAttempts int -} - -// MarshalTokenJSON returns the marshalled inner token. -func (spt ServicePrincipalToken) MarshalTokenJSON() ([]byte, error) { - return json.Marshal(spt.inner.Token) -} - -// SetRefreshCallbacks replaces any existing refresh callbacks with the specified callbacks. -func (spt *ServicePrincipalToken) SetRefreshCallbacks(callbacks []TokenRefreshCallback) { - spt.refreshCallbacks = callbacks -} - -// SetCustomRefreshFunc sets a custom refresh function used to refresh the token. -func (spt *ServicePrincipalToken) SetCustomRefreshFunc(customRefreshFunc TokenRefresh) { - spt.customRefreshFunc = customRefreshFunc -} - -// MarshalJSON implements the json.Marshaler interface. -func (spt ServicePrincipalToken) MarshalJSON() ([]byte, error) { - return json.Marshal(spt.inner) -} - -// UnmarshalJSON implements the json.Unmarshaler interface. -func (spt *ServicePrincipalToken) UnmarshalJSON(data []byte) error { - // need to determine the token type - raw := map[string]interface{}{} - err := json.Unmarshal(data, &raw) - if err != nil { - return err - } - secret := raw["secret"].(map[string]interface{}) - switch secret["type"] { - case "ServicePrincipalNoSecret": - spt.inner.Secret = &ServicePrincipalNoSecret{} - case "ServicePrincipalTokenSecret": - spt.inner.Secret = &ServicePrincipalTokenSecret{} - case "ServicePrincipalCertificateSecret": - return errors.New("unmarshalling ServicePrincipalCertificateSecret is not supported") - case "ServicePrincipalMSISecret": - return errors.New("unmarshalling ServicePrincipalMSISecret is not supported") - case "ServicePrincipalUsernamePasswordSecret": - spt.inner.Secret = &ServicePrincipalUsernamePasswordSecret{} - case "ServicePrincipalAuthorizationCodeSecret": - spt.inner.Secret = &ServicePrincipalAuthorizationCodeSecret{} - case "ServicePrincipalFederatedSecret": - return errors.New("unmarshalling ServicePrincipalFederatedSecret is not supported") - default: - return fmt.Errorf("unrecognized token type '%s'", secret["type"]) - } - err = json.Unmarshal(data, &spt.inner) - if err != nil { - return err - } - // Don't override the refreshLock or the sender if those have been already set. - if spt.refreshLock == nil { - spt.refreshLock = &sync.RWMutex{} - } - if spt.sender == nil { - spt.sender = sender() - } - return nil -} - -// internal type used for marshalling/unmarshalling -type servicePrincipalToken struct { - Token Token `json:"token"` - Secret ServicePrincipalSecret `json:"secret"` - OauthConfig OAuthConfig `json:"oauth"` - ClientID string `json:"clientID"` - Resource string `json:"resource"` - AutoRefresh bool `json:"autoRefresh"` - RefreshWithin time.Duration `json:"refreshWithin"` -} - -func validateOAuthConfig(oac OAuthConfig) error { - if oac.IsZero() { - return fmt.Errorf("parameter 'oauthConfig' cannot be zero-initialized") - } - return nil -} - -// NewServicePrincipalTokenWithSecret create a ServicePrincipalToken using the supplied ServicePrincipalSecret implementation. -func NewServicePrincipalTokenWithSecret(oauthConfig OAuthConfig, id string, resource string, secret ServicePrincipalSecret, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { - if err := validateOAuthConfig(oauthConfig); err != nil { - return nil, err - } - if err := validateStringParam(id, "id"); err != nil { - return nil, err - } - if err := validateStringParam(resource, "resource"); err != nil { - return nil, err - } - if secret == nil { - return nil, fmt.Errorf("parameter 'secret' cannot be nil") - } - spt := &ServicePrincipalToken{ - inner: servicePrincipalToken{ - Token: newToken(), - OauthConfig: oauthConfig, - Secret: secret, - ClientID: id, - Resource: resource, - AutoRefresh: true, - RefreshWithin: defaultRefresh, - }, - refreshLock: &sync.RWMutex{}, - sender: sender(), - refreshCallbacks: callbacks, - } - return spt, nil -} - -// NewServicePrincipalTokenFromManualToken creates a ServicePrincipalToken using the supplied token -func NewServicePrincipalTokenFromManualToken(oauthConfig OAuthConfig, clientID string, resource string, token Token, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { - if err := validateOAuthConfig(oauthConfig); err != nil { - return nil, err - } - if err := validateStringParam(clientID, "clientID"); err != nil { - return nil, err - } - if err := validateStringParam(resource, "resource"); err != nil { - return nil, err - } - if token.IsZero() { - return nil, fmt.Errorf("parameter 'token' cannot be zero-initialized") - } - spt, err := NewServicePrincipalTokenWithSecret( - oauthConfig, - clientID, - resource, - &ServicePrincipalNoSecret{}, - callbacks...) - if err != nil { - return nil, err - } - - spt.inner.Token = token - - return spt, nil -} - -// NewServicePrincipalTokenFromManualTokenSecret creates a ServicePrincipalToken using the supplied token and secret -func NewServicePrincipalTokenFromManualTokenSecret(oauthConfig OAuthConfig, clientID string, resource string, token Token, secret ServicePrincipalSecret, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { - if err := validateOAuthConfig(oauthConfig); err != nil { - return nil, err - } - if err := validateStringParam(clientID, "clientID"); err != nil { - return nil, err - } - if err := validateStringParam(resource, "resource"); err != nil { - return nil, err - } - if secret == nil { - return nil, fmt.Errorf("parameter 'secret' cannot be nil") - } - if token.IsZero() { - return nil, fmt.Errorf("parameter 'token' cannot be zero-initialized") - } - spt, err := NewServicePrincipalTokenWithSecret( - oauthConfig, - clientID, - resource, - secret, - callbacks...) - if err != nil { - return nil, err - } - - spt.inner.Token = token - - return spt, nil -} - -// NewServicePrincipalToken creates a ServicePrincipalToken from the supplied Service Principal -// credentials scoped to the named resource. -func NewServicePrincipalToken(oauthConfig OAuthConfig, clientID string, secret string, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { - if err := validateOAuthConfig(oauthConfig); err != nil { - return nil, err - } - if err := validateStringParam(clientID, "clientID"); err != nil { - return nil, err - } - if err := validateStringParam(secret, "secret"); err != nil { - return nil, err - } - if err := validateStringParam(resource, "resource"); err != nil { - return nil, err - } - return NewServicePrincipalTokenWithSecret( - oauthConfig, - clientID, - resource, - &ServicePrincipalTokenSecret{ - ClientSecret: secret, - }, - callbacks..., - ) -} - -// NewServicePrincipalTokenFromCertificate creates a ServicePrincipalToken from the supplied pkcs12 bytes. -func NewServicePrincipalTokenFromCertificate(oauthConfig OAuthConfig, clientID string, certificate *x509.Certificate, privateKey *rsa.PrivateKey, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { - if err := validateOAuthConfig(oauthConfig); err != nil { - return nil, err - } - if err := validateStringParam(clientID, "clientID"); err != nil { - return nil, err - } - if err := validateStringParam(resource, "resource"); err != nil { - return nil, err - } - if certificate == nil { - return nil, fmt.Errorf("parameter 'certificate' cannot be nil") - } - if privateKey == nil { - return nil, fmt.Errorf("parameter 'privateKey' cannot be nil") - } - return NewServicePrincipalTokenWithSecret( - oauthConfig, - clientID, - resource, - &ServicePrincipalCertificateSecret{ - PrivateKey: privateKey, - Certificate: certificate, - }, - callbacks..., - ) -} - -// NewServicePrincipalTokenFromUsernamePassword creates a ServicePrincipalToken from the username and password. -func NewServicePrincipalTokenFromUsernamePassword(oauthConfig OAuthConfig, clientID string, username string, password string, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { - if err := validateOAuthConfig(oauthConfig); err != nil { - return nil, err - } - if err := validateStringParam(clientID, "clientID"); err != nil { - return nil, err - } - if err := validateStringParam(username, "username"); err != nil { - return nil, err - } - if err := validateStringParam(password, "password"); err != nil { - return nil, err - } - if err := validateStringParam(resource, "resource"); err != nil { - return nil, err - } - return NewServicePrincipalTokenWithSecret( - oauthConfig, - clientID, - resource, - &ServicePrincipalUsernamePasswordSecret{ - Username: username, - Password: password, - }, - callbacks..., - ) -} - -// NewServicePrincipalTokenFromAuthorizationCode creates a ServicePrincipalToken from the -func NewServicePrincipalTokenFromAuthorizationCode(oauthConfig OAuthConfig, clientID string, clientSecret string, authorizationCode string, redirectURI string, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { - - if err := validateOAuthConfig(oauthConfig); err != nil { - return nil, err - } - if err := validateStringParam(clientID, "clientID"); err != nil { - return nil, err - } - if err := validateStringParam(clientSecret, "clientSecret"); err != nil { - return nil, err - } - if err := validateStringParam(authorizationCode, "authorizationCode"); err != nil { - return nil, err - } - if err := validateStringParam(redirectURI, "redirectURI"); err != nil { - return nil, err - } - if err := validateStringParam(resource, "resource"); err != nil { - return nil, err - } - - return NewServicePrincipalTokenWithSecret( - oauthConfig, - clientID, - resource, - &ServicePrincipalAuthorizationCodeSecret{ - ClientSecret: clientSecret, - AuthorizationCode: authorizationCode, - RedirectURI: redirectURI, - }, - callbacks..., - ) -} - -// NewServicePrincipalTokenFromFederatedToken creates a ServicePrincipalToken from the supplied federated OIDC JWT. -// -// Deprecated: Use NewServicePrincipalTokenFromFederatedTokenWithCallback to refresh jwt dynamically. -func NewServicePrincipalTokenFromFederatedToken(oauthConfig OAuthConfig, clientID string, jwt string, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { - if err := validateOAuthConfig(oauthConfig); err != nil { - return nil, err - } - if err := validateStringParam(clientID, "clientID"); err != nil { - return nil, err - } - if err := validateStringParam(resource, "resource"); err != nil { - return nil, err - } - if jwt == "" { - return nil, fmt.Errorf("parameter 'jwt' cannot be empty") - } - return NewServicePrincipalTokenFromFederatedTokenCallback( - oauthConfig, - clientID, - func() (string, error) { - return jwt, nil - }, - resource, - callbacks..., - ) -} - -// NewServicePrincipalTokenFromFederatedTokenCallback creates a ServicePrincipalToken from the supplied federated OIDC JWTCallback. -func NewServicePrincipalTokenFromFederatedTokenCallback(oauthConfig OAuthConfig, clientID string, jwtCallback JWTCallback, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { - if err := validateOAuthConfig(oauthConfig); err != nil { - return nil, err - } - if err := validateStringParam(clientID, "clientID"); err != nil { - return nil, err - } - if err := validateStringParam(resource, "resource"); err != nil { - return nil, err - } - if jwtCallback == nil { - return nil, fmt.Errorf("parameter 'jwtCallback' cannot be empty") - } - return NewServicePrincipalTokenWithSecret( - oauthConfig, - clientID, - resource, - &ServicePrincipalFederatedSecret{ - jwtCallback: jwtCallback, - }, - callbacks..., - ) -} - -type msiType int - -const ( - msiTypeUnavailable msiType = iota - msiTypeAppServiceV20170901 - msiTypeCloudShell - msiTypeIMDS -) - -func (m msiType) String() string { - switch m { - case msiTypeAppServiceV20170901: - return "AppServiceV20170901" - case msiTypeCloudShell: - return "CloudShell" - case msiTypeIMDS: - return "IMDS" - default: - return fmt.Sprintf("unhandled MSI type %d", m) - } -} - -// returns the MSI type and endpoint, or an error -func getMSIType() (msiType, string, error) { - if endpointEnvVar := os.Getenv(msiEndpointEnv); endpointEnvVar != "" { - // if the env var MSI_ENDPOINT is set - if secretEnvVar := os.Getenv(msiSecretEnv); secretEnvVar != "" { - // if BOTH the env vars MSI_ENDPOINT and MSI_SECRET are set the msiType is AppService - return msiTypeAppServiceV20170901, endpointEnvVar, nil - } - // if ONLY the env var MSI_ENDPOINT is set the msiType is CloudShell - return msiTypeCloudShell, endpointEnvVar, nil - } - // if MSI_ENDPOINT is NOT set assume the msiType is IMDS - return msiTypeIMDS, msiEndpoint, nil -} - -// GetMSIVMEndpoint gets the MSI endpoint on Virtual Machines. -// NOTE: this always returns the IMDS endpoint, it does not work for app services or cloud shell. -// Deprecated: NewServicePrincipalTokenFromMSI() and variants will automatically detect the endpoint. -func GetMSIVMEndpoint() (string, error) { - return msiEndpoint, nil -} - -// GetMSIAppServiceEndpoint get the MSI endpoint for App Service and Functions. -// It will return an error when not running in an app service/functions environment. -// Deprecated: NewServicePrincipalTokenFromMSI() and variants will automatically detect the endpoint. -func GetMSIAppServiceEndpoint() (string, error) { - msiType, endpoint, err := getMSIType() - if err != nil { - return "", err - } - switch msiType { - case msiTypeAppServiceV20170901: - return endpoint, nil - default: - return "", fmt.Errorf("%s is not app service environment", msiType) - } -} - -// GetMSIEndpoint get the appropriate MSI endpoint depending on the runtime environment -// Deprecated: NewServicePrincipalTokenFromMSI() and variants will automatically detect the endpoint. -func GetMSIEndpoint() (string, error) { - _, endpoint, err := getMSIType() - return endpoint, err -} - -// NewServicePrincipalTokenFromMSI creates a ServicePrincipalToken via the MSI VM Extension. -// It will use the system assigned identity when creating the token. -// msiEndpoint - empty string, or pass a non-empty string to override the default value. -// Deprecated: use NewServicePrincipalTokenFromManagedIdentity() instead. -func NewServicePrincipalTokenFromMSI(msiEndpoint, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { - return newServicePrincipalTokenFromMSI(msiEndpoint, resource, "", "", callbacks...) -} - -// NewServicePrincipalTokenFromMSIWithUserAssignedID creates a ServicePrincipalToken via the MSI VM Extension. -// It will use the clientID of specified user assigned identity when creating the token. -// msiEndpoint - empty string, or pass a non-empty string to override the default value. -// Deprecated: use NewServicePrincipalTokenFromManagedIdentity() instead. -func NewServicePrincipalTokenFromMSIWithUserAssignedID(msiEndpoint, resource string, userAssignedID string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { - if err := validateStringParam(userAssignedID, "userAssignedID"); err != nil { - return nil, err - } - return newServicePrincipalTokenFromMSI(msiEndpoint, resource, userAssignedID, "", callbacks...) -} - -// NewServicePrincipalTokenFromMSIWithIdentityResourceID creates a ServicePrincipalToken via the MSI VM Extension. -// It will use the azure resource id of user assigned identity when creating the token. -// msiEndpoint - empty string, or pass a non-empty string to override the default value. -// Deprecated: use NewServicePrincipalTokenFromManagedIdentity() instead. -func NewServicePrincipalTokenFromMSIWithIdentityResourceID(msiEndpoint, resource string, identityResourceID string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { - if err := validateStringParam(identityResourceID, "identityResourceID"); err != nil { - return nil, err - } - return newServicePrincipalTokenFromMSI(msiEndpoint, resource, "", identityResourceID, callbacks...) -} - -// ManagedIdentityOptions contains optional values for configuring managed identity authentication. -type ManagedIdentityOptions struct { - // ClientID is the user-assigned identity to use during authentication. - // It is mutually exclusive with IdentityResourceID. - ClientID string - - // IdentityResourceID is the resource ID of the user-assigned identity to use during authentication. - // It is mutually exclusive with ClientID. - IdentityResourceID string -} - -// NewServicePrincipalTokenFromManagedIdentity creates a ServicePrincipalToken using a managed identity. -// It supports the following managed identity environments. -// - App Service Environment (API version 2017-09-01 only) -// - Cloud shell -// - IMDS with a system or user assigned identity -func NewServicePrincipalTokenFromManagedIdentity(resource string, options *ManagedIdentityOptions, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { - if options == nil { - options = &ManagedIdentityOptions{} - } - return newServicePrincipalTokenFromMSI("", resource, options.ClientID, options.IdentityResourceID, callbacks...) -} - -func newServicePrincipalTokenFromMSI(msiEndpoint, resource, userAssignedID, identityResourceID string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) { - if err := validateStringParam(resource, "resource"); err != nil { - return nil, err - } - if userAssignedID != "" && identityResourceID != "" { - return nil, errors.New("cannot specify userAssignedID and identityResourceID") - } - msiType, endpoint, err := getMSIType() - if err != nil { - logger.Instance.Writef(logger.LogError, "Error determining managed identity environment: %v\n", err) - return nil, err - } - logger.Instance.Writef(logger.LogInfo, "Managed identity environment is %s, endpoint is %s\n", msiType, endpoint) - if msiEndpoint != "" { - endpoint = msiEndpoint - logger.Instance.Writef(logger.LogInfo, "Managed identity custom endpoint is %s\n", endpoint) - } - msiEndpointURL, err := url.Parse(endpoint) - if err != nil { - return nil, err - } - // cloud shell sends its data in the request body - if msiType != msiTypeCloudShell { - v := url.Values{} - v.Set("resource", resource) - clientIDParam := "client_id" - switch msiType { - case msiTypeAppServiceV20170901: - clientIDParam = "clientid" - v.Set("api-version", appServiceAPIVersion2017) - break - case msiTypeIMDS: - v.Set("api-version", msiAPIVersion) - } - if userAssignedID != "" { - v.Set(clientIDParam, userAssignedID) - } else if identityResourceID != "" { - v.Set("mi_res_id", identityResourceID) - } - msiEndpointURL.RawQuery = v.Encode() - } - - spt := &ServicePrincipalToken{ - inner: servicePrincipalToken{ - Token: newToken(), - OauthConfig: OAuthConfig{ - TokenEndpoint: *msiEndpointURL, - }, - Secret: &ServicePrincipalMSISecret{ - msiType: msiType, - clientResourceID: identityResourceID, - }, - Resource: resource, - AutoRefresh: true, - RefreshWithin: defaultRefresh, - ClientID: userAssignedID, - }, - refreshLock: &sync.RWMutex{}, - sender: sender(), - refreshCallbacks: callbacks, - MaxMSIRefreshAttempts: defaultMaxMSIRefreshAttempts, - } - - return spt, nil -} - -// internal type that implements TokenRefreshError -type tokenRefreshError struct { - message string - resp *http.Response -} - -// Error implements the error interface which is part of the TokenRefreshError interface. -func (tre tokenRefreshError) Error() string { - return tre.message -} - -// Response implements the TokenRefreshError interface, it returns the raw HTTP response from the refresh operation. -func (tre tokenRefreshError) Response() *http.Response { - return tre.resp -} - -func newTokenRefreshError(message string, resp *http.Response) TokenRefreshError { - return tokenRefreshError{message: message, resp: resp} -} - -// EnsureFresh will refresh the token if it will expire within the refresh window (as set by -// RefreshWithin) and autoRefresh flag is on. This method is safe for concurrent use. -func (spt *ServicePrincipalToken) EnsureFresh() error { - return spt.EnsureFreshWithContext(context.Background()) -} - -// EnsureFreshWithContext will refresh the token if it will expire within the refresh window (as set by -// RefreshWithin) and autoRefresh flag is on. This method is safe for concurrent use. -func (spt *ServicePrincipalToken) EnsureFreshWithContext(ctx context.Context) error { - // must take the read lock when initially checking the token's expiration - if spt.inner.AutoRefresh && spt.Token().WillExpireIn(spt.inner.RefreshWithin) { - // take the write lock then check again to see if the token was already refreshed - spt.refreshLock.Lock() - defer spt.refreshLock.Unlock() - if spt.inner.Token.WillExpireIn(spt.inner.RefreshWithin) { - return spt.refreshInternal(ctx, spt.inner.Resource) - } - } - return nil -} - -// InvokeRefreshCallbacks calls any TokenRefreshCallbacks that were added to the SPT during initialization -func (spt *ServicePrincipalToken) InvokeRefreshCallbacks(token Token) error { - if spt.refreshCallbacks != nil { - for _, callback := range spt.refreshCallbacks { - err := callback(spt.inner.Token) - if err != nil { - return fmt.Errorf("adal: TokenRefreshCallback handler failed. Error = '%v'", err) - } - } - } - return nil -} - -// Refresh obtains a fresh token for the Service Principal. -// This method is safe for concurrent use. -func (spt *ServicePrincipalToken) Refresh() error { - return spt.RefreshWithContext(context.Background()) -} - -// RefreshWithContext obtains a fresh token for the Service Principal. -// This method is safe for concurrent use. -func (spt *ServicePrincipalToken) RefreshWithContext(ctx context.Context) error { - spt.refreshLock.Lock() - defer spt.refreshLock.Unlock() - return spt.refreshInternal(ctx, spt.inner.Resource) -} - -// RefreshExchange refreshes the token, but for a different resource. -// This method is safe for concurrent use. -func (spt *ServicePrincipalToken) RefreshExchange(resource string) error { - return spt.RefreshExchangeWithContext(context.Background(), resource) -} - -// RefreshExchangeWithContext refreshes the token, but for a different resource. -// This method is safe for concurrent use. -func (spt *ServicePrincipalToken) RefreshExchangeWithContext(ctx context.Context, resource string) error { - spt.refreshLock.Lock() - defer spt.refreshLock.Unlock() - return spt.refreshInternal(ctx, resource) -} - -func (spt *ServicePrincipalToken) getGrantType() string { - switch spt.inner.Secret.(type) { - case *ServicePrincipalUsernamePasswordSecret: - return OAuthGrantTypeUserPass - case *ServicePrincipalAuthorizationCodeSecret: - return OAuthGrantTypeAuthorizationCode - default: - return OAuthGrantTypeClientCredentials - } -} - -func (spt *ServicePrincipalToken) refreshInternal(ctx context.Context, resource string) error { - if spt.customRefreshFunc != nil { - token, err := spt.customRefreshFunc(ctx, resource) - if err != nil { - return err - } - spt.inner.Token = *token - return spt.InvokeRefreshCallbacks(spt.inner.Token) - } - req, err := http.NewRequest(http.MethodPost, spt.inner.OauthConfig.TokenEndpoint.String(), nil) - if err != nil { - return fmt.Errorf("adal: Failed to build the refresh request. Error = '%v'", err) - } - req.Header.Add("User-Agent", UserAgent()) - req = req.WithContext(ctx) - var resp *http.Response - authBodyFilter := func(b []byte) []byte { - if logger.Level() != logger.LogAuth { - return []byte("**REDACTED** authentication body") - } - return b - } - if msiSecret, ok := spt.inner.Secret.(*ServicePrincipalMSISecret); ok { - switch msiSecret.msiType { - case msiTypeAppServiceV20170901: - req.Method = http.MethodGet - req.Header.Set("secret", os.Getenv(msiSecretEnv)) - break - case msiTypeCloudShell: - req.Header.Set("Metadata", "true") - data := url.Values{} - data.Set("resource", spt.inner.Resource) - if spt.inner.ClientID != "" { - data.Set("client_id", spt.inner.ClientID) - } else if msiSecret.clientResourceID != "" { - data.Set("msi_res_id", msiSecret.clientResourceID) - } - req.Body = ioutil.NopCloser(strings.NewReader(data.Encode())) - req.Header.Set("Content-Type", "application/x-www-form-urlencoded") - break - case msiTypeIMDS: - req.Method = http.MethodGet - req.Header.Set("Metadata", "true") - break - } - logger.Instance.WriteRequest(req, logger.Filter{Body: authBodyFilter}) - resp, err = retryForIMDS(spt.sender, req, spt.MaxMSIRefreshAttempts) - } else { - v := url.Values{} - v.Set("client_id", spt.inner.ClientID) - v.Set("resource", resource) - - if spt.inner.Token.RefreshToken != "" { - v.Set("grant_type", OAuthGrantTypeRefreshToken) - v.Set("refresh_token", spt.inner.Token.RefreshToken) - // web apps must specify client_secret when refreshing tokens - // see https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-protocols-oauth-code#refreshing-the-access-tokens - if spt.getGrantType() == OAuthGrantTypeAuthorizationCode { - err := spt.inner.Secret.SetAuthenticationValues(spt, &v) - if err != nil { - return err - } - } - } else { - v.Set("grant_type", spt.getGrantType()) - err := spt.inner.Secret.SetAuthenticationValues(spt, &v) - if err != nil { - return err - } - } - - s := v.Encode() - body := ioutil.NopCloser(strings.NewReader(s)) - req.ContentLength = int64(len(s)) - req.Header.Set(contentType, mimeTypeFormPost) - req.Body = body - logger.Instance.WriteRequest(req, logger.Filter{Body: authBodyFilter}) - resp, err = spt.sender.Do(req) - } - - // don't return a TokenRefreshError here; this will allow retry logic to apply - if err != nil { - return fmt.Errorf("adal: Failed to execute the refresh request. Error = '%v'", err) - } else if resp == nil { - return fmt.Errorf("adal: received nil response and error") - } - - logger.Instance.WriteResponse(resp, logger.Filter{Body: authBodyFilter}) - defer resp.Body.Close() - rb, err := ioutil.ReadAll(resp.Body) - - if resp.StatusCode != http.StatusOK { - if err != nil { - return newTokenRefreshError(fmt.Sprintf("adal: Refresh request failed. Status Code = '%d'. Failed reading response body: %v Endpoint %s", resp.StatusCode, err, req.URL.String()), resp) - } - return newTokenRefreshError(fmt.Sprintf("adal: Refresh request failed. Status Code = '%d'. Response body: %s Endpoint %s", resp.StatusCode, string(rb), req.URL.String()), resp) - } - - // for the following error cases don't return a TokenRefreshError. the operation succeeded - // but some transient failure happened during deserialization. by returning a generic error - // the retry logic will kick in (we don't retry on TokenRefreshError). - - if err != nil { - return fmt.Errorf("adal: Failed to read a new service principal token during refresh. Error = '%v'", err) - } - if len(strings.Trim(string(rb), " ")) == 0 { - return fmt.Errorf("adal: Empty service principal token received during refresh") - } - token := struct { - AccessToken string `json:"access_token"` - RefreshToken string `json:"refresh_token"` - - // AAD returns expires_in as a string, ADFS returns it as an int - ExpiresIn json.Number `json:"expires_in"` - // expires_on can be in three formats, a UTC time stamp, or the number of seconds as a string *or* int. - ExpiresOn interface{} `json:"expires_on"` - NotBefore json.Number `json:"not_before"` - - Resource string `json:"resource"` - Type string `json:"token_type"` - }{} - // return a TokenRefreshError in the follow error cases as the token is in an unexpected format - err = json.Unmarshal(rb, &token) - if err != nil { - return newTokenRefreshError(fmt.Sprintf("adal: Failed to unmarshal the service principal token during refresh. Error = '%v' JSON = '%s'", err, string(rb)), resp) - } - expiresOn := json.Number("") - // ADFS doesn't include the expires_on field - if token.ExpiresOn != nil { - if expiresOn, err = parseExpiresOn(token.ExpiresOn); err != nil { - return newTokenRefreshError(fmt.Sprintf("adal: failed to parse expires_on: %v value '%s'", err, token.ExpiresOn), resp) - } - } - spt.inner.Token.AccessToken = token.AccessToken - spt.inner.Token.RefreshToken = token.RefreshToken - spt.inner.Token.ExpiresIn = token.ExpiresIn - spt.inner.Token.ExpiresOn = expiresOn - spt.inner.Token.NotBefore = token.NotBefore - spt.inner.Token.Resource = token.Resource - spt.inner.Token.Type = token.Type - - return spt.InvokeRefreshCallbacks(spt.inner.Token) -} - -// converts expires_on to the number of seconds -func parseExpiresOn(s interface{}) (json.Number, error) { - // the JSON unmarshaler treats JSON numbers unmarshaled into an interface{} as float64 - asFloat64, ok := s.(float64) - if ok { - // this is the number of seconds as int case - return json.Number(strconv.FormatInt(int64(asFloat64), 10)), nil - } - asStr, ok := s.(string) - if !ok { - return "", fmt.Errorf("unexpected expires_on type %T", s) - } - // convert the expiration date to the number of seconds from the unix epoch - timeToDuration := func(t time.Time) json.Number { - return json.Number(strconv.FormatInt(t.UTC().Unix(), 10)) - } - if _, err := json.Number(asStr).Int64(); err == nil { - // this is the number of seconds case, no conversion required - return json.Number(asStr), nil - } else if eo, err := time.Parse(expiresOnDateFormatPM, asStr); err == nil { - return timeToDuration(eo), nil - } else if eo, err := time.Parse(expiresOnDateFormat, asStr); err == nil { - return timeToDuration(eo), nil - } else { - // unknown format - return json.Number(""), err - } -} - -// retry logic specific to retrieving a token from the IMDS endpoint -func retryForIMDS(sender Sender, req *http.Request, maxAttempts int) (resp *http.Response, err error) { - // copied from client.go due to circular dependency - retries := []int{ - http.StatusRequestTimeout, // 408 - http.StatusTooManyRequests, // 429 - http.StatusInternalServerError, // 500 - http.StatusBadGateway, // 502 - http.StatusServiceUnavailable, // 503 - http.StatusGatewayTimeout, // 504 - } - // extra retry status codes specific to IMDS - retries = append(retries, - http.StatusNotFound, - http.StatusGone, - // all remaining 5xx - http.StatusNotImplemented, - http.StatusHTTPVersionNotSupported, - http.StatusVariantAlsoNegotiates, - http.StatusInsufficientStorage, - http.StatusLoopDetected, - http.StatusNotExtended, - http.StatusNetworkAuthenticationRequired) - - // see https://docs.microsoft.com/en-us/azure/active-directory/managed-service-identity/how-to-use-vm-token#retry-guidance - - const maxDelay time.Duration = 60 * time.Second - - attempt := 0 - delay := time.Duration(0) - - // maxAttempts is user-specified, ensure that its value is greater than zero else no request will be made - if maxAttempts < 1 { - maxAttempts = defaultMaxMSIRefreshAttempts - } - - for attempt < maxAttempts { - if resp != nil && resp.Body != nil { - io.Copy(ioutil.Discard, resp.Body) - resp.Body.Close() - } - resp, err = sender.Do(req) - // we want to retry if err is not nil or the status code is in the list of retry codes - if err == nil && !responseHasStatusCode(resp, retries...) { - return - } - - // perform exponential backoff with a cap. - // must increment attempt before calculating delay. - attempt++ - // the base value of 2 is the "delta backoff" as specified in the guidance doc - delay += (time.Duration(math.Pow(2, float64(attempt))) * time.Second) - if delay > maxDelay { - delay = maxDelay - } - - select { - case <-time.After(delay): - // intentionally left blank - case <-req.Context().Done(): - err = req.Context().Err() - return - } - } - return -} - -func responseHasStatusCode(resp *http.Response, codes ...int) bool { - if resp != nil { - for _, i := range codes { - if i == resp.StatusCode { - return true - } - } - } - return false -} - -// SetAutoRefresh enables or disables automatic refreshing of stale tokens. -func (spt *ServicePrincipalToken) SetAutoRefresh(autoRefresh bool) { - spt.inner.AutoRefresh = autoRefresh -} - -// SetRefreshWithin sets the interval within which if the token will expire, EnsureFresh will -// refresh the token. -func (spt *ServicePrincipalToken) SetRefreshWithin(d time.Duration) { - spt.inner.RefreshWithin = d - return -} - -// SetSender sets the http.Client used when obtaining the Service Principal token. An -// undecorated http.Client is used by default. -func (spt *ServicePrincipalToken) SetSender(s Sender) { spt.sender = s } - -// OAuthToken implements the OAuthTokenProvider interface. It returns the current access token. -func (spt *ServicePrincipalToken) OAuthToken() string { - spt.refreshLock.RLock() - defer spt.refreshLock.RUnlock() - return spt.inner.Token.OAuthToken() -} - -// Token returns a copy of the current token. -func (spt *ServicePrincipalToken) Token() Token { - spt.refreshLock.RLock() - defer spt.refreshLock.RUnlock() - return spt.inner.Token -} - -// MultiTenantServicePrincipalToken contains tokens for multi-tenant authorization. -type MultiTenantServicePrincipalToken struct { - PrimaryToken *ServicePrincipalToken - AuxiliaryTokens []*ServicePrincipalToken -} - -// PrimaryOAuthToken returns the primary authorization token. -func (mt *MultiTenantServicePrincipalToken) PrimaryOAuthToken() string { - return mt.PrimaryToken.OAuthToken() -} - -// AuxiliaryOAuthTokens returns one to three auxiliary authorization tokens. -func (mt *MultiTenantServicePrincipalToken) AuxiliaryOAuthTokens() []string { - tokens := make([]string, len(mt.AuxiliaryTokens)) - for i := range mt.AuxiliaryTokens { - tokens[i] = mt.AuxiliaryTokens[i].OAuthToken() - } - return tokens -} - -// NewMultiTenantServicePrincipalToken creates a new MultiTenantServicePrincipalToken with the specified credentials and resource. -func NewMultiTenantServicePrincipalToken(multiTenantCfg MultiTenantOAuthConfig, clientID string, secret string, resource string) (*MultiTenantServicePrincipalToken, error) { - if err := validateStringParam(clientID, "clientID"); err != nil { - return nil, err - } - if err := validateStringParam(secret, "secret"); err != nil { - return nil, err - } - if err := validateStringParam(resource, "resource"); err != nil { - return nil, err - } - auxTenants := multiTenantCfg.AuxiliaryTenants() - m := MultiTenantServicePrincipalToken{ - AuxiliaryTokens: make([]*ServicePrincipalToken, len(auxTenants)), - } - primary, err := NewServicePrincipalToken(*multiTenantCfg.PrimaryTenant(), clientID, secret, resource) - if err != nil { - return nil, fmt.Errorf("failed to create SPT for primary tenant: %v", err) - } - m.PrimaryToken = primary - for i := range auxTenants { - aux, err := NewServicePrincipalToken(*auxTenants[i], clientID, secret, resource) - if err != nil { - return nil, fmt.Errorf("failed to create SPT for auxiliary tenant: %v", err) - } - m.AuxiliaryTokens[i] = aux - } - return &m, nil -} - -// NewMultiTenantServicePrincipalTokenFromCertificate creates a new MultiTenantServicePrincipalToken with the specified certificate credentials and resource. -func NewMultiTenantServicePrincipalTokenFromCertificate(multiTenantCfg MultiTenantOAuthConfig, clientID string, certificate *x509.Certificate, privateKey *rsa.PrivateKey, resource string) (*MultiTenantServicePrincipalToken, error) { - if err := validateStringParam(clientID, "clientID"); err != nil { - return nil, err - } - if err := validateStringParam(resource, "resource"); err != nil { - return nil, err - } - if certificate == nil { - return nil, fmt.Errorf("parameter 'certificate' cannot be nil") - } - if privateKey == nil { - return nil, fmt.Errorf("parameter 'privateKey' cannot be nil") - } - auxTenants := multiTenantCfg.AuxiliaryTenants() - m := MultiTenantServicePrincipalToken{ - AuxiliaryTokens: make([]*ServicePrincipalToken, len(auxTenants)), - } - primary, err := NewServicePrincipalTokenWithSecret( - *multiTenantCfg.PrimaryTenant(), - clientID, - resource, - &ServicePrincipalCertificateSecret{ - PrivateKey: privateKey, - Certificate: certificate, - }, - ) - if err != nil { - return nil, fmt.Errorf("failed to create SPT for primary tenant: %v", err) - } - m.PrimaryToken = primary - for i := range auxTenants { - aux, err := NewServicePrincipalTokenWithSecret( - *auxTenants[i], - clientID, - resource, - &ServicePrincipalCertificateSecret{ - PrivateKey: privateKey, - Certificate: certificate, - }, - ) - if err != nil { - return nil, fmt.Errorf("failed to create SPT for auxiliary tenant: %v", err) - } - m.AuxiliaryTokens[i] = aux - } - return &m, nil -} - -// MSIAvailable returns true if the MSI endpoint is available for authentication. -func MSIAvailable(ctx context.Context, s Sender) bool { - msiType, _, err := getMSIType() - - if err != nil { - return false - } - - if msiType != msiTypeIMDS { - return true - } - - if s == nil { - s = sender() - } - - resp, err := getMSIEndpoint(ctx, s) - - if err == nil { - resp.Body.Close() - } - - return err == nil -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/token_1.13.go b/vendor/github.com/Azure/go-autorest/autorest/adal/token_1.13.go deleted file mode 100644 index 89190a42..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/adal/token_1.13.go +++ /dev/null @@ -1,76 +0,0 @@ -//go:build go1.13 -// +build go1.13 - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package adal - -import ( - "context" - "fmt" - "net/http" - "time" -) - -func getMSIEndpoint(ctx context.Context, sender Sender) (*http.Response, error) { - tempCtx, cancel := context.WithTimeout(ctx, 2*time.Second) - defer cancel() - // http.NewRequestWithContext() was added in Go 1.13 - req, _ := http.NewRequestWithContext(tempCtx, http.MethodGet, msiEndpoint, nil) - q := req.URL.Query() - q.Add("api-version", msiAPIVersion) - req.URL.RawQuery = q.Encode() - return sender.Do(req) -} - -// EnsureFreshWithContext will refresh the token if it will expire within the refresh window (as set by -// RefreshWithin) and autoRefresh flag is on. This method is safe for concurrent use. -func (mt *MultiTenantServicePrincipalToken) EnsureFreshWithContext(ctx context.Context) error { - if err := mt.PrimaryToken.EnsureFreshWithContext(ctx); err != nil { - return fmt.Errorf("failed to refresh primary token: %w", err) - } - for _, aux := range mt.AuxiliaryTokens { - if err := aux.EnsureFreshWithContext(ctx); err != nil { - return fmt.Errorf("failed to refresh auxiliary token: %w", err) - } - } - return nil -} - -// RefreshWithContext obtains a fresh token for the Service Principal. -func (mt *MultiTenantServicePrincipalToken) RefreshWithContext(ctx context.Context) error { - if err := mt.PrimaryToken.RefreshWithContext(ctx); err != nil { - return fmt.Errorf("failed to refresh primary token: %w", err) - } - for _, aux := range mt.AuxiliaryTokens { - if err := aux.RefreshWithContext(ctx); err != nil { - return fmt.Errorf("failed to refresh auxiliary token: %w", err) - } - } - return nil -} - -// RefreshExchangeWithContext refreshes the token, but for a different resource. -func (mt *MultiTenantServicePrincipalToken) RefreshExchangeWithContext(ctx context.Context, resource string) error { - if err := mt.PrimaryToken.RefreshExchangeWithContext(ctx, resource); err != nil { - return fmt.Errorf("failed to refresh primary token: %w", err) - } - for _, aux := range mt.AuxiliaryTokens { - if err := aux.RefreshExchangeWithContext(ctx, resource); err != nil { - return fmt.Errorf("failed to refresh auxiliary token: %w", err) - } - } - return nil -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/token_legacy.go b/vendor/github.com/Azure/go-autorest/autorest/adal/token_legacy.go deleted file mode 100644 index 27ec4efa..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/adal/token_legacy.go +++ /dev/null @@ -1,75 +0,0 @@ -//go:build !go1.13 -// +build !go1.13 - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package adal - -import ( - "context" - "net/http" - "time" -) - -func getMSIEndpoint(ctx context.Context, sender Sender) (*http.Response, error) { - tempCtx, cancel := context.WithTimeout(ctx, 2*time.Second) - defer cancel() - req, _ := http.NewRequest(http.MethodGet, msiEndpoint, nil) - req = req.WithContext(tempCtx) - q := req.URL.Query() - q.Add("api-version", msiAPIVersion) - req.URL.RawQuery = q.Encode() - return sender.Do(req) -} - -// EnsureFreshWithContext will refresh the token if it will expire within the refresh window (as set by -// RefreshWithin) and autoRefresh flag is on. This method is safe for concurrent use. -func (mt *MultiTenantServicePrincipalToken) EnsureFreshWithContext(ctx context.Context) error { - if err := mt.PrimaryToken.EnsureFreshWithContext(ctx); err != nil { - return err - } - for _, aux := range mt.AuxiliaryTokens { - if err := aux.EnsureFreshWithContext(ctx); err != nil { - return err - } - } - return nil -} - -// RefreshWithContext obtains a fresh token for the Service Principal. -func (mt *MultiTenantServicePrincipalToken) RefreshWithContext(ctx context.Context) error { - if err := mt.PrimaryToken.RefreshWithContext(ctx); err != nil { - return err - } - for _, aux := range mt.AuxiliaryTokens { - if err := aux.RefreshWithContext(ctx); err != nil { - return err - } - } - return nil -} - -// RefreshExchangeWithContext refreshes the token, but for a different resource. -func (mt *MultiTenantServicePrincipalToken) RefreshExchangeWithContext(ctx context.Context, resource string) error { - if err := mt.PrimaryToken.RefreshExchangeWithContext(ctx, resource); err != nil { - return err - } - for _, aux := range mt.AuxiliaryTokens { - if err := aux.RefreshExchangeWithContext(ctx, resource); err != nil { - return err - } - } - return nil -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/adal/version.go b/vendor/github.com/Azure/go-autorest/autorest/adal/version.go deleted file mode 100644 index c867b348..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/adal/version.go +++ /dev/null @@ -1,45 +0,0 @@ -package adal - -import ( - "fmt" - "runtime" -) - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -const number = "v1.0.0" - -var ( - ua = fmt.Sprintf("Go/%s (%s-%s) go-autorest/adal/%s", - runtime.Version(), - runtime.GOARCH, - runtime.GOOS, - number, - ) -) - -// UserAgent returns a string containing the Go version, system architecture and OS, and the adal version. -func UserAgent() string { - return ua -} - -// AddToUserAgent adds an extension to the current user agent -func AddToUserAgent(extension string) error { - if extension != "" { - ua = fmt.Sprintf("%s %s", ua, extension) - return nil - } - return fmt.Errorf("Extension was empty, User Agent remained as '%s'", ua) -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/authorization.go b/vendor/github.com/Azure/go-autorest/autorest/authorization.go deleted file mode 100644 index 1226c411..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/authorization.go +++ /dev/null @@ -1,353 +0,0 @@ -package autorest - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import ( - "crypto/tls" - "encoding/base64" - "fmt" - "net/http" - "net/url" - "strings" - - "github.com/Azure/go-autorest/autorest/adal" -) - -const ( - bearerChallengeHeader = "Www-Authenticate" - bearer = "Bearer" - tenantID = "tenantID" - apiKeyAuthorizerHeader = "Ocp-Apim-Subscription-Key" - bingAPISdkHeader = "X-BingApis-SDK-Client" - golangBingAPISdkHeaderValue = "Go-SDK" - authorization = "Authorization" - basic = "Basic" -) - -// Authorizer is the interface that provides a PrepareDecorator used to supply request -// authorization. Most often, the Authorizer decorator runs last so it has access to the full -// state of the formed HTTP request. -type Authorizer interface { - WithAuthorization() PrepareDecorator -} - -// NullAuthorizer implements a default, "do nothing" Authorizer. -type NullAuthorizer struct{} - -// WithAuthorization returns a PrepareDecorator that does nothing. -func (na NullAuthorizer) WithAuthorization() PrepareDecorator { - return WithNothing() -} - -// APIKeyAuthorizer implements API Key authorization. -type APIKeyAuthorizer struct { - headers map[string]interface{} - queryParameters map[string]interface{} -} - -// NewAPIKeyAuthorizerWithHeaders creates an ApiKeyAuthorizer with headers. -func NewAPIKeyAuthorizerWithHeaders(headers map[string]interface{}) *APIKeyAuthorizer { - return NewAPIKeyAuthorizer(headers, nil) -} - -// NewAPIKeyAuthorizerWithQueryParameters creates an ApiKeyAuthorizer with query parameters. -func NewAPIKeyAuthorizerWithQueryParameters(queryParameters map[string]interface{}) *APIKeyAuthorizer { - return NewAPIKeyAuthorizer(nil, queryParameters) -} - -// NewAPIKeyAuthorizer creates an ApiKeyAuthorizer with headers. -func NewAPIKeyAuthorizer(headers map[string]interface{}, queryParameters map[string]interface{}) *APIKeyAuthorizer { - return &APIKeyAuthorizer{headers: headers, queryParameters: queryParameters} -} - -// WithAuthorization returns a PrepareDecorator that adds an HTTP headers and Query Parameters. -func (aka *APIKeyAuthorizer) WithAuthorization() PrepareDecorator { - return func(p Preparer) Preparer { - return DecoratePreparer(p, WithHeaders(aka.headers), WithQueryParameters(aka.queryParameters)) - } -} - -// CognitiveServicesAuthorizer implements authorization for Cognitive Services. -type CognitiveServicesAuthorizer struct { - subscriptionKey string -} - -// NewCognitiveServicesAuthorizer is -func NewCognitiveServicesAuthorizer(subscriptionKey string) *CognitiveServicesAuthorizer { - return &CognitiveServicesAuthorizer{subscriptionKey: subscriptionKey} -} - -// WithAuthorization is -func (csa *CognitiveServicesAuthorizer) WithAuthorization() PrepareDecorator { - headers := make(map[string]interface{}) - headers[apiKeyAuthorizerHeader] = csa.subscriptionKey - headers[bingAPISdkHeader] = golangBingAPISdkHeaderValue - - return NewAPIKeyAuthorizerWithHeaders(headers).WithAuthorization() -} - -// BearerAuthorizer implements the bearer authorization -type BearerAuthorizer struct { - tokenProvider adal.OAuthTokenProvider -} - -// NewBearerAuthorizer crates a BearerAuthorizer using the given token provider -func NewBearerAuthorizer(tp adal.OAuthTokenProvider) *BearerAuthorizer { - return &BearerAuthorizer{tokenProvider: tp} -} - -// WithAuthorization returns a PrepareDecorator that adds an HTTP Authorization header whose -// value is "Bearer " followed by the token. -// -// By default, the token will be automatically refreshed through the Refresher interface. -func (ba *BearerAuthorizer) WithAuthorization() PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err == nil { - // the ordering is important here, prefer RefresherWithContext if available - if refresher, ok := ba.tokenProvider.(adal.RefresherWithContext); ok { - err = refresher.EnsureFreshWithContext(r.Context()) - } else if refresher, ok := ba.tokenProvider.(adal.Refresher); ok { - err = refresher.EnsureFresh() - } - if err != nil { - var resp *http.Response - if tokError, ok := err.(adal.TokenRefreshError); ok { - resp = tokError.Response() - } - return r, NewErrorWithError(err, "azure.BearerAuthorizer", "WithAuthorization", resp, - "Failed to refresh the Token for request to %s", r.URL) - } - return Prepare(r, WithHeader(headerAuthorization, fmt.Sprintf("Bearer %s", ba.tokenProvider.OAuthToken()))) - } - return r, err - }) - } -} - -// TokenProvider returns OAuthTokenProvider so that it can be used for authorization outside the REST. -func (ba *BearerAuthorizer) TokenProvider() adal.OAuthTokenProvider { - return ba.tokenProvider -} - -// BearerAuthorizerCallbackFunc is the authentication callback signature. -type BearerAuthorizerCallbackFunc func(tenantID, resource string) (*BearerAuthorizer, error) - -// BearerAuthorizerCallback implements bearer authorization via a callback. -type BearerAuthorizerCallback struct { - sender Sender - callback BearerAuthorizerCallbackFunc -} - -// NewBearerAuthorizerCallback creates a bearer authorization callback. The callback -// is invoked when the HTTP request is submitted. -func NewBearerAuthorizerCallback(s Sender, callback BearerAuthorizerCallbackFunc) *BearerAuthorizerCallback { - if s == nil { - s = sender(tls.RenegotiateNever) - } - return &BearerAuthorizerCallback{sender: s, callback: callback} -} - -// WithAuthorization returns a PrepareDecorator that adds an HTTP Authorization header whose value -// is "Bearer " followed by the token. The BearerAuthorizer is obtained via a user-supplied callback. -// -// By default, the token will be automatically refreshed through the Refresher interface. -func (bacb *BearerAuthorizerCallback) WithAuthorization() PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err == nil { - // make a copy of the request and remove the body as it's not - // required and avoids us having to create a copy of it. - rCopy := *r - removeRequestBody(&rCopy) - - resp, err := bacb.sender.Do(&rCopy) - if err != nil { - return r, err - } - DrainResponseBody(resp) - if resp.StatusCode == 401 && hasBearerChallenge(resp.Header) { - bc, err := newBearerChallenge(resp.Header) - if err != nil { - return r, err - } - if bacb.callback != nil { - ba, err := bacb.callback(bc.values[tenantID], bc.values["resource"]) - if err != nil { - return r, err - } - return Prepare(r, ba.WithAuthorization()) - } - } - } - return r, err - }) - } -} - -// returns true if the HTTP response contains a bearer challenge -func hasBearerChallenge(header http.Header) bool { - authHeader := header.Get(bearerChallengeHeader) - if len(authHeader) == 0 || strings.Index(authHeader, bearer) < 0 { - return false - } - return true -} - -type bearerChallenge struct { - values map[string]string -} - -func newBearerChallenge(header http.Header) (bc bearerChallenge, err error) { - challenge := strings.TrimSpace(header.Get(bearerChallengeHeader)) - trimmedChallenge := challenge[len(bearer)+1:] - - // challenge is a set of key=value pairs that are comma delimited - pairs := strings.Split(trimmedChallenge, ",") - if len(pairs) < 1 { - err = fmt.Errorf("challenge '%s' contains no pairs", challenge) - return bc, err - } - - bc.values = make(map[string]string) - for i := range pairs { - trimmedPair := strings.TrimSpace(pairs[i]) - pair := strings.Split(trimmedPair, "=") - if len(pair) == 2 { - // remove the enclosing quotes - key := strings.Trim(pair[0], "\"") - value := strings.Trim(pair[1], "\"") - - switch key { - case "authorization", "authorization_uri": - // strip the tenant ID from the authorization URL - asURL, err := url.Parse(value) - if err != nil { - return bc, err - } - bc.values[tenantID] = asURL.Path[1:] - default: - bc.values[key] = value - } - } - } - - return bc, err -} - -// EventGridKeyAuthorizer implements authorization for event grid using key authentication. -type EventGridKeyAuthorizer struct { - topicKey string -} - -// NewEventGridKeyAuthorizer creates a new EventGridKeyAuthorizer -// with the specified topic key. -func NewEventGridKeyAuthorizer(topicKey string) EventGridKeyAuthorizer { - return EventGridKeyAuthorizer{topicKey: topicKey} -} - -// WithAuthorization returns a PrepareDecorator that adds the aeg-sas-key authentication header. -func (egta EventGridKeyAuthorizer) WithAuthorization() PrepareDecorator { - headers := map[string]interface{}{ - "aeg-sas-key": egta.topicKey, - } - return NewAPIKeyAuthorizerWithHeaders(headers).WithAuthorization() -} - -// BasicAuthorizer implements basic HTTP authorization by adding the Authorization HTTP header -// with the value "Basic " where is a base64-encoded username:password tuple. -type BasicAuthorizer struct { - userName string - password string -} - -// NewBasicAuthorizer creates a new BasicAuthorizer with the specified username and password. -func NewBasicAuthorizer(userName, password string) *BasicAuthorizer { - return &BasicAuthorizer{ - userName: userName, - password: password, - } -} - -// WithAuthorization returns a PrepareDecorator that adds an HTTP Authorization header whose -// value is "Basic " followed by the base64-encoded username:password tuple. -func (ba *BasicAuthorizer) WithAuthorization() PrepareDecorator { - headers := make(map[string]interface{}) - headers[authorization] = basic + " " + base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", ba.userName, ba.password))) - - return NewAPIKeyAuthorizerWithHeaders(headers).WithAuthorization() -} - -// MultiTenantServicePrincipalTokenAuthorizer provides authentication across tenants. -type MultiTenantServicePrincipalTokenAuthorizer interface { - WithAuthorization() PrepareDecorator -} - -// NewMultiTenantServicePrincipalTokenAuthorizer crates a BearerAuthorizer using the given token provider -func NewMultiTenantServicePrincipalTokenAuthorizer(tp adal.MultitenantOAuthTokenProvider) MultiTenantServicePrincipalTokenAuthorizer { - return NewMultiTenantBearerAuthorizer(tp) -} - -// MultiTenantBearerAuthorizer implements bearer authorization across multiple tenants. -type MultiTenantBearerAuthorizer struct { - tp adal.MultitenantOAuthTokenProvider -} - -// NewMultiTenantBearerAuthorizer creates a MultiTenantBearerAuthorizer using the given token provider. -func NewMultiTenantBearerAuthorizer(tp adal.MultitenantOAuthTokenProvider) *MultiTenantBearerAuthorizer { - return &MultiTenantBearerAuthorizer{tp: tp} -} - -// WithAuthorization returns a PrepareDecorator that adds an HTTP Authorization header using the -// primary token along with the auxiliary authorization header using the auxiliary tokens. -// -// By default, the token will be automatically refreshed through the Refresher interface. -func (mt *MultiTenantBearerAuthorizer) WithAuthorization() PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err != nil { - return r, err - } - if refresher, ok := mt.tp.(adal.RefresherWithContext); ok { - err = refresher.EnsureFreshWithContext(r.Context()) - if err != nil { - var resp *http.Response - if tokError, ok := err.(adal.TokenRefreshError); ok { - resp = tokError.Response() - } - return r, NewErrorWithError(err, "azure.multiTenantSPTAuthorizer", "WithAuthorization", resp, - "Failed to refresh one or more Tokens for request to %s", r.URL) - } - } - r, err = Prepare(r, WithHeader(headerAuthorization, fmt.Sprintf("Bearer %s", mt.tp.PrimaryOAuthToken()))) - if err != nil { - return r, err - } - auxTokens := mt.tp.AuxiliaryOAuthTokens() - for i := range auxTokens { - auxTokens[i] = fmt.Sprintf("Bearer %s", auxTokens[i]) - } - return Prepare(r, WithHeader(headerAuxAuthorization, strings.Join(auxTokens, ", "))) - }) - } -} - -// TokenProvider returns the underlying MultitenantOAuthTokenProvider for this authorizer. -func (mt *MultiTenantBearerAuthorizer) TokenProvider() adal.MultitenantOAuthTokenProvider { - return mt.tp -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/authorization_sas.go b/vendor/github.com/Azure/go-autorest/autorest/authorization_sas.go deleted file mode 100644 index 66501493..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/authorization_sas.go +++ /dev/null @@ -1,66 +0,0 @@ -package autorest - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import ( - "fmt" - "net/http" - "strings" -) - -// SASTokenAuthorizer implements an authorization for SAS Token Authentication -// this can be used for interaction with Blob Storage Endpoints -type SASTokenAuthorizer struct { - sasToken string -} - -// NewSASTokenAuthorizer creates a SASTokenAuthorizer using the given credentials -func NewSASTokenAuthorizer(sasToken string) (*SASTokenAuthorizer, error) { - if strings.TrimSpace(sasToken) == "" { - return nil, fmt.Errorf("sasToken cannot be empty") - } - - token := sasToken - if strings.HasPrefix(sasToken, "?") { - token = strings.TrimPrefix(sasToken, "?") - } - - return &SASTokenAuthorizer{ - sasToken: token, - }, nil -} - -// WithAuthorization returns a PrepareDecorator that adds a shared access signature token to the -// URI's query parameters. This can be used for the Blob, Queue, and File Services. -// -// See https://docs.microsoft.com/en-us/rest/api/storageservices/delegate-access-with-shared-access-signature -func (sas *SASTokenAuthorizer) WithAuthorization() PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err != nil { - return r, err - } - - if r.URL.RawQuery == "" { - r.URL.RawQuery = sas.sasToken - } else if !strings.Contains(r.URL.RawQuery, sas.sasToken) { - r.URL.RawQuery = fmt.Sprintf("%s&%s", r.URL.RawQuery, sas.sasToken) - } - - return Prepare(r) - }) - } -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/authorization_storage.go b/vendor/github.com/Azure/go-autorest/autorest/authorization_storage.go deleted file mode 100644 index c58d7b7b..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/authorization_storage.go +++ /dev/null @@ -1,307 +0,0 @@ -package autorest - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import ( - "bytes" - "crypto/hmac" - "crypto/sha256" - "encoding/base64" - "fmt" - "net/http" - "net/url" - "sort" - "strings" - "time" -) - -// SharedKeyType defines the enumeration for the various shared key types. -// See https://docs.microsoft.com/en-us/rest/api/storageservices/authorize-with-shared-key for details on the shared key types. -type SharedKeyType string - -const ( - // SharedKey is used to authorize against blobs, files and queues services. - SharedKey SharedKeyType = "sharedKey" - - // SharedKeyForTable is used to authorize against the table service. - SharedKeyForTable SharedKeyType = "sharedKeyTable" - - // SharedKeyLite is used to authorize against blobs, files and queues services. It's provided for - // backwards compatibility with API versions before 2009-09-19. Prefer SharedKey instead. - SharedKeyLite SharedKeyType = "sharedKeyLite" - - // SharedKeyLiteForTable is used to authorize against the table service. It's provided for - // backwards compatibility with older table API versions. Prefer SharedKeyForTable instead. - SharedKeyLiteForTable SharedKeyType = "sharedKeyLiteTable" -) - -const ( - headerAccept = "Accept" - headerAcceptCharset = "Accept-Charset" - headerContentEncoding = "Content-Encoding" - headerContentLength = "Content-Length" - headerContentMD5 = "Content-MD5" - headerContentLanguage = "Content-Language" - headerIfModifiedSince = "If-Modified-Since" - headerIfMatch = "If-Match" - headerIfNoneMatch = "If-None-Match" - headerIfUnmodifiedSince = "If-Unmodified-Since" - headerDate = "Date" - headerXMSDate = "X-Ms-Date" - headerXMSVersion = "x-ms-version" - headerRange = "Range" -) - -const storageEmulatorAccountName = "devstoreaccount1" - -// SharedKeyAuthorizer implements an authorization for Shared Key -// this can be used for interaction with Blob, File and Queue Storage Endpoints -type SharedKeyAuthorizer struct { - accountName string - accountKey []byte - keyType SharedKeyType -} - -// NewSharedKeyAuthorizer creates a SharedKeyAuthorizer using the provided credentials and shared key type. -func NewSharedKeyAuthorizer(accountName, accountKey string, keyType SharedKeyType) (*SharedKeyAuthorizer, error) { - key, err := base64.StdEncoding.DecodeString(accountKey) - if err != nil { - return nil, fmt.Errorf("malformed storage account key: %v", err) - } - return &SharedKeyAuthorizer{ - accountName: accountName, - accountKey: key, - keyType: keyType, - }, nil -} - -// WithAuthorization returns a PrepareDecorator that adds an HTTP Authorization header whose -// value is " " followed by the computed key. -// This can be used for the Blob, Queue, and File Services -// -// from: https://docs.microsoft.com/en-us/rest/api/storageservices/authorize-with-shared-key -// You may use Shared Key authorization to authorize a request made against the -// 2009-09-19 version and later of the Blob and Queue services, -// and version 2014-02-14 and later of the File services. -func (sk *SharedKeyAuthorizer) WithAuthorization() PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err != nil { - return r, err - } - - sk, err := buildSharedKey(sk.accountName, sk.accountKey, r, sk.keyType) - if err != nil { - return r, err - } - return Prepare(r, WithHeader(headerAuthorization, sk)) - }) - } -} - -func buildSharedKey(accName string, accKey []byte, req *http.Request, keyType SharedKeyType) (string, error) { - canRes, err := buildCanonicalizedResource(accName, req.URL.String(), keyType) - if err != nil { - return "", err - } - - if req.Header == nil { - req.Header = http.Header{} - } - - // ensure date is set - if req.Header.Get(headerDate) == "" && req.Header.Get(headerXMSDate) == "" { - date := time.Now().UTC().Format(http.TimeFormat) - req.Header.Set(headerXMSDate, date) - } - canString, err := buildCanonicalizedString(req.Method, req.Header, canRes, keyType) - if err != nil { - return "", err - } - return createAuthorizationHeader(accName, accKey, canString, keyType), nil -} - -func buildCanonicalizedResource(accountName, uri string, keyType SharedKeyType) (string, error) { - errMsg := "buildCanonicalizedResource error: %s" - u, err := url.Parse(uri) - if err != nil { - return "", fmt.Errorf(errMsg, err.Error()) - } - - cr := bytes.NewBufferString("") - if accountName != storageEmulatorAccountName { - cr.WriteString("/") - cr.WriteString(getCanonicalizedAccountName(accountName)) - } - - if len(u.Path) > 0 { - // Any portion of the CanonicalizedResource string that is derived from - // the resource's URI should be encoded exactly as it is in the URI. - // -- https://msdn.microsoft.com/en-gb/library/azure/dd179428.aspx - cr.WriteString(u.EscapedPath()) - } else { - // a slash is required to indicate the root path - cr.WriteString("/") - } - - params, err := url.ParseQuery(u.RawQuery) - if err != nil { - return "", fmt.Errorf(errMsg, err.Error()) - } - - // See https://github.com/Azure/azure-storage-net/blob/master/Lib/Common/Core/Util/AuthenticationUtility.cs#L277 - if keyType == SharedKey { - if len(params) > 0 { - cr.WriteString("\n") - - keys := []string{} - for key := range params { - keys = append(keys, key) - } - sort.Strings(keys) - - completeParams := []string{} - for _, key := range keys { - if len(params[key]) > 1 { - sort.Strings(params[key]) - } - - completeParams = append(completeParams, fmt.Sprintf("%s:%s", key, strings.Join(params[key], ","))) - } - cr.WriteString(strings.Join(completeParams, "\n")) - } - } else { - // search for "comp" parameter, if exists then add it to canonicalizedresource - if v, ok := params["comp"]; ok { - cr.WriteString("?comp=" + v[0]) - } - } - - return cr.String(), nil -} - -func getCanonicalizedAccountName(accountName string) string { - // since we may be trying to access a secondary storage account, we need to - // remove the -secondary part of the storage name - return strings.TrimSuffix(accountName, "-secondary") -} - -func buildCanonicalizedString(verb string, headers http.Header, canonicalizedResource string, keyType SharedKeyType) (string, error) { - contentLength := headers.Get(headerContentLength) - if contentLength == "0" { - contentLength = "" - } - date := headers.Get(headerDate) - if v := headers.Get(headerXMSDate); v != "" { - if keyType == SharedKey || keyType == SharedKeyLite { - date = "" - } else { - date = v - } - } - var canString string - switch keyType { - case SharedKey: - canString = strings.Join([]string{ - verb, - headers.Get(headerContentEncoding), - headers.Get(headerContentLanguage), - contentLength, - headers.Get(headerContentMD5), - headers.Get(headerContentType), - date, - headers.Get(headerIfModifiedSince), - headers.Get(headerIfMatch), - headers.Get(headerIfNoneMatch), - headers.Get(headerIfUnmodifiedSince), - headers.Get(headerRange), - buildCanonicalizedHeader(headers), - canonicalizedResource, - }, "\n") - case SharedKeyForTable: - canString = strings.Join([]string{ - verb, - headers.Get(headerContentMD5), - headers.Get(headerContentType), - date, - canonicalizedResource, - }, "\n") - case SharedKeyLite: - canString = strings.Join([]string{ - verb, - headers.Get(headerContentMD5), - headers.Get(headerContentType), - date, - buildCanonicalizedHeader(headers), - canonicalizedResource, - }, "\n") - case SharedKeyLiteForTable: - canString = strings.Join([]string{ - date, - canonicalizedResource, - }, "\n") - default: - return "", fmt.Errorf("key type '%s' is not supported", keyType) - } - return canString, nil -} - -func buildCanonicalizedHeader(headers http.Header) string { - cm := make(map[string]string) - - for k := range headers { - headerName := strings.TrimSpace(strings.ToLower(k)) - if strings.HasPrefix(headerName, "x-ms-") { - cm[headerName] = headers.Get(k) - } - } - - if len(cm) == 0 { - return "" - } - - keys := []string{} - for key := range cm { - keys = append(keys, key) - } - - sort.Strings(keys) - - ch := bytes.NewBufferString("") - - for _, key := range keys { - ch.WriteString(key) - ch.WriteRune(':') - ch.WriteString(cm[key]) - ch.WriteRune('\n') - } - - return strings.TrimSuffix(ch.String(), "\n") -} - -func createAuthorizationHeader(accountName string, accountKey []byte, canonicalizedString string, keyType SharedKeyType) string { - h := hmac.New(sha256.New, accountKey) - h.Write([]byte(canonicalizedString)) - signature := base64.StdEncoding.EncodeToString(h.Sum(nil)) - var key string - switch keyType { - case SharedKey, SharedKeyForTable: - key = "SharedKey" - case SharedKeyLite, SharedKeyLiteForTable: - key = "SharedKeyLite" - } - return fmt.Sprintf("%s %s:%s", key, getCanonicalizedAccountName(accountName), signature) -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/autorest.go b/vendor/github.com/Azure/go-autorest/autorest/autorest.go deleted file mode 100644 index 211c98d1..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/autorest.go +++ /dev/null @@ -1,150 +0,0 @@ -/* -Package autorest implements an HTTP request pipeline suitable for use across multiple go-routines -and provides the shared routines relied on by AutoRest (see https://github.com/Azure/autorest/) -generated Go code. - -The package breaks sending and responding to HTTP requests into three phases: Preparing, Sending, -and Responding. A typical pattern is: - - req, err := Prepare(&http.Request{}, - token.WithAuthorization()) - - resp, err := Send(req, - WithLogging(logger), - DoErrorIfStatusCode(http.StatusInternalServerError), - DoCloseIfError(), - DoRetryForAttempts(5, time.Second)) - - err = Respond(resp, - ByDiscardingBody(), - ByClosing()) - -Each phase relies on decorators to modify and / or manage processing. Decorators may first modify -and then pass the data along, pass the data first and then modify the result, or wrap themselves -around passing the data (such as a logger might do). Decorators run in the order provided. For -example, the following: - - req, err := Prepare(&http.Request{}, - WithBaseURL("https://microsoft.com/"), - WithPath("a"), - WithPath("b"), - WithPath("c")) - -will set the URL to: - - https://microsoft.com/a/b/c - -Preparers and Responders may be shared and re-used (assuming the underlying decorators support -sharing and re-use). Performant use is obtained by creating one or more Preparers and Responders -shared among multiple go-routines, and a single Sender shared among multiple sending go-routines, -all bound together by means of input / output channels. - -Decorators hold their passed state within a closure (such as the path components in the example -above). Be careful to share Preparers and Responders only in a context where such held state -applies. For example, it may not make sense to share a Preparer that applies a query string from a -fixed set of values. Similarly, sharing a Responder that reads the response body into a passed -struct (e.g., ByUnmarshallingJson) is likely incorrect. - -Lastly, the Swagger specification (https://swagger.io) that drives AutoRest -(https://github.com/Azure/autorest/) precisely defines two date forms: date and date-time. The -github.com/Azure/go-autorest/autorest/date package provides time.Time derivations to ensure -correct parsing and formatting. - -Errors raised by autorest objects and methods will conform to the autorest.Error interface. - -See the included examples for more detail. For details on the suggested use of this package by -generated clients, see the Client described below. -*/ -package autorest - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import ( - "context" - "net/http" - "time" -) - -const ( - // HeaderLocation specifies the HTTP Location header. - HeaderLocation = "Location" - - // HeaderRetryAfter specifies the HTTP Retry-After header. - HeaderRetryAfter = "Retry-After" -) - -// ResponseHasStatusCode returns true if the status code in the HTTP Response is in the passed set -// and false otherwise. -func ResponseHasStatusCode(resp *http.Response, codes ...int) bool { - if resp == nil { - return false - } - return containsInt(codes, resp.StatusCode) -} - -// GetLocation retrieves the URL from the Location header of the passed response. -func GetLocation(resp *http.Response) string { - return resp.Header.Get(HeaderLocation) -} - -// GetRetryAfter extracts the retry delay from the Retry-After header of the passed response. If -// the header is absent or is malformed, it will return the supplied default delay time.Duration. -func GetRetryAfter(resp *http.Response, defaultDelay time.Duration) time.Duration { - retry := resp.Header.Get(HeaderRetryAfter) - if retry == "" { - return defaultDelay - } - - d, err := time.ParseDuration(retry + "s") - if err != nil { - return defaultDelay - } - - return d -} - -// NewPollingRequest allocates and returns a new http.Request to poll for the passed response. -func NewPollingRequest(resp *http.Response, cancel <-chan struct{}) (*http.Request, error) { - location := GetLocation(resp) - if location == "" { - return nil, NewErrorWithResponse("autorest", "NewPollingRequest", resp, "Location header missing from response that requires polling") - } - - req, err := Prepare(&http.Request{Cancel: cancel}, - AsGet(), - WithBaseURL(location)) - if err != nil { - return nil, NewErrorWithError(err, "autorest", "NewPollingRequest", nil, "Failure creating poll request to %s", location) - } - - return req, nil -} - -// NewPollingRequestWithContext allocates and returns a new http.Request with the specified context to poll for the passed response. -func NewPollingRequestWithContext(ctx context.Context, resp *http.Response) (*http.Request, error) { - location := GetLocation(resp) - if location == "" { - return nil, NewErrorWithResponse("autorest", "NewPollingRequestWithContext", resp, "Location header missing from response that requires polling") - } - - req, err := Prepare((&http.Request{}).WithContext(ctx), - AsGet(), - WithBaseURL(location)) - if err != nil { - return nil, NewErrorWithError(err, "autorest", "NewPollingRequestWithContext", nil, "Failure creating poll request to %s", location) - } - - return req, nil -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/async.go b/vendor/github.com/Azure/go-autorest/autorest/azure/async.go deleted file mode 100644 index f119b11d..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/azure/async.go +++ /dev/null @@ -1,995 +0,0 @@ -package azure - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "io" - "net/http" - "net/url" - "strings" - "time" - - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/logger" - "github.com/Azure/go-autorest/tracing" -) - -const ( - headerAsyncOperation = "Azure-AsyncOperation" -) - -const ( - operationInProgress string = "InProgress" - operationCanceled string = "Canceled" - operationFailed string = "Failed" - operationSucceeded string = "Succeeded" -) - -var pollingCodes = [...]int{http.StatusNoContent, http.StatusAccepted, http.StatusCreated, http.StatusOK} - -// FutureAPI contains the set of methods on the Future type. -type FutureAPI interface { - // Response returns the last HTTP response. - Response() *http.Response - - // Status returns the last status message of the operation. - Status() string - - // PollingMethod returns the method used to monitor the status of the asynchronous operation. - PollingMethod() PollingMethodType - - // DoneWithContext queries the service to see if the operation has completed. - DoneWithContext(context.Context, autorest.Sender) (bool, error) - - // GetPollingDelay returns a duration the application should wait before checking - // the status of the asynchronous request and true; this value is returned from - // the service via the Retry-After response header. If the header wasn't returned - // then the function returns the zero-value time.Duration and false. - GetPollingDelay() (time.Duration, bool) - - // WaitForCompletionRef will return when one of the following conditions is met: the long - // running operation has completed, the provided context is cancelled, or the client's - // polling duration has been exceeded. It will retry failed polling attempts based on - // the retry value defined in the client up to the maximum retry attempts. - // If no deadline is specified in the context then the client.PollingDuration will be - // used to determine if a default deadline should be used. - // If PollingDuration is greater than zero the value will be used as the context's timeout. - // If PollingDuration is zero then no default deadline will be used. - WaitForCompletionRef(context.Context, autorest.Client) error - - // MarshalJSON implements the json.Marshaler interface. - MarshalJSON() ([]byte, error) - - // MarshalJSON implements the json.Unmarshaler interface. - UnmarshalJSON([]byte) error - - // PollingURL returns the URL used for retrieving the status of the long-running operation. - PollingURL() string - - // GetResult should be called once polling has completed successfully. - // It makes the final GET call to retrieve the resultant payload. - GetResult(autorest.Sender) (*http.Response, error) -} - -var _ FutureAPI = (*Future)(nil) - -// Future provides a mechanism to access the status and results of an asynchronous request. -// Since futures are stateful they should be passed by value to avoid race conditions. -type Future struct { - pt pollingTracker -} - -// NewFutureFromResponse returns a new Future object initialized -// with the initial response from an asynchronous operation. -func NewFutureFromResponse(resp *http.Response) (Future, error) { - pt, err := createPollingTracker(resp) - return Future{pt: pt}, err -} - -// Response returns the last HTTP response. -func (f Future) Response() *http.Response { - if f.pt == nil { - return nil - } - return f.pt.latestResponse() -} - -// Status returns the last status message of the operation. -func (f Future) Status() string { - if f.pt == nil { - return "" - } - return f.pt.pollingStatus() -} - -// PollingMethod returns the method used to monitor the status of the asynchronous operation. -func (f Future) PollingMethod() PollingMethodType { - if f.pt == nil { - return PollingUnknown - } - return f.pt.pollingMethod() -} - -// DoneWithContext queries the service to see if the operation has completed. -func (f *Future) DoneWithContext(ctx context.Context, sender autorest.Sender) (done bool, err error) { - ctx = tracing.StartSpan(ctx, "github.com/Azure/go-autorest/autorest/azure/async.DoneWithContext") - defer func() { - sc := -1 - resp := f.Response() - if resp != nil { - sc = resp.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - - if f.pt == nil { - return false, autorest.NewError("Future", "Done", "future is not initialized") - } - if f.pt.hasTerminated() { - return true, f.pt.pollingError() - } - if err := f.pt.pollForStatus(ctx, sender); err != nil { - return false, err - } - if err := f.pt.checkForErrors(); err != nil { - return f.pt.hasTerminated(), err - } - if err := f.pt.updatePollingState(f.pt.provisioningStateApplicable()); err != nil { - return false, err - } - if err := f.pt.initPollingMethod(); err != nil { - return false, err - } - if err := f.pt.updatePollingMethod(); err != nil { - return false, err - } - return f.pt.hasTerminated(), f.pt.pollingError() -} - -// GetPollingDelay returns a duration the application should wait before checking -// the status of the asynchronous request and true; this value is returned from -// the service via the Retry-After response header. If the header wasn't returned -// then the function returns the zero-value time.Duration and false. -func (f Future) GetPollingDelay() (time.Duration, bool) { - if f.pt == nil { - return 0, false - } - resp := f.pt.latestResponse() - if resp == nil { - return 0, false - } - - retry := resp.Header.Get(autorest.HeaderRetryAfter) - if retry == "" { - return 0, false - } - - d, err := time.ParseDuration(retry + "s") - if err != nil { - panic(err) - } - - return d, true -} - -// WaitForCompletionRef will return when one of the following conditions is met: the long -// running operation has completed, the provided context is cancelled, or the client's -// polling duration has been exceeded. It will retry failed polling attempts based on -// the retry value defined in the client up to the maximum retry attempts. -// If no deadline is specified in the context then the client.PollingDuration will be -// used to determine if a default deadline should be used. -// If PollingDuration is greater than zero the value will be used as the context's timeout. -// If PollingDuration is zero then no default deadline will be used. -func (f *Future) WaitForCompletionRef(ctx context.Context, client autorest.Client) (err error) { - ctx = tracing.StartSpan(ctx, "github.com/Azure/go-autorest/autorest/azure/async.WaitForCompletionRef") - defer func() { - sc := -1 - resp := f.Response() - if resp != nil { - sc = resp.StatusCode - } - tracing.EndSpan(ctx, sc, err) - }() - cancelCtx := ctx - // if the provided context already has a deadline don't override it - _, hasDeadline := ctx.Deadline() - if d := client.PollingDuration; !hasDeadline && d != 0 { - var cancel context.CancelFunc - cancelCtx, cancel = context.WithTimeout(ctx, d) - defer cancel() - } - // if the initial response has a Retry-After, sleep for the specified amount of time before starting to poll - if delay, ok := f.GetPollingDelay(); ok { - logger.Instance.Writeln(logger.LogInfo, "WaitForCompletionRef: initial polling delay") - if delayElapsed := autorest.DelayForBackoff(delay, 0, cancelCtx.Done()); !delayElapsed { - err = cancelCtx.Err() - return - } - } - done, err := f.DoneWithContext(ctx, client) - for attempts := 0; !done; done, err = f.DoneWithContext(ctx, client) { - if attempts >= client.RetryAttempts { - return autorest.NewErrorWithError(err, "Future", "WaitForCompletion", f.pt.latestResponse(), "the number of retries has been exceeded") - } - // we want delayAttempt to be zero in the non-error case so - // that DelayForBackoff doesn't perform exponential back-off - var delayAttempt int - var delay time.Duration - if err == nil { - // check for Retry-After delay, if not present use the client's polling delay - var ok bool - delay, ok = f.GetPollingDelay() - if !ok { - logger.Instance.Writeln(logger.LogInfo, "WaitForCompletionRef: Using client polling delay") - delay = client.PollingDelay - } - } else { - // there was an error polling for status so perform exponential - // back-off based on the number of attempts using the client's retry - // duration. update attempts after delayAttempt to avoid off-by-one. - logger.Instance.Writef(logger.LogError, "WaitForCompletionRef: %s\n", err) - delayAttempt = attempts - delay = client.RetryDuration - attempts++ - } - // wait until the delay elapses or the context is cancelled - delayElapsed := autorest.DelayForBackoff(delay, delayAttempt, cancelCtx.Done()) - if !delayElapsed { - return autorest.NewErrorWithError(cancelCtx.Err(), "Future", "WaitForCompletion", f.pt.latestResponse(), "context has been cancelled") - } - } - return -} - -// MarshalJSON implements the json.Marshaler interface. -func (f Future) MarshalJSON() ([]byte, error) { - return json.Marshal(f.pt) -} - -// UnmarshalJSON implements the json.Unmarshaler interface. -func (f *Future) UnmarshalJSON(data []byte) error { - // unmarshal into JSON object to determine the tracker type - obj := map[string]interface{}{} - err := json.Unmarshal(data, &obj) - if err != nil { - return err - } - if obj["method"] == nil { - return autorest.NewError("Future", "UnmarshalJSON", "missing 'method' property") - } - method := obj["method"].(string) - switch strings.ToUpper(method) { - case http.MethodDelete: - f.pt = &pollingTrackerDelete{} - case http.MethodPatch: - f.pt = &pollingTrackerPatch{} - case http.MethodPost: - f.pt = &pollingTrackerPost{} - case http.MethodPut: - f.pt = &pollingTrackerPut{} - default: - return autorest.NewError("Future", "UnmarshalJSON", "unsupoorted method '%s'", method) - } - // now unmarshal into the tracker - return json.Unmarshal(data, &f.pt) -} - -// PollingURL returns the URL used for retrieving the status of the long-running operation. -func (f Future) PollingURL() string { - if f.pt == nil { - return "" - } - return f.pt.pollingURL() -} - -// GetResult should be called once polling has completed successfully. -// It makes the final GET call to retrieve the resultant payload. -func (f Future) GetResult(sender autorest.Sender) (*http.Response, error) { - if f.pt.finalGetURL() == "" { - // we can end up in this situation if the async operation returns a 200 - // with no polling URLs. in that case return the response which should - // contain the JSON payload (only do this for successful terminal cases). - if lr := f.pt.latestResponse(); lr != nil && f.pt.hasSucceeded() { - return lr, nil - } - return nil, autorest.NewError("Future", "GetResult", "missing URL for retrieving result") - } - req, err := http.NewRequest(http.MethodGet, f.pt.finalGetURL(), nil) - if err != nil { - return nil, err - } - resp, err := sender.Do(req) - if err == nil && resp.Body != nil { - // copy the body and close it so callers don't have to - defer resp.Body.Close() - b, err := io.ReadAll(resp.Body) - if err != nil { - return resp, err - } - resp.Body = io.NopCloser(bytes.NewReader(b)) - } - return resp, err -} - -type pollingTracker interface { - // these methods can differ per tracker - - // checks the response headers and status code to determine the polling mechanism - updatePollingMethod() error - - // checks the response for tracker-specific error conditions - checkForErrors() error - - // returns true if provisioning state should be checked - provisioningStateApplicable() bool - - // methods common to all trackers - - // initializes a tracker's polling URL and method, called for each iteration. - // these values can be overridden by each polling tracker as required. - initPollingMethod() error - - // initializes the tracker's internal state, call this when the tracker is created - initializeState() error - - // makes an HTTP request to check the status of the LRO - pollForStatus(ctx context.Context, sender autorest.Sender) error - - // updates internal tracker state, call this after each call to pollForStatus - updatePollingState(provStateApl bool) error - - // returns the error response from the service, can be nil - pollingError() error - - // returns the polling method being used - pollingMethod() PollingMethodType - - // returns the state of the LRO as returned from the service - pollingStatus() string - - // returns the URL used for polling status - pollingURL() string - - // returns the URL used for the final GET to retrieve the resource - finalGetURL() string - - // returns true if the LRO is in a terminal state - hasTerminated() bool - - // returns true if the LRO is in a failed terminal state - hasFailed() bool - - // returns true if the LRO is in a successful terminal state - hasSucceeded() bool - - // returns the cached HTTP response after a call to pollForStatus(), can be nil - latestResponse() *http.Response -} - -type pollingTrackerBase struct { - // resp is the last response, either from the submission of the LRO or from polling - resp *http.Response - - // method is the HTTP verb, this is needed for deserialization - Method string `json:"method"` - - // rawBody is the raw JSON response body - rawBody map[string]interface{} - - // denotes if polling is using async-operation or location header - Pm PollingMethodType `json:"pollingMethod"` - - // the URL to poll for status - URI string `json:"pollingURI"` - - // the state of the LRO as returned from the service - State string `json:"lroState"` - - // the URL to GET for the final result - FinalGetURI string `json:"resultURI"` - - // used to hold an error object returned from the service - Err *ServiceError `json:"error,omitempty"` -} - -func (pt *pollingTrackerBase) initializeState() error { - // determine the initial polling state based on response body and/or HTTP status - // code. this is applicable to the initial LRO response, not polling responses! - pt.Method = pt.resp.Request.Method - if err := pt.updateRawBody(); err != nil { - return err - } - switch pt.resp.StatusCode { - case http.StatusOK: - if ps := pt.getProvisioningState(); ps != nil { - pt.State = *ps - if pt.hasFailed() { - pt.updateErrorFromResponse() - return pt.pollingError() - } - } else { - pt.State = operationSucceeded - } - case http.StatusCreated: - if ps := pt.getProvisioningState(); ps != nil { - pt.State = *ps - } else { - pt.State = operationInProgress - } - case http.StatusAccepted: - pt.State = operationInProgress - case http.StatusNoContent: - pt.State = operationSucceeded - default: - pt.State = operationFailed - pt.updateErrorFromResponse() - return pt.pollingError() - } - return pt.initPollingMethod() -} - -func (pt pollingTrackerBase) getProvisioningState() *string { - if pt.rawBody != nil && pt.rawBody["properties"] != nil { - p := pt.rawBody["properties"].(map[string]interface{}) - if ps := p["provisioningState"]; ps != nil { - s := ps.(string) - return &s - } - } - return nil -} - -func (pt *pollingTrackerBase) updateRawBody() error { - pt.rawBody = map[string]interface{}{} - if pt.resp.ContentLength != 0 { - defer pt.resp.Body.Close() - b, err := io.ReadAll(pt.resp.Body) - if err != nil { - return autorest.NewErrorWithError(err, "pollingTrackerBase", "updateRawBody", nil, "failed to read response body") - } - // put the body back so it's available to other callers - pt.resp.Body = io.NopCloser(bytes.NewReader(b)) - // observed in 204 responses over HTTP/2.0; the content length is -1 but body is empty - if len(b) == 0 { - return nil - } - if err = json.Unmarshal(b, &pt.rawBody); err != nil { - return autorest.NewErrorWithError(err, "pollingTrackerBase", "updateRawBody", nil, "failed to unmarshal response body") - } - } - return nil -} - -func (pt *pollingTrackerBase) pollForStatus(ctx context.Context, sender autorest.Sender) error { - req, err := http.NewRequest(http.MethodGet, pt.URI, nil) - if err != nil { - return autorest.NewErrorWithError(err, "pollingTrackerBase", "pollForStatus", nil, "failed to create HTTP request") - } - - req = req.WithContext(ctx) - preparer := autorest.CreatePreparer(autorest.GetPrepareDecorators(ctx)...) - req, err = preparer.Prepare(req) - if err != nil { - return autorest.NewErrorWithError(err, "pollingTrackerBase", "pollForStatus", nil, "failed preparing HTTP request") - } - pt.resp, err = sender.Do(req) - if err != nil { - return autorest.NewErrorWithError(err, "pollingTrackerBase", "pollForStatus", nil, "failed to send HTTP request") - } - if autorest.ResponseHasStatusCode(pt.resp, pollingCodes[:]...) { - // reset the service error on success case - pt.Err = nil - err = pt.updateRawBody() - } else { - // check response body for error content - pt.updateErrorFromResponse() - err = pt.pollingError() - } - return err -} - -// attempts to unmarshal a ServiceError type from the response body. -// if that fails then make a best attempt at creating something meaningful. -// NOTE: this assumes that the async operation has failed. -func (pt *pollingTrackerBase) updateErrorFromResponse() { - var err error - if pt.resp.ContentLength != 0 { - type respErr struct { - ServiceError *ServiceError `json:"error"` - } - re := respErr{} - defer pt.resp.Body.Close() - var b []byte - if b, err = io.ReadAll(pt.resp.Body); err != nil { - goto Default - } - // put the body back so it's available to other callers - pt.resp.Body = io.NopCloser(bytes.NewReader(b)) - if len(b) == 0 { - goto Default - } - if err = json.Unmarshal(b, &re); err != nil { - goto Default - } - // unmarshalling the error didn't yield anything, try unwrapped error - if re.ServiceError == nil { - err = json.Unmarshal(b, &re.ServiceError) - if err != nil { - goto Default - } - } - // the unmarshaller will ensure re.ServiceError is non-nil - // even if there was no content unmarshalled so check the code. - if re.ServiceError.Code != "" { - pt.Err = re.ServiceError - return - } - } -Default: - se := &ServiceError{ - Code: pt.pollingStatus(), - Message: "The async operation failed.", - } - if err != nil { - se.InnerError = make(map[string]interface{}) - se.InnerError["unmarshalError"] = err.Error() - } - // stick the response body into the error object in hopes - // it contains something useful to help diagnose the failure. - if len(pt.rawBody) > 0 { - se.AdditionalInfo = []map[string]interface{}{ - pt.rawBody, - } - } - pt.Err = se -} - -func (pt *pollingTrackerBase) updatePollingState(provStateApl bool) error { - if pt.Pm == PollingAsyncOperation && pt.rawBody["status"] != nil { - pt.State = pt.rawBody["status"].(string) - } else { - if pt.resp.StatusCode == http.StatusAccepted { - pt.State = operationInProgress - } else if provStateApl { - if ps := pt.getProvisioningState(); ps != nil { - pt.State = *ps - } else { - pt.State = operationSucceeded - } - } else { - return autorest.NewError("pollingTrackerBase", "updatePollingState", "the response from the async operation has an invalid status code") - } - } - // if the operation has failed update the error state - if pt.hasFailed() { - pt.updateErrorFromResponse() - } - return nil -} - -func (pt pollingTrackerBase) pollingError() error { - if pt.Err == nil { - return nil - } - return pt.Err -} - -func (pt pollingTrackerBase) pollingMethod() PollingMethodType { - return pt.Pm -} - -func (pt pollingTrackerBase) pollingStatus() string { - return pt.State -} - -func (pt pollingTrackerBase) pollingURL() string { - return pt.URI -} - -func (pt pollingTrackerBase) finalGetURL() string { - return pt.FinalGetURI -} - -func (pt pollingTrackerBase) hasTerminated() bool { - return strings.EqualFold(pt.State, operationCanceled) || strings.EqualFold(pt.State, operationFailed) || strings.EqualFold(pt.State, operationSucceeded) -} - -func (pt pollingTrackerBase) hasFailed() bool { - return strings.EqualFold(pt.State, operationCanceled) || strings.EqualFold(pt.State, operationFailed) -} - -func (pt pollingTrackerBase) hasSucceeded() bool { - return strings.EqualFold(pt.State, operationSucceeded) -} - -func (pt pollingTrackerBase) latestResponse() *http.Response { - return pt.resp -} - -// error checking common to all trackers -func (pt pollingTrackerBase) baseCheckForErrors() error { - // for Azure-AsyncOperations the response body cannot be nil or empty - if pt.Pm == PollingAsyncOperation { - if pt.resp.Body == nil || pt.resp.ContentLength == 0 { - return autorest.NewError("pollingTrackerBase", "baseCheckForErrors", "for Azure-AsyncOperation response body cannot be nil") - } - if pt.rawBody["status"] == nil { - return autorest.NewError("pollingTrackerBase", "baseCheckForErrors", "missing status property in Azure-AsyncOperation response body") - } - } - return nil -} - -// default initialization of polling URL/method. each verb tracker will update this as required. -func (pt *pollingTrackerBase) initPollingMethod() error { - if ao, err := getURLFromAsyncOpHeader(pt.resp); err != nil { - return err - } else if ao != "" { - pt.URI = ao - pt.Pm = PollingAsyncOperation - return nil - } - if lh, err := getURLFromLocationHeader(pt.resp); err != nil { - return err - } else if lh != "" { - pt.URI = lh - pt.Pm = PollingLocation - return nil - } - // it's ok if we didn't find a polling header, this will be handled elsewhere - return nil -} - -// DELETE - -type pollingTrackerDelete struct { - pollingTrackerBase -} - -func (pt *pollingTrackerDelete) updatePollingMethod() error { - // for 201 the Location header is required - if pt.resp.StatusCode == http.StatusCreated { - if lh, err := getURLFromLocationHeader(pt.resp); err != nil { - return err - } else if lh == "" { - return autorest.NewError("pollingTrackerDelete", "updateHeaders", "missing Location header in 201 response") - } else { - pt.URI = lh - } - pt.Pm = PollingLocation - pt.FinalGetURI = pt.URI - } - // for 202 prefer the Azure-AsyncOperation header but fall back to Location if necessary - if pt.resp.StatusCode == http.StatusAccepted { - ao, err := getURLFromAsyncOpHeader(pt.resp) - if err != nil { - return err - } else if ao != "" { - pt.URI = ao - pt.Pm = PollingAsyncOperation - } - // if the Location header is invalid and we already have a polling URL - // then we don't care if the Location header URL is malformed. - if lh, err := getURLFromLocationHeader(pt.resp); err != nil && pt.URI == "" { - return err - } else if lh != "" { - if ao == "" { - pt.URI = lh - pt.Pm = PollingLocation - } - // when both headers are returned we use the value in the Location header for the final GET - pt.FinalGetURI = lh - } - // make sure a polling URL was found - if pt.URI == "" { - return autorest.NewError("pollingTrackerPost", "updateHeaders", "didn't get any suitable polling URLs in 202 response") - } - } - return nil -} - -func (pt pollingTrackerDelete) checkForErrors() error { - return pt.baseCheckForErrors() -} - -func (pt pollingTrackerDelete) provisioningStateApplicable() bool { - return pt.resp.StatusCode == http.StatusOK || pt.resp.StatusCode == http.StatusNoContent -} - -// PATCH - -type pollingTrackerPatch struct { - pollingTrackerBase -} - -func (pt *pollingTrackerPatch) updatePollingMethod() error { - // by default we can use the original URL for polling and final GET - if pt.URI == "" { - pt.URI = pt.resp.Request.URL.String() - } - if pt.FinalGetURI == "" { - pt.FinalGetURI = pt.resp.Request.URL.String() - } - if pt.Pm == PollingUnknown { - pt.Pm = PollingRequestURI - } - // for 201 it's permissible for no headers to be returned - if pt.resp.StatusCode == http.StatusCreated { - if ao, err := getURLFromAsyncOpHeader(pt.resp); err != nil { - return err - } else if ao != "" { - pt.URI = ao - pt.Pm = PollingAsyncOperation - } - } - // for 202 prefer the Azure-AsyncOperation header but fall back to Location if necessary - // note the absence of the "final GET" mechanism for PATCH - if pt.resp.StatusCode == http.StatusAccepted { - ao, err := getURLFromAsyncOpHeader(pt.resp) - if err != nil { - return err - } else if ao != "" { - pt.URI = ao - pt.Pm = PollingAsyncOperation - } - if ao == "" { - if lh, err := getURLFromLocationHeader(pt.resp); err != nil { - return err - } else if lh == "" { - return autorest.NewError("pollingTrackerPatch", "updateHeaders", "didn't get any suitable polling URLs in 202 response") - } else { - pt.URI = lh - pt.Pm = PollingLocation - } - } - } - return nil -} - -func (pt pollingTrackerPatch) checkForErrors() error { - return pt.baseCheckForErrors() -} - -func (pt pollingTrackerPatch) provisioningStateApplicable() bool { - return pt.resp.StatusCode == http.StatusOK || pt.resp.StatusCode == http.StatusCreated -} - -// POST - -type pollingTrackerPost struct { - pollingTrackerBase -} - -func (pt *pollingTrackerPost) updatePollingMethod() error { - // 201 requires Location header - if pt.resp.StatusCode == http.StatusCreated { - if lh, err := getURLFromLocationHeader(pt.resp); err != nil { - return err - } else if lh == "" { - return autorest.NewError("pollingTrackerPost", "updateHeaders", "missing Location header in 201 response") - } else { - pt.URI = lh - pt.FinalGetURI = lh - pt.Pm = PollingLocation - } - } - // for 202 prefer the Azure-AsyncOperation header but fall back to Location if necessary - if pt.resp.StatusCode == http.StatusAccepted { - ao, err := getURLFromAsyncOpHeader(pt.resp) - if err != nil { - return err - } else if ao != "" { - pt.URI = ao - pt.Pm = PollingAsyncOperation - } - // if the Location header is invalid and we already have a polling URL - // then we don't care if the Location header URL is malformed. - if lh, err := getURLFromLocationHeader(pt.resp); err != nil && pt.URI == "" { - return err - } else if lh != "" { - if ao == "" { - pt.URI = lh - pt.Pm = PollingLocation - } - // when both headers are returned we use the value in the Location header for the final GET - pt.FinalGetURI = lh - } - // make sure a polling URL was found - if pt.URI == "" { - return autorest.NewError("pollingTrackerPost", "updateHeaders", "didn't get any suitable polling URLs in 202 response") - } - } - return nil -} - -func (pt pollingTrackerPost) checkForErrors() error { - return pt.baseCheckForErrors() -} - -func (pt pollingTrackerPost) provisioningStateApplicable() bool { - return pt.resp.StatusCode == http.StatusOK || pt.resp.StatusCode == http.StatusNoContent -} - -// PUT - -type pollingTrackerPut struct { - pollingTrackerBase -} - -func (pt *pollingTrackerPut) updatePollingMethod() error { - // by default we can use the original URL for polling and final GET - if pt.URI == "" { - pt.URI = pt.resp.Request.URL.String() - } - if pt.FinalGetURI == "" { - pt.FinalGetURI = pt.resp.Request.URL.String() - } - if pt.Pm == PollingUnknown { - pt.Pm = PollingRequestURI - } - // for 201 it's permissible for no headers to be returned - if pt.resp.StatusCode == http.StatusCreated { - if ao, err := getURLFromAsyncOpHeader(pt.resp); err != nil { - return err - } else if ao != "" { - pt.URI = ao - pt.Pm = PollingAsyncOperation - } - } - // for 202 prefer the Azure-AsyncOperation header but fall back to Location if necessary - if pt.resp.StatusCode == http.StatusAccepted { - ao, err := getURLFromAsyncOpHeader(pt.resp) - if err != nil { - return err - } else if ao != "" { - pt.URI = ao - pt.Pm = PollingAsyncOperation - } - // if the Location header is invalid and we already have a polling URL - // then we don't care if the Location header URL is malformed. - if lh, err := getURLFromLocationHeader(pt.resp); err != nil && pt.URI == "" { - return err - } else if lh != "" { - if ao == "" { - pt.URI = lh - pt.Pm = PollingLocation - } - } - // make sure a polling URL was found - if pt.URI == "" { - return autorest.NewError("pollingTrackerPut", "updateHeaders", "didn't get any suitable polling URLs in 202 response") - } - } - return nil -} - -func (pt pollingTrackerPut) checkForErrors() error { - err := pt.baseCheckForErrors() - if err != nil { - return err - } - // if there are no LRO headers then the body cannot be empty - ao, err := getURLFromAsyncOpHeader(pt.resp) - if err != nil { - return err - } - lh, err := getURLFromLocationHeader(pt.resp) - if err != nil { - return err - } - if ao == "" && lh == "" && len(pt.rawBody) == 0 { - return autorest.NewError("pollingTrackerPut", "checkForErrors", "the response did not contain a body") - } - return nil -} - -func (pt pollingTrackerPut) provisioningStateApplicable() bool { - return pt.resp.StatusCode == http.StatusOK || pt.resp.StatusCode == http.StatusCreated -} - -// creates a polling tracker based on the verb of the original request -func createPollingTracker(resp *http.Response) (pollingTracker, error) { - var pt pollingTracker - switch strings.ToUpper(resp.Request.Method) { - case http.MethodDelete: - pt = &pollingTrackerDelete{pollingTrackerBase: pollingTrackerBase{resp: resp}} - case http.MethodPatch: - pt = &pollingTrackerPatch{pollingTrackerBase: pollingTrackerBase{resp: resp}} - case http.MethodPost: - pt = &pollingTrackerPost{pollingTrackerBase: pollingTrackerBase{resp: resp}} - case http.MethodPut: - pt = &pollingTrackerPut{pollingTrackerBase: pollingTrackerBase{resp: resp}} - default: - return nil, autorest.NewError("azure", "createPollingTracker", "unsupported HTTP method %s", resp.Request.Method) - } - if err := pt.initializeState(); err != nil { - return pt, err - } - // this initializes the polling header values, we do this during creation in case the - // initial response send us invalid values; this way the API call will return a non-nil - // error (not doing this means the error shows up in Future.Done) - return pt, pt.updatePollingMethod() -} - -// gets the polling URL from the Azure-AsyncOperation header. -// ensures the URL is well-formed and absolute. -func getURLFromAsyncOpHeader(resp *http.Response) (string, error) { - s := resp.Header.Get(http.CanonicalHeaderKey(headerAsyncOperation)) - if s == "" { - return "", nil - } - if !isValidURL(s) { - return "", autorest.NewError("azure", "getURLFromAsyncOpHeader", "invalid polling URL '%s'", s) - } - return s, nil -} - -// gets the polling URL from the Location header. -// ensures the URL is well-formed and absolute. -func getURLFromLocationHeader(resp *http.Response) (string, error) { - s := resp.Header.Get(http.CanonicalHeaderKey(autorest.HeaderLocation)) - if s == "" { - return "", nil - } - if !isValidURL(s) { - return "", autorest.NewError("azure", "getURLFromLocationHeader", "invalid polling URL '%s'", s) - } - return s, nil -} - -// verify that the URL is valid and absolute -func isValidURL(s string) bool { - u, err := url.Parse(s) - return err == nil && u.IsAbs() -} - -// PollingMethodType defines a type used for enumerating polling mechanisms. -type PollingMethodType string - -const ( - // PollingAsyncOperation indicates the polling method uses the Azure-AsyncOperation header. - PollingAsyncOperation PollingMethodType = "AsyncOperation" - - // PollingLocation indicates the polling method uses the Location header. - PollingLocation PollingMethodType = "Location" - - // PollingRequestURI indicates the polling method uses the original request URI. - PollingRequestURI PollingMethodType = "RequestURI" - - // PollingUnknown indicates an unknown polling method and is the default value. - PollingUnknown PollingMethodType = "" -) - -// AsyncOpIncompleteError is the type that's returned from a future that has not completed. -type AsyncOpIncompleteError struct { - // FutureType is the name of the type composed of a azure.Future. - FutureType string -} - -// Error returns an error message including the originating type name of the error. -func (e AsyncOpIncompleteError) Error() string { - return fmt.Sprintf("%s: asynchronous operation has not completed", e.FutureType) -} - -// NewAsyncOpIncompleteError creates a new AsyncOpIncompleteError with the specified parameters. -func NewAsyncOpIncompleteError(futureType string) AsyncOpIncompleteError { - return AsyncOpIncompleteError{ - FutureType: futureType, - } -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/auth/LICENSE b/vendor/github.com/Azure/go-autorest/autorest/azure/auth/LICENSE deleted file mode 100644 index b9d6a27e..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/azure/auth/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2015 Microsoft Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/auth/README.md b/vendor/github.com/Azure/go-autorest/autorest/azure/auth/README.md deleted file mode 100644 index 05bef8a8..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/azure/auth/README.md +++ /dev/null @@ -1,152 +0,0 @@ -# NOTE: This module will go out of support by March 31, 2023. For authenticating with Azure AD, use module [azidentity](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity) instead. For help migrating from `auth` to `azidentiy` please consult the [migration guide](https://aka.ms/azsdk/go/identity/migration). General information about the retirement of this and other legacy modules can be found [here](https://azure.microsoft.com/updates/support-for-azure-sdk-libraries-that-do-not-conform-to-our-current-azure-sdk-guidelines-will-be-retired-as-of-31-march-2023/). - -## Authentication - -Typical SDK operations must be authenticated and authorized. The `autorest.Authorizer` -interface allows use of any auth style in requests, such as inserting an OAuth2 -Authorization header and bearer token received from Azure AD. - -The SDK itself provides a simple way to get an authorizer which first checks -for OAuth client credentials in environment variables and then falls back to -Azure's [Managed Service Identity]() when available, e.g. when on an Azure -VM. The following snippet from [the previous section](#use) demonstrates -this helper. - -```go -import "github.com/Azure/go-autorest/autorest/azure/auth" - -// create a VirtualNetworks client -vnetClient := network.NewVirtualNetworksClient("") - -// create an authorizer from env vars or Azure Managed Service Idenity -authorizer, err := auth.NewAuthorizerFromEnvironment() -if err != nil { - handle(err) -} - -vnetClient.Authorizer = authorizer - -// call the VirtualNetworks CreateOrUpdate API -vnetClient.CreateOrUpdate(context.Background(), -// ... -``` - -The following environment variables help determine authentication configuration: - -- `AZURE_ENVIRONMENT`: Specifies the Azure Environment to use. If not set, it - defaults to `AzurePublicCloud`. Not applicable to authentication with Managed - Service Identity (MSI). -- `AZURE_AD_RESOURCE`: Specifies the AAD resource ID to use. If not set, it - defaults to `ResourceManagerEndpoint` for operations with Azure Resource - Manager. You can also choose an alternate resource programmatically with - `auth.NewAuthorizerFromEnvironmentWithResource(resource string)`. - -### More Authentication Details - -The previous is the first and most recommended of several authentication -options offered by the SDK because it allows seamless use of both service -principals and [Azure Managed Service Identity][]. Other options are listed -below. - -> Note: If you need to create a new service principal, run `az ad sp create-for-rbac -n ""` in the -> [azure-cli](https://github.com/Azure/azure-cli). See [these -> docs](https://docs.microsoft.com/cli/azure/create-an-azure-service-principal-azure-cli?view=azure-cli-latest) -> for more info. Copy the new principal's ID, secret, and tenant ID for use in -> your app, or consider the `--sdk-auth` parameter for serialized output. - -[azure managed service identity]: https://docs.microsoft.com/azure/active-directory/msi-overview - -- The `auth.NewAuthorizerFromEnvironment()` described above creates an authorizer - from the first available of the following configuration: - - 1. **Client Credentials**: Azure AD Application ID and Secret. - - - `AZURE_TENANT_ID`: Specifies the Tenant to which to authenticate. - - `AZURE_CLIENT_ID`: Specifies the app client ID to use. - - `AZURE_CLIENT_SECRET`: Specifies the app secret to use. - - 2. **Client Certificate**: Azure AD Application ID and X.509 Certificate. - - - `AZURE_TENANT_ID`: Specifies the Tenant to which to authenticate. - - `AZURE_CLIENT_ID`: Specifies the app client ID to use. - - `AZURE_CERTIFICATE_PATH`: Specifies the certificate Path to use. - - `AZURE_CERTIFICATE_PASSWORD`: Specifies the certificate password to use. - - 3. **Resource Owner Password**: Azure AD User and Password. This grant type is *not - recommended*, use device login instead if you need interactive login. - - - `AZURE_TENANT_ID`: Specifies the Tenant to which to authenticate. - - `AZURE_CLIENT_ID`: Specifies the app client ID to use. - - `AZURE_USERNAME`: Specifies the username to use. - - `AZURE_PASSWORD`: Specifies the password to use. - - 4. **Azure Managed Service Identity**: Delegate credential management to the - platform. Requires that code is running in Azure, e.g. on a VM. All - configuration is handled by Azure. See [Azure Managed Service - Identity](https://docs.microsoft.com/azure/active-directory/msi-overview) - for more details. - -- The `auth.NewAuthorizerFromFile()` method creates an authorizer using - credentials from an auth file created by the [Azure CLI][]. Follow these - steps to utilize: - - 1. Create a service principal and output an auth file using `az ad sp create-for-rbac --sdk-auth > client_credentials.json`. - 2. Set environment variable `AZURE_AUTH_LOCATION` to the path of the saved - output file. - 3. Use the authorizer returned by `auth.NewAuthorizerFromFile()` in your - client as described above. - -- The `auth.NewAuthorizerFromCLI()` method creates an authorizer which - uses [Azure CLI][] to obtain its credentials. - - The default audience being requested is `https://management.azure.com` (Azure ARM API). - To specify your own audience, export `AZURE_AD_RESOURCE` as an evironment variable. - This is read by `auth.NewAuthorizerFromCLI()` and passed to Azure CLI to acquire the access token. - - For example, to request an access token for Azure Key Vault, export - ``` - AZURE_AD_RESOURCE="https://vault.azure.net" - ``` - -- `auth.NewAuthorizerFromCLIWithResource(AUDIENCE_URL_OR_APPLICATION_ID)` - this method is self contained and does - not require exporting environment variables. For example, to request an access token for Azure Key Vault: - ``` - auth.NewAuthorizerFromCLIWithResource("https://vault.azure.net") - ``` - - To use `NewAuthorizerFromCLI()` or `NewAuthorizerFromCLIWithResource()`, follow these steps: - - 1. Install [Azure CLI v2.0.12](https://docs.microsoft.com/cli/azure/install-azure-cli) or later. Upgrade earlier versions. - 2. Use `az login` to sign in to Azure. - - If you receive an error, use `az account get-access-token` to verify access. - - If Azure CLI is not installed to the default directory, you may receive an error - reporting that `az` cannot be found. - Use the `AzureCLIPath` environment variable to define the Azure CLI installation folder. - - If you are signed in to Azure CLI using multiple accounts or your account has - access to multiple subscriptions, you need to specify the specific subscription - to be used. To do so, use: - - ``` - az account set --subscription - ``` - - To verify the current account settings, use: - - ``` - az account list - ``` - -[azure cli]: https://github.com/Azure/azure-cli - -- Finally, you can use OAuth's [Device Flow][] by calling - `auth.NewDeviceFlowConfig()` and extracting the Authorizer as follows: - - ```go - config := auth.NewDeviceFlowConfig(clientID, tenantID) - a, err := config.Authorizer() - ``` - -[device flow]: https://oauth.net/2/device-flow/ diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/auth/auth.go b/vendor/github.com/Azure/go-autorest/autorest/azure/auth/auth.go deleted file mode 100644 index 25697b3c..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/azure/auth/auth.go +++ /dev/null @@ -1,772 +0,0 @@ -package auth - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import ( - "bytes" - "context" - "encoding/binary" - "encoding/json" - "errors" - "fmt" - "io" - "log" - "os" - "strings" - "unicode/utf16" - - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/adal" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/Azure/go-autorest/autorest/azure/cli" - "github.com/Azure/go-autorest/logger" - "github.com/dimchansky/utfbom" -) - -// The possible keys in the Values map. -const ( - SubscriptionID = "AZURE_SUBSCRIPTION_ID" - TenantID = "AZURE_TENANT_ID" - AuxiliaryTenantIDs = "AZURE_AUXILIARY_TENANT_IDS" - ClientID = "AZURE_CLIENT_ID" - ClientSecret = "AZURE_CLIENT_SECRET" - CertificatePath = "AZURE_CERTIFICATE_PATH" - CertificatePassword = "AZURE_CERTIFICATE_PASSWORD" - Username = "AZURE_USERNAME" - Password = "AZURE_PASSWORD" - EnvironmentName = "AZURE_ENVIRONMENT" - Resource = "AZURE_AD_RESOURCE" - ActiveDirectoryEndpoint = "ActiveDirectoryEndpoint" - ResourceManagerEndpoint = "ResourceManagerEndpoint" - GraphResourceID = "GraphResourceID" - SQLManagementEndpoint = "SQLManagementEndpoint" - GalleryEndpoint = "GalleryEndpoint" - ManagementEndpoint = "ManagementEndpoint" -) - -// NewAuthorizerFromEnvironment creates an Authorizer configured from environment variables in the order: -// 1. Client credentials -// 2. Client certificate -// 3. Username password -// 4. MSI -func NewAuthorizerFromEnvironment() (autorest.Authorizer, error) { - logger.Instance.Writeln(logger.LogInfo, "NewAuthorizerFromEnvironment() determining authentication mechanism") - settings, err := GetSettingsFromEnvironment() - if err != nil { - return nil, err - } - return settings.GetAuthorizer() -} - -// NewAuthorizerFromEnvironmentWithResource creates an Authorizer configured from environment variables in the order: -// 1. Client credentials -// 2. Client certificate -// 3. Username password -// 4. MSI -func NewAuthorizerFromEnvironmentWithResource(resource string) (autorest.Authorizer, error) { - logger.Instance.Writeln(logger.LogInfo, "NewAuthorizerFromEnvironmentWithResource() determining authentication mechanism") - settings, err := GetSettingsFromEnvironment() - if err != nil { - return nil, err - } - settings.Values[Resource] = resource - return settings.GetAuthorizer() -} - -// EnvironmentSettings contains the available authentication settings. -type EnvironmentSettings struct { - Values map[string]string - Environment azure.Environment -} - -// GetSettingsFromEnvironment returns the available authentication settings from the environment. -func GetSettingsFromEnvironment() (s EnvironmentSettings, err error) { - s = EnvironmentSettings{ - Values: map[string]string{}, - } - s.setValue(SubscriptionID) - s.setValue(TenantID) - s.setValue(AuxiliaryTenantIDs) - s.setValue(ClientID) - s.setValue(ClientSecret) - s.setValue(CertificatePath) - s.setValue(CertificatePassword) - s.setValue(Username) - s.setValue(Password) - s.setValue(EnvironmentName) - s.setValue(Resource) - if v := s.Values[EnvironmentName]; v == "" { - s.Environment = azure.PublicCloud - } else { - s.Environment, err = azure.EnvironmentFromName(v) - } - if s.Values[Resource] == "" { - s.Values[Resource] = s.Environment.ResourceManagerEndpoint - } - return -} - -// GetSubscriptionID returns the available subscription ID or an empty string. -func (settings EnvironmentSettings) GetSubscriptionID() string { - return settings.Values[SubscriptionID] -} - -// adds the specified environment variable value to the Values map if it exists -func (settings EnvironmentSettings) setValue(key string) { - if v := os.Getenv(key); v != "" { - logger.Instance.Writef(logger.LogInfo, "GetSettingsFromEnvironment() found environment var %s\n", key) - settings.Values[key] = v - } -} - -// helper to return client and tenant IDs -func (settings EnvironmentSettings) getClientAndTenant() (string, string) { - clientID := settings.Values[ClientID] - tenantID := settings.Values[TenantID] - return clientID, tenantID -} - -// GetClientCredentials creates a config object from the available client credentials. -// An error is returned if no client credentials are available. -func (settings EnvironmentSettings) GetClientCredentials() (ClientCredentialsConfig, error) { - secret := settings.Values[ClientSecret] - if secret == "" { - logger.Instance.Writeln(logger.LogInfo, "EnvironmentSettings.GetClientCredentials() missing client secret") - return ClientCredentialsConfig{}, errors.New("missing client secret") - } - clientID, tenantID := settings.getClientAndTenant() - config := NewClientCredentialsConfig(clientID, secret, tenantID) - config.AADEndpoint = settings.Environment.ActiveDirectoryEndpoint - config.Resource = settings.Values[Resource] - if auxTenants, ok := settings.Values[AuxiliaryTenantIDs]; ok { - config.AuxTenants = strings.Split(auxTenants, ";") - for i := range config.AuxTenants { - config.AuxTenants[i] = strings.TrimSpace(config.AuxTenants[i]) - } - } - return config, nil -} - -// GetClientCertificate creates a config object from the available certificate credentials. -// An error is returned if no certificate credentials are available. -func (settings EnvironmentSettings) GetClientCertificate() (ClientCertificateConfig, error) { - certPath := settings.Values[CertificatePath] - if certPath == "" { - logger.Instance.Writeln(logger.LogInfo, "EnvironmentSettings.GetClientCertificate() missing certificate path") - return ClientCertificateConfig{}, errors.New("missing certificate path") - } - certPwd := settings.Values[CertificatePassword] - clientID, tenantID := settings.getClientAndTenant() - config := NewClientCertificateConfig(certPath, certPwd, clientID, tenantID) - config.AADEndpoint = settings.Environment.ActiveDirectoryEndpoint - config.Resource = settings.Values[Resource] - return config, nil -} - -// GetUsernamePassword creates a config object from the available username/password credentials. -// An error is returned if no username/password credentials are available. -func (settings EnvironmentSettings) GetUsernamePassword() (UsernamePasswordConfig, error) { - username := settings.Values[Username] - password := settings.Values[Password] - if username == "" || password == "" { - logger.Instance.Writeln(logger.LogInfo, "EnvironmentSettings.GetUsernamePassword() missing username and/or password") - return UsernamePasswordConfig{}, errors.New("missing username/password") - } - clientID, tenantID := settings.getClientAndTenant() - config := NewUsernamePasswordConfig(username, password, clientID, tenantID) - config.AADEndpoint = settings.Environment.ActiveDirectoryEndpoint - config.Resource = settings.Values[Resource] - return config, nil -} - -// GetMSI creates a MSI config object from the available client ID. -func (settings EnvironmentSettings) GetMSI() MSIConfig { - config := NewMSIConfig() - config.Resource = settings.Values[Resource] - config.ClientID = settings.Values[ClientID] - return config -} - -// GetDeviceFlow creates a device-flow config object from the available client and tenant IDs. -func (settings EnvironmentSettings) GetDeviceFlow() DeviceFlowConfig { - clientID, tenantID := settings.getClientAndTenant() - config := NewDeviceFlowConfig(clientID, tenantID) - config.AADEndpoint = settings.Environment.ActiveDirectoryEndpoint - config.Resource = settings.Values[Resource] - return config -} - -// GetAuthorizer creates an Authorizer configured from environment variables in the order: -// 1. Client credentials -// 2. Client certificate -// 3. Username password -// 4. MSI -func (settings EnvironmentSettings) GetAuthorizer() (autorest.Authorizer, error) { - //1.Client Credentials - if c, e := settings.GetClientCredentials(); e == nil { - logger.Instance.Writeln(logger.LogInfo, "EnvironmentSettings.GetAuthorizer() using client secret credentials") - return c.Authorizer() - } - - //2. Client Certificate - if c, e := settings.GetClientCertificate(); e == nil { - logger.Instance.Writeln(logger.LogInfo, "EnvironmentSettings.GetAuthorizer() using client certificate credentials") - return c.Authorizer() - } - - //3. Username Password - if c, e := settings.GetUsernamePassword(); e == nil { - logger.Instance.Writeln(logger.LogInfo, "EnvironmentSettings.GetAuthorizer() using user name/password credentials") - return c.Authorizer() - } - - // 4. MSI - if !adal.MSIAvailable(context.Background(), nil) { - return nil, errors.New("MSI not available") - } - logger.Instance.Writeln(logger.LogInfo, "EnvironmentSettings.GetAuthorizer() using MSI authentication") - return settings.GetMSI().Authorizer() -} - -// NewAuthorizerFromFile creates an Authorizer configured from a configuration file in the following order. -// 1. Client credentials -// 2. Client certificate -// The path to the configuration file must be specified in the AZURE_AUTH_LOCATION environment variable. -// resourceBaseURI - used to determine the resource type -func NewAuthorizerFromFile(resourceBaseURI string) (autorest.Authorizer, error) { - settings, err := GetSettingsFromFile() - if err != nil { - return nil, err - } - return settings.GetAuthorizer(resourceBaseURI) -} - -// GetAuthorizer create an Authorizer in the following order. -// 1. Client credentials -// 2. Client certificate -// resourceBaseURI - used to determine the resource type -func (settings FileSettings) GetAuthorizer(resourceBaseURI string) (autorest.Authorizer, error) { - if resourceBaseURI == "" { - resourceBaseURI = azure.PublicCloud.ServiceManagementEndpoint - } - if a, err := settings.ClientCredentialsAuthorizer(resourceBaseURI); err == nil { - return a, err - } - if a, err := settings.ClientCertificateAuthorizer(resourceBaseURI); err == nil { - return a, err - } - return nil, errors.New("auth file missing client and certificate credentials") -} - -// NewAuthorizerFromFileWithResource creates an Authorizer configured from a configuration file in the following order. -// 1. Client credentials -// 2. Client certificate -// The path to the configuration file must be specified in the AZURE_AUTH_LOCATION environment variable. -func NewAuthorizerFromFileWithResource(resource string) (autorest.Authorizer, error) { - s, err := GetSettingsFromFile() - if err != nil { - return nil, err - } - if a, err := s.ClientCredentialsAuthorizerWithResource(resource); err == nil { - return a, err - } - if a, err := s.ClientCertificateAuthorizerWithResource(resource); err == nil { - return a, err - } - return nil, errors.New("auth file missing client and certificate credentials") -} - -// NewAuthorizerFromCLI creates an Authorizer configured from Azure CLI 2.0 for local development scenarios. -func NewAuthorizerFromCLI() (autorest.Authorizer, error) { - settings, err := GetSettingsFromEnvironment() - if err != nil { - return nil, err - } - - if settings.Values[Resource] == "" { - settings.Values[Resource] = settings.Environment.ResourceManagerEndpoint - } - - return NewAuthorizerFromCLIWithResource(settings.Values[Resource]) -} - -// NewAuthorizerFromCLIWithResource creates an Authorizer configured from Azure CLI 2.0 for local development scenarios. -func NewAuthorizerFromCLIWithResource(resource string) (autorest.Authorizer, error) { - token, err := cli.GetTokenFromCLI(resource) - if err != nil { - return nil, err - } - - adalToken, err := token.ToADALToken() - if err != nil { - return nil, err - } - - return autorest.NewBearerAuthorizer(&adalToken), nil -} - -// GetSettingsFromFile returns the available authentication settings from an Azure CLI authentication file. -func GetSettingsFromFile() (FileSettings, error) { - s := FileSettings{} - fileLocation := os.Getenv("AZURE_AUTH_LOCATION") - if fileLocation == "" { - return s, errors.New("environment variable AZURE_AUTH_LOCATION is not set") - } - - contents, err := os.ReadFile(fileLocation) - if err != nil { - return s, err - } - - // Auth file might be encoded - decoded, err := decode(contents) - if err != nil { - return s, err - } - - authFile := map[string]interface{}{} - err = json.Unmarshal(decoded, &authFile) - if err != nil { - return s, err - } - - s.Values = map[string]string{} - s.setKeyValue(ClientID, authFile["clientId"]) - s.setKeyValue(ClientSecret, authFile["clientSecret"]) - s.setKeyValue(CertificatePath, authFile["clientCertificate"]) - s.setKeyValue(CertificatePassword, authFile["clientCertificatePassword"]) - s.setKeyValue(SubscriptionID, authFile["subscriptionId"]) - s.setKeyValue(TenantID, authFile["tenantId"]) - s.setKeyValue(ActiveDirectoryEndpoint, authFile["activeDirectoryEndpointUrl"]) - s.setKeyValue(ResourceManagerEndpoint, authFile["resourceManagerEndpointUrl"]) - s.setKeyValue(GraphResourceID, authFile["activeDirectoryGraphResourceId"]) - s.setKeyValue(SQLManagementEndpoint, authFile["sqlManagementEndpointUrl"]) - s.setKeyValue(GalleryEndpoint, authFile["galleryEndpointUrl"]) - s.setKeyValue(ManagementEndpoint, authFile["managementEndpointUrl"]) - return s, nil -} - -// FileSettings contains the available authentication settings. -type FileSettings struct { - Values map[string]string -} - -// GetSubscriptionID returns the available subscription ID or an empty string. -func (settings FileSettings) GetSubscriptionID() string { - return settings.Values[SubscriptionID] -} - -// adds the specified value to the Values map if it isn't nil -func (settings FileSettings) setKeyValue(key string, val interface{}) { - if val != nil { - settings.Values[key] = val.(string) - } -} - -// returns the specified AAD endpoint or the public cloud endpoint if unspecified -func (settings FileSettings) getAADEndpoint() string { - if v, ok := settings.Values[ActiveDirectoryEndpoint]; ok { - return v - } - return azure.PublicCloud.ActiveDirectoryEndpoint -} - -// ServicePrincipalTokenFromClientCredentials creates a ServicePrincipalToken from the available client credentials. -func (settings FileSettings) ServicePrincipalTokenFromClientCredentials(baseURI string) (*adal.ServicePrincipalToken, error) { - resource, err := settings.getResourceForToken(baseURI) - if err != nil { - return nil, err - } - return settings.ServicePrincipalTokenFromClientCredentialsWithResource(resource) -} - -// ClientCredentialsAuthorizer creates an authorizer from the available client credentials. -func (settings FileSettings) ClientCredentialsAuthorizer(baseURI string) (autorest.Authorizer, error) { - resource, err := settings.getResourceForToken(baseURI) - if err != nil { - return nil, err - } - return settings.ClientCredentialsAuthorizerWithResource(resource) -} - -// ServicePrincipalTokenFromClientCredentialsWithResource creates a ServicePrincipalToken -// from the available client credentials and the specified resource. -func (settings FileSettings) ServicePrincipalTokenFromClientCredentialsWithResource(resource string) (*adal.ServicePrincipalToken, error) { - if _, ok := settings.Values[ClientSecret]; !ok { - return nil, errors.New("missing client secret") - } - config, err := adal.NewOAuthConfig(settings.getAADEndpoint(), settings.Values[TenantID]) - if err != nil { - return nil, err - } - return adal.NewServicePrincipalToken(*config, settings.Values[ClientID], settings.Values[ClientSecret], resource) -} - -func (settings FileSettings) clientCertificateConfigWithResource(resource string) (ClientCertificateConfig, error) { - if _, ok := settings.Values[CertificatePath]; !ok { - return ClientCertificateConfig{}, errors.New("missing certificate path") - } - cfg := NewClientCertificateConfig(settings.Values[CertificatePath], settings.Values[CertificatePassword], settings.Values[ClientID], settings.Values[TenantID]) - cfg.AADEndpoint = settings.getAADEndpoint() - cfg.Resource = resource - return cfg, nil -} - -// ClientCredentialsAuthorizerWithResource creates an authorizer from the available client credentials and the specified resource. -func (settings FileSettings) ClientCredentialsAuthorizerWithResource(resource string) (autorest.Authorizer, error) { - spToken, err := settings.ServicePrincipalTokenFromClientCredentialsWithResource(resource) - if err != nil { - return nil, err - } - return autorest.NewBearerAuthorizer(spToken), nil -} - -// ServicePrincipalTokenFromClientCertificate creates a ServicePrincipalToken from the available certificate credentials. -func (settings FileSettings) ServicePrincipalTokenFromClientCertificate(baseURI string) (*adal.ServicePrincipalToken, error) { - resource, err := settings.getResourceForToken(baseURI) - if err != nil { - return nil, err - } - return settings.ServicePrincipalTokenFromClientCertificateWithResource(resource) -} - -// ClientCertificateAuthorizer creates an authorizer from the available certificate credentials. -func (settings FileSettings) ClientCertificateAuthorizer(baseURI string) (autorest.Authorizer, error) { - resource, err := settings.getResourceForToken(baseURI) - if err != nil { - return nil, err - } - return settings.ClientCertificateAuthorizerWithResource(resource) -} - -// ServicePrincipalTokenFromClientCertificateWithResource creates a ServicePrincipalToken from the available certificate credentials. -func (settings FileSettings) ServicePrincipalTokenFromClientCertificateWithResource(resource string) (*adal.ServicePrincipalToken, error) { - cfg, err := settings.clientCertificateConfigWithResource(resource) - if err != nil { - return nil, err - } - return cfg.ServicePrincipalToken() -} - -// ClientCertificateAuthorizerWithResource creates an authorizer from the available certificate credentials and the specified resource. -func (settings FileSettings) ClientCertificateAuthorizerWithResource(resource string) (autorest.Authorizer, error) { - cfg, err := settings.clientCertificateConfigWithResource(resource) - if err != nil { - return nil, err - } - return cfg.Authorizer() -} - -func decode(b []byte) ([]byte, error) { - reader, enc := utfbom.Skip(bytes.NewReader(b)) - - switch enc { - case utfbom.UTF16LittleEndian: - u16 := make([]uint16, (len(b)/2)-1) - err := binary.Read(reader, binary.LittleEndian, &u16) - if err != nil { - return nil, err - } - return []byte(string(utf16.Decode(u16))), nil - case utfbom.UTF16BigEndian: - u16 := make([]uint16, (len(b)/2)-1) - err := binary.Read(reader, binary.BigEndian, &u16) - if err != nil { - return nil, err - } - return []byte(string(utf16.Decode(u16))), nil - } - return io.ReadAll(reader) -} - -func (settings FileSettings) getResourceForToken(baseURI string) (string, error) { - // Compare default base URI from the SDK to the endpoints from the public cloud - // Base URI and token resource are the same string. This func finds the authentication - // file field that matches the SDK base URI. The SDK defines the public cloud - // endpoint as its default base URI - if !strings.HasSuffix(baseURI, "/") { - baseURI += "/" - } - switch baseURI { - case azure.PublicCloud.ServiceManagementEndpoint: - return settings.Values[ManagementEndpoint], nil - case azure.PublicCloud.ResourceManagerEndpoint: - return settings.Values[ResourceManagerEndpoint], nil - case azure.PublicCloud.ActiveDirectoryEndpoint: - return settings.Values[ActiveDirectoryEndpoint], nil - case azure.PublicCloud.GalleryEndpoint: - return settings.Values[GalleryEndpoint], nil - case azure.PublicCloud.GraphEndpoint: - return settings.Values[GraphResourceID], nil - } - return "", fmt.Errorf("auth: base URI not found in endpoints") -} - -// NewClientCredentialsConfig creates an AuthorizerConfig object configured to obtain an Authorizer through Client Credentials. -// Defaults to Public Cloud and Resource Manager Endpoint. -func NewClientCredentialsConfig(clientID string, clientSecret string, tenantID string) ClientCredentialsConfig { - return ClientCredentialsConfig{ - ClientID: clientID, - ClientSecret: clientSecret, - TenantID: tenantID, - Resource: azure.PublicCloud.ResourceManagerEndpoint, - AADEndpoint: azure.PublicCloud.ActiveDirectoryEndpoint, - } -} - -// NewClientCertificateConfig creates a ClientCertificateConfig object configured to obtain an Authorizer through client certificate. -// Defaults to Public Cloud and Resource Manager Endpoint. -func NewClientCertificateConfig(certificatePath string, certificatePassword string, clientID string, tenantID string) ClientCertificateConfig { - return ClientCertificateConfig{ - CertificatePath: certificatePath, - CertificatePassword: certificatePassword, - ClientID: clientID, - TenantID: tenantID, - Resource: azure.PublicCloud.ResourceManagerEndpoint, - AADEndpoint: azure.PublicCloud.ActiveDirectoryEndpoint, - } -} - -// NewUsernamePasswordConfig creates an UsernamePasswordConfig object configured to obtain an Authorizer through username and password. -// Defaults to Public Cloud and Resource Manager Endpoint. -func NewUsernamePasswordConfig(username string, password string, clientID string, tenantID string) UsernamePasswordConfig { - return UsernamePasswordConfig{ - Username: username, - Password: password, - ClientID: clientID, - TenantID: tenantID, - Resource: azure.PublicCloud.ResourceManagerEndpoint, - AADEndpoint: azure.PublicCloud.ActiveDirectoryEndpoint, - } -} - -// NewMSIConfig creates an MSIConfig object configured to obtain an Authorizer through MSI. -func NewMSIConfig() MSIConfig { - return MSIConfig{ - Resource: azure.PublicCloud.ResourceManagerEndpoint, - } -} - -// NewDeviceFlowConfig creates a DeviceFlowConfig object configured to obtain an Authorizer through device flow. -// Defaults to Public Cloud and Resource Manager Endpoint. -func NewDeviceFlowConfig(clientID string, tenantID string) DeviceFlowConfig { - return DeviceFlowConfig{ - ClientID: clientID, - TenantID: tenantID, - Resource: azure.PublicCloud.ResourceManagerEndpoint, - AADEndpoint: azure.PublicCloud.ActiveDirectoryEndpoint, - } -} - -// AuthorizerConfig provides an authorizer from the configuration provided. -type AuthorizerConfig interface { - Authorizer() (autorest.Authorizer, error) -} - -// ClientCredentialsConfig provides the options to get a bearer authorizer from client credentials. -type ClientCredentialsConfig struct { - ClientID string - ClientSecret string - TenantID string - AuxTenants []string - AADEndpoint string - Resource string -} - -// ServicePrincipalToken creates a ServicePrincipalToken from client credentials. -func (ccc ClientCredentialsConfig) ServicePrincipalToken() (*adal.ServicePrincipalToken, error) { - oauthConfig, err := adal.NewOAuthConfig(ccc.AADEndpoint, ccc.TenantID) - if err != nil { - return nil, err - } - return adal.NewServicePrincipalToken(*oauthConfig, ccc.ClientID, ccc.ClientSecret, ccc.Resource) -} - -// MultiTenantServicePrincipalToken creates a MultiTenantServicePrincipalToken from client credentials. -func (ccc ClientCredentialsConfig) MultiTenantServicePrincipalToken() (*adal.MultiTenantServicePrincipalToken, error) { - oauthConfig, err := adal.NewMultiTenantOAuthConfig(ccc.AADEndpoint, ccc.TenantID, ccc.AuxTenants, adal.OAuthOptions{}) - if err != nil { - return nil, err - } - return adal.NewMultiTenantServicePrincipalToken(oauthConfig, ccc.ClientID, ccc.ClientSecret, ccc.Resource) -} - -// Authorizer gets the authorizer from client credentials. -func (ccc ClientCredentialsConfig) Authorizer() (autorest.Authorizer, error) { - if len(ccc.AuxTenants) == 0 { - spToken, err := ccc.ServicePrincipalToken() - if err != nil { - return nil, fmt.Errorf("failed to get SPT from client credentials: %v", err) - } - return autorest.NewBearerAuthorizer(spToken), nil - } - mtSPT, err := ccc.MultiTenantServicePrincipalToken() - if err != nil { - return nil, fmt.Errorf("failed to get multitenant SPT from client credentials: %v", err) - } - return autorest.NewMultiTenantServicePrincipalTokenAuthorizer(mtSPT), nil -} - -// ClientCertificateConfig provides the options to get a bearer authorizer from a client certificate. -type ClientCertificateConfig struct { - ClientID string - CertificatePath string - CertificatePassword string - TenantID string - AuxTenants []string - AADEndpoint string - Resource string -} - -// ServicePrincipalToken creates a ServicePrincipalToken from client certificate. -func (ccc ClientCertificateConfig) ServicePrincipalToken() (*adal.ServicePrincipalToken, error) { - oauthConfig, err := adal.NewOAuthConfig(ccc.AADEndpoint, ccc.TenantID) - if err != nil { - return nil, err - } - certData, err := os.ReadFile(ccc.CertificatePath) - if err != nil { - return nil, fmt.Errorf("failed to read the certificate file (%s): %v", ccc.CertificatePath, err) - } - certificate, rsaPrivateKey, err := adal.DecodePfxCertificateData(certData, ccc.CertificatePassword) - if err != nil { - return nil, fmt.Errorf("failed to decode pkcs12 certificate while creating spt: %v", err) - } - return adal.NewServicePrincipalTokenFromCertificate(*oauthConfig, ccc.ClientID, certificate, rsaPrivateKey, ccc.Resource) -} - -// MultiTenantServicePrincipalToken creates a MultiTenantServicePrincipalToken from client certificate. -func (ccc ClientCertificateConfig) MultiTenantServicePrincipalToken() (*adal.MultiTenantServicePrincipalToken, error) { - oauthConfig, err := adal.NewMultiTenantOAuthConfig(ccc.AADEndpoint, ccc.TenantID, ccc.AuxTenants, adal.OAuthOptions{}) - if err != nil { - return nil, err - } - certData, err := os.ReadFile(ccc.CertificatePath) - if err != nil { - return nil, fmt.Errorf("failed to read the certificate file (%s): %v", ccc.CertificatePath, err) - } - certificate, rsaPrivateKey, err := adal.DecodePfxCertificateData(certData, ccc.CertificatePassword) - if err != nil { - return nil, fmt.Errorf("failed to decode pkcs12 certificate while creating spt: %v", err) - } - return adal.NewMultiTenantServicePrincipalTokenFromCertificate(oauthConfig, ccc.ClientID, certificate, rsaPrivateKey, ccc.Resource) -} - -// Authorizer gets an authorizer object from client certificate. -func (ccc ClientCertificateConfig) Authorizer() (autorest.Authorizer, error) { - if len(ccc.AuxTenants) == 0 { - spToken, err := ccc.ServicePrincipalToken() - if err != nil { - return nil, fmt.Errorf("failed to get oauth token from certificate auth: %v", err) - } - return autorest.NewBearerAuthorizer(spToken), nil - } - mtSPT, err := ccc.MultiTenantServicePrincipalToken() - if err != nil { - return nil, fmt.Errorf("failed to get multitenant SPT from certificate auth: %v", err) - } - return autorest.NewMultiTenantServicePrincipalTokenAuthorizer(mtSPT), nil -} - -// DeviceFlowConfig provides the options to get a bearer authorizer using device flow authentication. -type DeviceFlowConfig struct { - ClientID string - TenantID string - AADEndpoint string - Resource string -} - -// Authorizer gets the authorizer from device flow. -func (dfc DeviceFlowConfig) Authorizer() (autorest.Authorizer, error) { - spToken, err := dfc.ServicePrincipalToken() - if err != nil { - return nil, fmt.Errorf("failed to get oauth token from device flow: %v", err) - } - return autorest.NewBearerAuthorizer(spToken), nil -} - -// ServicePrincipalToken gets the service principal token from device flow. -func (dfc DeviceFlowConfig) ServicePrincipalToken() (*adal.ServicePrincipalToken, error) { - oauthConfig, err := adal.NewOAuthConfig(dfc.AADEndpoint, dfc.TenantID) - if err != nil { - return nil, err - } - oauthClient := &autorest.Client{} - deviceCode, err := adal.InitiateDeviceAuth(oauthClient, *oauthConfig, dfc.ClientID, dfc.Resource) - if err != nil { - return nil, fmt.Errorf("failed to start device auth flow: %s", err) - } - log.Println(*deviceCode.Message) - token, err := adal.WaitForUserCompletion(oauthClient, deviceCode) - if err != nil { - return nil, fmt.Errorf("failed to finish device auth flow: %s", err) - } - return adal.NewServicePrincipalTokenFromManualToken(*oauthConfig, dfc.ClientID, dfc.Resource, *token) -} - -// UsernamePasswordConfig provides the options to get a bearer authorizer from a username and a password. -type UsernamePasswordConfig struct { - ClientID string - Username string - Password string - TenantID string - AADEndpoint string - Resource string -} - -// ServicePrincipalToken creates a ServicePrincipalToken from username and password. -func (ups UsernamePasswordConfig) ServicePrincipalToken() (*adal.ServicePrincipalToken, error) { - oauthConfig, err := adal.NewOAuthConfig(ups.AADEndpoint, ups.TenantID) - if err != nil { - return nil, err - } - return adal.NewServicePrincipalTokenFromUsernamePassword(*oauthConfig, ups.ClientID, ups.Username, ups.Password, ups.Resource) -} - -// Authorizer gets the authorizer from a username and a password. -func (ups UsernamePasswordConfig) Authorizer() (autorest.Authorizer, error) { - spToken, err := ups.ServicePrincipalToken() - if err != nil { - return nil, fmt.Errorf("failed to get oauth token from username and password auth: %v", err) - } - return autorest.NewBearerAuthorizer(spToken), nil -} - -// MSIConfig provides the options to get a bearer authorizer through MSI. -type MSIConfig struct { - Resource string - ClientID string -} - -// ServicePrincipalToken creates a ServicePrincipalToken from MSI. -func (mc MSIConfig) ServicePrincipalToken() (*adal.ServicePrincipalToken, error) { - spToken, err := adal.NewServicePrincipalTokenFromManagedIdentity(mc.Resource, &adal.ManagedIdentityOptions{ - ClientID: mc.ClientID, - }) - if err != nil { - return nil, fmt.Errorf("failed to get oauth token from MSI: %v", err) - } - return spToken, nil -} - -// Authorizer gets the authorizer from MSI. -func (mc MSIConfig) Authorizer() (autorest.Authorizer, error) { - spToken, err := mc.ServicePrincipalToken() - if err != nil { - return nil, err - } - - return autorest.NewBearerAuthorizer(spToken), nil -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/auth/go_mod_tidy_hack.go b/vendor/github.com/Azure/go-autorest/autorest/azure/auth/go_mod_tidy_hack.go deleted file mode 100644 index f7eb26fd..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/azure/auth/go_mod_tidy_hack.go +++ /dev/null @@ -1,25 +0,0 @@ -//go:build modhack -// +build modhack - -package auth - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// This file, and the github.com/Azure/go-autorest import, won't actually become part of -// the resultant binary. - -// Necessary for safely adding multi-module repo. -// See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository -import _ "github.com/Azure/go-autorest" diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/azure.go b/vendor/github.com/Azure/go-autorest/autorest/azure/azure.go deleted file mode 100644 index 09c87080..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/azure/azure.go +++ /dev/null @@ -1,388 +0,0 @@ -// Package azure provides Azure-specific implementations used with AutoRest. -// See the included examples for more detail. -package azure - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import ( - "bytes" - "encoding/json" - "fmt" - "io" - "net/http" - "regexp" - "strconv" - "strings" - - "github.com/Azure/go-autorest/autorest" -) - -const ( - // HeaderClientID is the Azure extension header to set a user-specified request ID. - HeaderClientID = "x-ms-client-request-id" - - // HeaderReturnClientID is the Azure extension header to set if the user-specified request ID - // should be included in the response. - HeaderReturnClientID = "x-ms-return-client-request-id" - - // HeaderContentType is the type of the content in the HTTP response. - HeaderContentType = "Content-Type" - - // HeaderRequestID is the Azure extension header of the service generated request ID returned - // in the response. - HeaderRequestID = "x-ms-request-id" -) - -// ServiceError encapsulates the error response from an Azure service. -// It adhears to the OData v4 specification for error responses. -type ServiceError struct { - Code string `json:"code"` - Message string `json:"message"` - Target *string `json:"target"` - Details []map[string]interface{} `json:"details"` - InnerError map[string]interface{} `json:"innererror"` - AdditionalInfo []map[string]interface{} `json:"additionalInfo"` -} - -func (se ServiceError) Error() string { - result := fmt.Sprintf("Code=%q Message=%q", se.Code, se.Message) - - if se.Target != nil { - result += fmt.Sprintf(" Target=%q", *se.Target) - } - - if se.Details != nil { - d, err := json.Marshal(se.Details) - if err != nil { - result += fmt.Sprintf(" Details=%v", se.Details) - } - result += fmt.Sprintf(" Details=%s", d) - } - - if se.InnerError != nil { - d, err := json.Marshal(se.InnerError) - if err != nil { - result += fmt.Sprintf(" InnerError=%v", se.InnerError) - } - result += fmt.Sprintf(" InnerError=%s", d) - } - - if se.AdditionalInfo != nil { - d, err := json.Marshal(se.AdditionalInfo) - if err != nil { - result += fmt.Sprintf(" AdditionalInfo=%v", se.AdditionalInfo) - } - result += fmt.Sprintf(" AdditionalInfo=%s", d) - } - - return result -} - -// UnmarshalJSON implements the json.Unmarshaler interface for the ServiceError type. -func (se *ServiceError) UnmarshalJSON(b []byte) error { - // http://docs.oasis-open.org/odata/odata-json-format/v4.0/os/odata-json-format-v4.0-os.html#_Toc372793091 - - type serviceErrorInternal struct { - Code string `json:"code"` - Message string `json:"message"` - Target *string `json:"target,omitempty"` - AdditionalInfo []map[string]interface{} `json:"additionalInfo,omitempty"` - // not all services conform to the OData v4 spec. - // the following fields are where we've seen discrepancies - - // spec calls for []map[string]interface{} but have seen map[string]interface{} - Details interface{} `json:"details,omitempty"` - - // spec calls for map[string]interface{} but have seen []map[string]interface{} and string - InnerError interface{} `json:"innererror,omitempty"` - } - - sei := serviceErrorInternal{} - if err := json.Unmarshal(b, &sei); err != nil { - return err - } - - // copy the fields we know to be correct - se.AdditionalInfo = sei.AdditionalInfo - se.Code = sei.Code - se.Message = sei.Message - se.Target = sei.Target - - // converts an []interface{} to []map[string]interface{} - arrayOfObjs := func(v interface{}) ([]map[string]interface{}, bool) { - arrayOf, ok := v.([]interface{}) - if !ok { - return nil, false - } - final := []map[string]interface{}{} - for _, item := range arrayOf { - as, ok := item.(map[string]interface{}) - if !ok { - return nil, false - } - final = append(final, as) - } - return final, true - } - - // convert the remaining fields, falling back to raw JSON if necessary - - if c, ok := arrayOfObjs(sei.Details); ok { - se.Details = c - } else if c, ok := sei.Details.(map[string]interface{}); ok { - se.Details = []map[string]interface{}{c} - } else if sei.Details != nil { - // stuff into Details - se.Details = []map[string]interface{}{ - {"raw": sei.Details}, - } - } - - if c, ok := sei.InnerError.(map[string]interface{}); ok { - se.InnerError = c - } else if c, ok := arrayOfObjs(sei.InnerError); ok { - // if there's only one error extract it - if len(c) == 1 { - se.InnerError = c[0] - } else { - // multiple errors, stuff them into the value - se.InnerError = map[string]interface{}{ - "multi": c, - } - } - } else if c, ok := sei.InnerError.(string); ok { - se.InnerError = map[string]interface{}{"error": c} - } else if sei.InnerError != nil { - // stuff into InnerError - se.InnerError = map[string]interface{}{ - "raw": sei.InnerError, - } - } - return nil -} - -// RequestError describes an error response returned by Azure service. -type RequestError struct { - autorest.DetailedError - - // The error returned by the Azure service. - ServiceError *ServiceError `json:"error" xml:"Error"` - - // The request id (from the x-ms-request-id-header) of the request. - RequestID string -} - -// Error returns a human-friendly error message from service error. -func (e RequestError) Error() string { - return fmt.Sprintf("autorest/azure: Service returned an error. Status=%v %v", - e.StatusCode, e.ServiceError) -} - -// IsAzureError returns true if the passed error is an Azure Service error; false otherwise. -func IsAzureError(e error) bool { - _, ok := e.(*RequestError) - return ok -} - -// Resource contains details about an Azure resource. -type Resource struct { - SubscriptionID string - ResourceGroup string - Provider string - ResourceType string - ResourceName string -} - -// String function returns a string in form of azureResourceID -func (r Resource) String() string { - return fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/%s/%s/%s", r.SubscriptionID, r.ResourceGroup, r.Provider, r.ResourceType, r.ResourceName) -} - -// ParseResourceID parses a resource ID into a ResourceDetails struct. -// See https://docs.microsoft.com/en-us/azure/azure-resource-manager/templates/template-functions-resource?tabs=json#resourceid. -func ParseResourceID(resourceID string) (Resource, error) { - - const resourceIDPatternText = `(?i)^/subscriptions/(.+)/resourceGroups/(.+)/providers/(.+?)/(.+?)/(.+)$` - resourceIDPattern := regexp.MustCompile(resourceIDPatternText) - match := resourceIDPattern.FindStringSubmatch(resourceID) - - if len(match) == 0 { - return Resource{}, fmt.Errorf("parsing failed for %s. Invalid resource Id format", resourceID) - } - - v := strings.Split(match[5], "/") - resourceName := v[len(v)-1] - - result := Resource{ - SubscriptionID: match[1], - ResourceGroup: match[2], - Provider: match[3], - ResourceType: match[4], - ResourceName: resourceName, - } - - return result, nil -} - -// NewErrorWithError creates a new Error conforming object from the -// passed packageType, method, statusCode of the given resp (UndefinedStatusCode -// if resp is nil), message, and original error. message is treated as a format -// string to which the optional args apply. -func NewErrorWithError(original error, packageType string, method string, resp *http.Response, message string, args ...interface{}) RequestError { - if v, ok := original.(*RequestError); ok { - return *v - } - - statusCode := autorest.UndefinedStatusCode - if resp != nil { - statusCode = resp.StatusCode - } - return RequestError{ - DetailedError: autorest.DetailedError{ - Original: original, - PackageType: packageType, - Method: method, - StatusCode: statusCode, - Message: fmt.Sprintf(message, args...), - }, - } -} - -// WithReturningClientID returns a PrepareDecorator that adds an HTTP extension header of -// x-ms-client-request-id whose value is the passed, undecorated UUID (e.g., -// "0F39878C-5F76-4DB8-A25D-61D2C193C3CA"). It also sets the x-ms-return-client-request-id -// header to true such that UUID accompanies the http.Response. -func WithReturningClientID(uuid string) autorest.PrepareDecorator { - preparer := autorest.CreatePreparer( - WithClientID(uuid), - WithReturnClientID(true)) - - return func(p autorest.Preparer) autorest.Preparer { - return autorest.PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err != nil { - return r, err - } - return preparer.Prepare(r) - }) - } -} - -// WithClientID returns a PrepareDecorator that adds an HTTP extension header of -// x-ms-client-request-id whose value is passed, undecorated UUID (e.g., -// "0F39878C-5F76-4DB8-A25D-61D2C193C3CA"). -func WithClientID(uuid string) autorest.PrepareDecorator { - return autorest.WithHeader(HeaderClientID, uuid) -} - -// WithReturnClientID returns a PrepareDecorator that adds an HTTP extension header of -// x-ms-return-client-request-id whose boolean value indicates if the value of the -// x-ms-client-request-id header should be included in the http.Response. -func WithReturnClientID(b bool) autorest.PrepareDecorator { - return autorest.WithHeader(HeaderReturnClientID, strconv.FormatBool(b)) -} - -// ExtractClientID extracts the client identifier from the x-ms-client-request-id header set on the -// http.Request sent to the service (and returned in the http.Response) -func ExtractClientID(resp *http.Response) string { - return autorest.ExtractHeaderValue(HeaderClientID, resp) -} - -// ExtractRequestID extracts the Azure server generated request identifier from the -// x-ms-request-id header. -func ExtractRequestID(resp *http.Response) string { - return autorest.ExtractHeaderValue(HeaderRequestID, resp) -} - -// WithErrorUnlessStatusCode returns a RespondDecorator that emits an -// azure.RequestError by reading the response body unless the response HTTP status code -// is among the set passed. -// -// If there is a chance service may return responses other than the Azure error -// format and the response cannot be parsed into an error, a decoding error will -// be returned containing the response body. In any case, the Responder will -// return an error if the status code is not satisfied. -// -// If this Responder returns an error, the response body will be replaced with -// an in-memory reader, which needs no further closing. -func WithErrorUnlessStatusCode(codes ...int) autorest.RespondDecorator { - return func(r autorest.Responder) autorest.Responder { - return autorest.ResponderFunc(func(resp *http.Response) error { - err := r.Respond(resp) - if err == nil && !autorest.ResponseHasStatusCode(resp, codes...) { - var e RequestError - defer resp.Body.Close() - - encodedAs := autorest.EncodedAsJSON - if strings.Contains(resp.Header.Get("Content-Type"), "xml") { - encodedAs = autorest.EncodedAsXML - } - - // Copy and replace the Body in case it does not contain an error object. - // This will leave the Body available to the caller. - b, decodeErr := autorest.CopyAndDecode(encodedAs, resp.Body, &e) - resp.Body = io.NopCloser(&b) - if decodeErr != nil { - return fmt.Errorf("autorest/azure: error response cannot be parsed: %q error: %v", b, decodeErr) - } - if e.ServiceError == nil { - // Check if error is unwrapped ServiceError - decoder := autorest.NewDecoder(encodedAs, bytes.NewReader(b.Bytes())) - if err := decoder.Decode(&e.ServiceError); err != nil { - return fmt.Errorf("autorest/azure: error response cannot be parsed: %q error: %v", b, err) - } - - // for example, should the API return the literal value `null` as the response - if e.ServiceError == nil { - e.ServiceError = &ServiceError{ - Code: "Unknown", - Message: "Unknown service error", - Details: []map[string]interface{}{ - { - "HttpResponse.Body": b.String(), - }, - }, - } - } - } - - if e.ServiceError != nil && e.ServiceError.Message == "" { - // if we're here it means the returned error wasn't OData v4 compliant. - // try to unmarshal the body in hopes of getting something. - rawBody := map[string]interface{}{} - decoder := autorest.NewDecoder(encodedAs, bytes.NewReader(b.Bytes())) - if err := decoder.Decode(&rawBody); err != nil { - return fmt.Errorf("autorest/azure: error response cannot be parsed: %q error: %v", b, err) - } - - e.ServiceError = &ServiceError{ - Code: "Unknown", - Message: "Unknown service error", - } - if len(rawBody) > 0 { - e.ServiceError.Details = []map[string]interface{}{rawBody} - } - } - e.Response = resp - e.RequestID = ExtractRequestID(resp) - if e.StatusCode == nil { - e.StatusCode = resp.StatusCode - } - err = &e - } - return err - }) - } -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/cli/LICENSE b/vendor/github.com/Azure/go-autorest/autorest/azure/cli/LICENSE deleted file mode 100644 index b9d6a27e..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/azure/cli/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2015 Microsoft Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/cli/go_mod_tidy_hack.go b/vendor/github.com/Azure/go-autorest/autorest/azure/cli/go_mod_tidy_hack.go deleted file mode 100644 index 50d6f039..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/azure/cli/go_mod_tidy_hack.go +++ /dev/null @@ -1,25 +0,0 @@ -//go:build modhack -// +build modhack - -package cli - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// This file, and the github.com/Azure/go-autorest import, won't actually become part of -// the resultant binary. - -// Necessary for safely adding multi-module repo. -// See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository -import _ "github.com/Azure/go-autorest" diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/cli/profile.go b/vendor/github.com/Azure/go-autorest/autorest/azure/cli/profile.go deleted file mode 100644 index f45c3a51..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/azure/cli/profile.go +++ /dev/null @@ -1,83 +0,0 @@ -package cli - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import ( - "bytes" - "encoding/json" - "fmt" - "io/ioutil" - "os" - "path/filepath" - - "github.com/dimchansky/utfbom" - "github.com/mitchellh/go-homedir" -) - -// Profile represents a Profile from the Azure CLI -type Profile struct { - InstallationID string `json:"installationId"` - Subscriptions []Subscription `json:"subscriptions"` -} - -// Subscription represents a Subscription from the Azure CLI -type Subscription struct { - EnvironmentName string `json:"environmentName"` - ID string `json:"id"` - IsDefault bool `json:"isDefault"` - Name string `json:"name"` - State string `json:"state"` - TenantID string `json:"tenantId"` - User *User `json:"user"` -} - -// User represents a User from the Azure CLI -type User struct { - Name string `json:"name"` - Type string `json:"type"` -} - -const azureProfileJSON = "azureProfile.json" - -func configDir() string { - return os.Getenv("AZURE_CONFIG_DIR") -} - -// ProfilePath returns the path where the Azure Profile is stored from the Azure CLI -func ProfilePath() (string, error) { - if cfgDir := configDir(); cfgDir != "" { - return filepath.Join(cfgDir, azureProfileJSON), nil - } - return homedir.Expand("~/.azure/" + azureProfileJSON) -} - -// LoadProfile restores a Profile object from a file located at 'path'. -func LoadProfile(path string) (result Profile, err error) { - var contents []byte - contents, err = ioutil.ReadFile(path) - if err != nil { - err = fmt.Errorf("failed to open file (%s) while loading token: %v", path, err) - return - } - reader := utfbom.SkipOnly(bytes.NewReader(contents)) - - dec := json.NewDecoder(reader) - if err = dec.Decode(&result); err != nil { - err = fmt.Errorf("failed to decode contents of file (%s) into a Profile representation: %v", path, err) - return - } - - return -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/cli/token.go b/vendor/github.com/Azure/go-autorest/autorest/azure/cli/token.go deleted file mode 100644 index 48661911..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/azure/cli/token.go +++ /dev/null @@ -1,227 +0,0 @@ -package cli - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import ( - "bytes" - "encoding/json" - "fmt" - "os" - "os/exec" - "path/filepath" - "regexp" - "runtime" - "strconv" - "time" - - "github.com/Azure/go-autorest/autorest/adal" - "github.com/Azure/go-autorest/autorest/date" - "github.com/mitchellh/go-homedir" -) - -// Token represents an AccessToken from the Azure CLI -type Token struct { - AccessToken string `json:"accessToken"` - Authority string `json:"_authority"` - ClientID string `json:"_clientId"` - ExpiresOn string `json:"expiresOn"` - IdentityProvider string `json:"identityProvider"` - IsMRRT bool `json:"isMRRT"` - RefreshToken string `json:"refreshToken"` - Resource string `json:"resource"` - TokenType string `json:"tokenType"` - UserID string `json:"userId"` -} - -const accessTokensJSON = "accessTokens.json" - -// ToADALToken converts an Azure CLI `Token`` to an `adal.Token`` -func (t Token) ToADALToken() (converted adal.Token, err error) { - tokenExpirationDate, err := ParseExpirationDate(t.ExpiresOn) - if err != nil { - err = fmt.Errorf("Error parsing Token Expiration Date %q: %+v", t.ExpiresOn, err) - return - } - - difference := tokenExpirationDate.Sub(date.UnixEpoch()) - - converted = adal.Token{ - AccessToken: t.AccessToken, - Type: t.TokenType, - ExpiresIn: "3600", - ExpiresOn: json.Number(strconv.Itoa(int(difference.Seconds()))), - RefreshToken: t.RefreshToken, - Resource: t.Resource, - } - return -} - -// AccessTokensPath returns the path where access tokens are stored from the Azure CLI -// TODO(#199): add unit test. -func AccessTokensPath() (string, error) { - // Azure-CLI allows user to customize the path of access tokens through environment variable. - if accessTokenPath := os.Getenv("AZURE_ACCESS_TOKEN_FILE"); accessTokenPath != "" { - return accessTokenPath, nil - } - - // Azure-CLI allows user to customize the path to Azure config directory through environment variable. - if cfgDir := configDir(); cfgDir != "" { - return filepath.Join(cfgDir, accessTokensJSON), nil - } - - // Fallback logic to default path on non-cloud-shell environment. - // TODO(#200): remove the dependency on hard-coding path. - return homedir.Expand("~/.azure/" + accessTokensJSON) -} - -// ParseExpirationDate parses either a Azure CLI or CloudShell date into a time object -func ParseExpirationDate(input string) (*time.Time, error) { - // CloudShell (and potentially the Azure CLI in future) - expirationDate, cloudShellErr := time.Parse(time.RFC3339, input) - if cloudShellErr != nil { - // Azure CLI (Python) e.g. 2017-08-31 19:48:57.998857 (plus the local timezone) - const cliFormat = "2006-01-02 15:04:05.999999" - expirationDate, cliErr := time.ParseInLocation(cliFormat, input, time.Local) - if cliErr == nil { - return &expirationDate, nil - } - - return nil, fmt.Errorf("Error parsing expiration date %q.\n\nCloudShell Error: \n%+v\n\nCLI Error:\n%+v", input, cloudShellErr, cliErr) - } - - return &expirationDate, nil -} - -// LoadTokens restores a set of Token objects from a file located at 'path'. -func LoadTokens(path string) ([]Token, error) { - file, err := os.Open(path) - if err != nil { - return nil, fmt.Errorf("failed to open file (%s) while loading token: %v", path, err) - } - defer file.Close() - - var tokens []Token - - dec := json.NewDecoder(file) - if err = dec.Decode(&tokens); err != nil { - return nil, fmt.Errorf("failed to decode contents of file (%s) into a `cli.Token` representation: %v", path, err) - } - - return tokens, nil -} - -// GetTokenFromCLI gets a token using Azure CLI 2.0 for local development scenarios. -func GetTokenFromCLI(resource string) (*Token, error) { - return GetTokenFromCLIWithParams(GetAccessTokenParams{Resource: resource}) -} - -// GetAccessTokenParams is the parameter struct of GetTokenFromCLIWithParams -type GetAccessTokenParams struct { - Resource string - ResourceType string - Subscription string - Tenant string -} - -// GetTokenFromCLIWithParams gets a token using Azure CLI 2.0 for local development scenarios. -func GetTokenFromCLIWithParams(params GetAccessTokenParams) (*Token, error) { - cliCmd := GetAzureCLICommand() - - cliCmd.Args = append(cliCmd.Args, "account", "get-access-token", "-o", "json") - if params.Resource != "" { - if err := validateParameter(params.Resource); err != nil { - return nil, err - } - cliCmd.Args = append(cliCmd.Args, "--resource", params.Resource) - } - if params.ResourceType != "" { - if err := validateParameter(params.ResourceType); err != nil { - return nil, err - } - cliCmd.Args = append(cliCmd.Args, "--resource-type", params.ResourceType) - } - if params.Subscription != "" { - if err := validateParameter(params.Subscription); err != nil { - return nil, err - } - cliCmd.Args = append(cliCmd.Args, "--subscription", params.Subscription) - } - if params.Tenant != "" { - if err := validateParameter(params.Tenant); err != nil { - return nil, err - } - cliCmd.Args = append(cliCmd.Args, "--tenant", params.Tenant) - } - - var stderr bytes.Buffer - cliCmd.Stderr = &stderr - - output, err := cliCmd.Output() - if err != nil { - if stderr.Len() > 0 { - return nil, fmt.Errorf("Invoking Azure CLI failed with the following error: %s", stderr.String()) - } - - return nil, fmt.Errorf("Invoking Azure CLI failed with the following error: %s", err.Error()) - } - - tokenResponse := Token{} - err = json.Unmarshal(output, &tokenResponse) - if err != nil { - return nil, err - } - - return &tokenResponse, err -} - -func validateParameter(param string) error { - // Validate parameters, since it gets sent as a command line argument to Azure CLI - const invalidResourceErrorTemplate = "Parameter %s is not in expected format. Only alphanumeric characters, [dot], [colon], [hyphen], and [forward slash] are allowed." - match, err := regexp.MatchString("^[0-9a-zA-Z-.:/]+$", param) - if err != nil { - return err - } - if !match { - return fmt.Errorf(invalidResourceErrorTemplate, param) - } - return nil -} - -// GetAzureCLICommand can be used to run arbitrary Azure CLI command -func GetAzureCLICommand() *exec.Cmd { - // This is the path that a developer can set to tell this class what the install path for Azure CLI is. - const azureCLIPath = "AzureCLIPath" - - // The default install paths are used to find Azure CLI. This is for security, so that any path in the calling program's Path environment is not used to execute Azure CLI. - azureCLIDefaultPathWindows := fmt.Sprintf("%s\\Microsoft SDKs\\Azure\\CLI2\\wbin; %s\\Microsoft SDKs\\Azure\\CLI2\\wbin", os.Getenv("ProgramFiles(x86)"), os.Getenv("ProgramFiles")) - - // Default path for non-Windows. - const azureCLIDefaultPath = "/bin:/sbin:/usr/bin:/usr/local/bin" - - // Execute Azure CLI to get token - var cliCmd *exec.Cmd - if runtime.GOOS == "windows" { - cliCmd = exec.Command(fmt.Sprintf("%s\\system32\\cmd.exe", os.Getenv("windir"))) - cliCmd.Env = os.Environ() - cliCmd.Env = append(cliCmd.Env, fmt.Sprintf("PATH=%s;%s", os.Getenv(azureCLIPath), azureCLIDefaultPathWindows)) - cliCmd.Args = append(cliCmd.Args, "/c", "az") - } else { - cliCmd = exec.Command("az") - cliCmd.Env = os.Environ() - cliCmd.Env = append(cliCmd.Env, fmt.Sprintf("PATH=%s:%s", os.Getenv(azureCLIPath), azureCLIDefaultPath)) - } - - return cliCmd -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/environments.go b/vendor/github.com/Azure/go-autorest/autorest/azure/environments.go deleted file mode 100644 index 4684291a..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/azure/environments.go +++ /dev/null @@ -1,330 +0,0 @@ -package azure - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import ( - "encoding/json" - "fmt" - "os" - "strings" -) - -const ( - // EnvironmentFilepathName captures the name of the environment variable containing the path to the file - // to be used while populating the Azure Environment. - EnvironmentFilepathName = "AZURE_ENVIRONMENT_FILEPATH" - - // NotAvailable is used for endpoints and resource IDs that are not available for a given cloud. - NotAvailable = "N/A" -) - -var environments = map[string]Environment{ - "AZURECHINACLOUD": ChinaCloud, - "AZUREGERMANCLOUD": GermanCloud, - "AZURECLOUD": PublicCloud, - "AZUREPUBLICCLOUD": PublicCloud, - "AZUREUSGOVERNMENT": USGovernmentCloud, - "AZUREUSGOVERNMENTCLOUD": USGovernmentCloud, //TODO: deprecate -} - -// ResourceIdentifier contains a set of Azure resource IDs. -type ResourceIdentifier struct { - Graph string `json:"graph"` - KeyVault string `json:"keyVault"` - Datalake string `json:"datalake"` - Batch string `json:"batch"` - OperationalInsights string `json:"operationalInsights"` - OSSRDBMS string `json:"ossRDBMS"` - Storage string `json:"storage"` - Synapse string `json:"synapse"` - ServiceBus string `json:"serviceBus"` - SQLDatabase string `json:"sqlDatabase"` - CosmosDB string `json:"cosmosDB"` - ManagedHSM string `json:"managedHSM"` - MicrosoftGraph string `json:"microsoftGraph"` -} - -// Environment represents a set of endpoints for each of Azure's Clouds. -type Environment struct { - Name string `json:"name"` - ManagementPortalURL string `json:"managementPortalURL"` - PublishSettingsURL string `json:"publishSettingsURL"` - ServiceManagementEndpoint string `json:"serviceManagementEndpoint"` - ResourceManagerEndpoint string `json:"resourceManagerEndpoint"` - ActiveDirectoryEndpoint string `json:"activeDirectoryEndpoint"` - GalleryEndpoint string `json:"galleryEndpoint"` - KeyVaultEndpoint string `json:"keyVaultEndpoint"` - ManagedHSMEndpoint string `json:"managedHSMEndpoint"` - GraphEndpoint string `json:"graphEndpoint"` - ServiceBusEndpoint string `json:"serviceBusEndpoint"` - BatchManagementEndpoint string `json:"batchManagementEndpoint"` - MicrosoftGraphEndpoint string `json:"microsoftGraphEndpoint"` - StorageEndpointSuffix string `json:"storageEndpointSuffix"` - CosmosDBDNSSuffix string `json:"cosmosDBDNSSuffix"` - MariaDBDNSSuffix string `json:"mariaDBDNSSuffix"` - MySQLDatabaseDNSSuffix string `json:"mySqlDatabaseDNSSuffix"` - PostgresqlDatabaseDNSSuffix string `json:"postgresqlDatabaseDNSSuffix"` - SQLDatabaseDNSSuffix string `json:"sqlDatabaseDNSSuffix"` - TrafficManagerDNSSuffix string `json:"trafficManagerDNSSuffix"` - KeyVaultDNSSuffix string `json:"keyVaultDNSSuffix"` - ManagedHSMDNSSuffix string `json:"managedHSMDNSSuffix"` - ServiceBusEndpointSuffix string `json:"serviceBusEndpointSuffix"` - ServiceManagementVMDNSSuffix string `json:"serviceManagementVMDNSSuffix"` - ResourceManagerVMDNSSuffix string `json:"resourceManagerVMDNSSuffix"` - ContainerRegistryDNSSuffix string `json:"containerRegistryDNSSuffix"` - TokenAudience string `json:"tokenAudience"` - APIManagementHostNameSuffix string `json:"apiManagementHostNameSuffix"` - SynapseEndpointSuffix string `json:"synapseEndpointSuffix"` - DatalakeSuffix string `json:"datalakeSuffix"` - ResourceIdentifiers ResourceIdentifier `json:"resourceIdentifiers"` -} - -var ( - // PublicCloud is the default public Azure cloud environment - PublicCloud = Environment{ - Name: "AzurePublicCloud", - ManagementPortalURL: "https://manage.windowsazure.com/", - PublishSettingsURL: "https://manage.windowsazure.com/publishsettings/index", - ServiceManagementEndpoint: "https://management.core.windows.net/", - ResourceManagerEndpoint: "https://management.azure.com/", - ActiveDirectoryEndpoint: "https://login.microsoftonline.com/", - GalleryEndpoint: "https://gallery.azure.com/", - KeyVaultEndpoint: "https://vault.azure.net/", - ManagedHSMEndpoint: "https://managedhsm.azure.net/", - GraphEndpoint: "https://graph.windows.net/", - ServiceBusEndpoint: "https://servicebus.windows.net/", - BatchManagementEndpoint: "https://batch.core.windows.net/", - MicrosoftGraphEndpoint: "https://graph.microsoft.com/", - StorageEndpointSuffix: "core.windows.net", - CosmosDBDNSSuffix: "documents.azure.com", - MariaDBDNSSuffix: "mariadb.database.azure.com", - MySQLDatabaseDNSSuffix: "mysql.database.azure.com", - PostgresqlDatabaseDNSSuffix: "postgres.database.azure.com", - SQLDatabaseDNSSuffix: "database.windows.net", - TrafficManagerDNSSuffix: "trafficmanager.net", - KeyVaultDNSSuffix: "vault.azure.net", - ManagedHSMDNSSuffix: "managedhsm.azure.net", - ServiceBusEndpointSuffix: "servicebus.windows.net", - ServiceManagementVMDNSSuffix: "cloudapp.net", - ResourceManagerVMDNSSuffix: "cloudapp.azure.com", - ContainerRegistryDNSSuffix: "azurecr.io", - TokenAudience: "https://management.azure.com/", - APIManagementHostNameSuffix: "azure-api.net", - SynapseEndpointSuffix: "dev.azuresynapse.net", - DatalakeSuffix: "azuredatalakestore.net", - ResourceIdentifiers: ResourceIdentifier{ - Graph: "https://graph.windows.net/", - KeyVault: "https://vault.azure.net", - Datalake: "https://datalake.azure.net/", - Batch: "https://batch.core.windows.net/", - OperationalInsights: "https://api.loganalytics.io", - OSSRDBMS: "https://ossrdbms-aad.database.windows.net", - Storage: "https://storage.azure.com/", - Synapse: "https://dev.azuresynapse.net", - ServiceBus: "https://servicebus.azure.net/", - SQLDatabase: "https://database.windows.net/", - CosmosDB: "https://cosmos.azure.com", - ManagedHSM: "https://managedhsm.azure.net", - MicrosoftGraph: "https://graph.microsoft.com/", - }, - } - - // USGovernmentCloud is the cloud environment for the US Government - USGovernmentCloud = Environment{ - Name: "AzureUSGovernmentCloud", - ManagementPortalURL: "https://manage.windowsazure.us/", - PublishSettingsURL: "https://manage.windowsazure.us/publishsettings/index", - ServiceManagementEndpoint: "https://management.core.usgovcloudapi.net/", - ResourceManagerEndpoint: "https://management.usgovcloudapi.net/", - ActiveDirectoryEndpoint: "https://login.microsoftonline.us/", - GalleryEndpoint: "https://gallery.usgovcloudapi.net/", - KeyVaultEndpoint: "https://vault.usgovcloudapi.net/", - ManagedHSMEndpoint: NotAvailable, - GraphEndpoint: "https://graph.windows.net/", - ServiceBusEndpoint: "https://servicebus.usgovcloudapi.net/", - BatchManagementEndpoint: "https://batch.core.usgovcloudapi.net/", - MicrosoftGraphEndpoint: "https://graph.microsoft.us/", - StorageEndpointSuffix: "core.usgovcloudapi.net", - CosmosDBDNSSuffix: "documents.azure.us", - MariaDBDNSSuffix: "mariadb.database.usgovcloudapi.net", - MySQLDatabaseDNSSuffix: "mysql.database.usgovcloudapi.net", - PostgresqlDatabaseDNSSuffix: "postgres.database.usgovcloudapi.net", - SQLDatabaseDNSSuffix: "database.usgovcloudapi.net", - TrafficManagerDNSSuffix: "usgovtrafficmanager.net", - KeyVaultDNSSuffix: "vault.usgovcloudapi.net", - ManagedHSMDNSSuffix: NotAvailable, - ServiceBusEndpointSuffix: "servicebus.usgovcloudapi.net", - ServiceManagementVMDNSSuffix: "usgovcloudapp.net", - ResourceManagerVMDNSSuffix: "cloudapp.usgovcloudapi.net", - ContainerRegistryDNSSuffix: "azurecr.us", - TokenAudience: "https://management.usgovcloudapi.net/", - APIManagementHostNameSuffix: "azure-api.us", - SynapseEndpointSuffix: "dev.azuresynapse.usgovcloudapi.net", - DatalakeSuffix: NotAvailable, - ResourceIdentifiers: ResourceIdentifier{ - Graph: "https://graph.windows.net/", - KeyVault: "https://vault.usgovcloudapi.net", - Datalake: NotAvailable, - Batch: "https://batch.core.usgovcloudapi.net/", - OperationalInsights: "https://api.loganalytics.us", - OSSRDBMS: "https://ossrdbms-aad.database.usgovcloudapi.net", - Storage: "https://storage.azure.com/", - Synapse: "https://dev.azuresynapse.usgovcloudapi.net", - ServiceBus: "https://servicebus.azure.net/", - SQLDatabase: "https://database.usgovcloudapi.net/", - CosmosDB: "https://cosmos.azure.com", - ManagedHSM: NotAvailable, - MicrosoftGraph: "https://graph.microsoft.us/", - }, - } - - // ChinaCloud is the cloud environment operated in China - ChinaCloud = Environment{ - Name: "AzureChinaCloud", - ManagementPortalURL: "https://manage.chinacloudapi.com/", - PublishSettingsURL: "https://manage.chinacloudapi.com/publishsettings/index", - ServiceManagementEndpoint: "https://management.core.chinacloudapi.cn/", - ResourceManagerEndpoint: "https://management.chinacloudapi.cn/", - ActiveDirectoryEndpoint: "https://login.chinacloudapi.cn/", - GalleryEndpoint: "https://gallery.chinacloudapi.cn/", - KeyVaultEndpoint: "https://vault.azure.cn/", - ManagedHSMEndpoint: NotAvailable, - GraphEndpoint: "https://graph.chinacloudapi.cn/", - ServiceBusEndpoint: "https://servicebus.chinacloudapi.cn/", - BatchManagementEndpoint: "https://batch.chinacloudapi.cn/", - MicrosoftGraphEndpoint: "https://microsoftgraph.chinacloudapi.cn/", - StorageEndpointSuffix: "core.chinacloudapi.cn", - CosmosDBDNSSuffix: "documents.azure.cn", - MariaDBDNSSuffix: "mariadb.database.chinacloudapi.cn", - MySQLDatabaseDNSSuffix: "mysql.database.chinacloudapi.cn", - PostgresqlDatabaseDNSSuffix: "postgres.database.chinacloudapi.cn", - SQLDatabaseDNSSuffix: "database.chinacloudapi.cn", - TrafficManagerDNSSuffix: "trafficmanager.cn", - KeyVaultDNSSuffix: "vault.azure.cn", - ManagedHSMDNSSuffix: NotAvailable, - ServiceBusEndpointSuffix: "servicebus.chinacloudapi.cn", - ServiceManagementVMDNSSuffix: "chinacloudapp.cn", - ResourceManagerVMDNSSuffix: "cloudapp.chinacloudapi.cn", - ContainerRegistryDNSSuffix: "azurecr.cn", - TokenAudience: "https://management.chinacloudapi.cn/", - APIManagementHostNameSuffix: "azure-api.cn", - SynapseEndpointSuffix: "dev.azuresynapse.azure.cn", - DatalakeSuffix: NotAvailable, - ResourceIdentifiers: ResourceIdentifier{ - Graph: "https://graph.chinacloudapi.cn/", - KeyVault: "https://vault.azure.cn", - Datalake: NotAvailable, - Batch: "https://batch.chinacloudapi.cn/", - OperationalInsights: NotAvailable, - OSSRDBMS: "https://ossrdbms-aad.database.chinacloudapi.cn", - Storage: "https://storage.azure.com/", - Synapse: "https://dev.azuresynapse.net", - ServiceBus: "https://servicebus.azure.net/", - SQLDatabase: "https://database.chinacloudapi.cn/", - CosmosDB: "https://cosmos.azure.com", - ManagedHSM: NotAvailable, - MicrosoftGraph: "https://microsoftgraph.chinacloudapi.cn", - }, - } - - // GermanCloud is the cloud environment operated in Germany - GermanCloud = Environment{ - Name: "AzureGermanCloud", - ManagementPortalURL: "http://portal.microsoftazure.de/", - PublishSettingsURL: "https://manage.microsoftazure.de/publishsettings/index", - ServiceManagementEndpoint: "https://management.core.cloudapi.de/", - ResourceManagerEndpoint: "https://management.microsoftazure.de/", - ActiveDirectoryEndpoint: "https://login.microsoftonline.de/", - GalleryEndpoint: "https://gallery.cloudapi.de/", - KeyVaultEndpoint: "https://vault.microsoftazure.de/", - ManagedHSMEndpoint: NotAvailable, - GraphEndpoint: "https://graph.cloudapi.de/", - ServiceBusEndpoint: "https://servicebus.cloudapi.de/", - BatchManagementEndpoint: "https://batch.cloudapi.de/", - MicrosoftGraphEndpoint: NotAvailable, - StorageEndpointSuffix: "core.cloudapi.de", - CosmosDBDNSSuffix: "documents.microsoftazure.de", - MariaDBDNSSuffix: "mariadb.database.cloudapi.de", - MySQLDatabaseDNSSuffix: "mysql.database.cloudapi.de", - PostgresqlDatabaseDNSSuffix: "postgres.database.cloudapi.de", - SQLDatabaseDNSSuffix: "database.cloudapi.de", - TrafficManagerDNSSuffix: "azuretrafficmanager.de", - KeyVaultDNSSuffix: "vault.microsoftazure.de", - ManagedHSMDNSSuffix: NotAvailable, - ServiceBusEndpointSuffix: "servicebus.cloudapi.de", - ServiceManagementVMDNSSuffix: "azurecloudapp.de", - ResourceManagerVMDNSSuffix: "cloudapp.microsoftazure.de", - ContainerRegistryDNSSuffix: NotAvailable, - TokenAudience: "https://management.microsoftazure.de/", - APIManagementHostNameSuffix: NotAvailable, - SynapseEndpointSuffix: NotAvailable, - DatalakeSuffix: NotAvailable, - ResourceIdentifiers: ResourceIdentifier{ - Graph: "https://graph.cloudapi.de/", - KeyVault: "https://vault.microsoftazure.de", - Datalake: NotAvailable, - Batch: "https://batch.cloudapi.de/", - OperationalInsights: NotAvailable, - OSSRDBMS: "https://ossrdbms-aad.database.cloudapi.de", - Storage: "https://storage.azure.com/", - Synapse: NotAvailable, - ServiceBus: "https://servicebus.azure.net/", - SQLDatabase: "https://database.cloudapi.de/", - CosmosDB: "https://cosmos.azure.com", - ManagedHSM: NotAvailable, - MicrosoftGraph: NotAvailable, - }, - } -) - -// EnvironmentFromName returns an Environment based on the common name specified. -func EnvironmentFromName(name string) (Environment, error) { - // IMPORTANT - // As per @radhikagupta5: - // This is technical debt, fundamentally here because Kubernetes is not currently accepting - // contributions to the providers. Once that is an option, the provider should be updated to - // directly call `EnvironmentFromFile`. Until then, we rely on dispatching Azure Stack environment creation - // from this method based on the name that is provided to us. - if strings.EqualFold(name, "AZURESTACKCLOUD") { - return EnvironmentFromFile(os.Getenv(EnvironmentFilepathName)) - } - - name = strings.ToUpper(name) - env, ok := environments[name] - if !ok { - return env, fmt.Errorf("autorest/azure: There is no cloud environment matching the name %q", name) - } - - return env, nil -} - -// EnvironmentFromFile loads an Environment from a configuration file available on disk. -// This function is particularly useful in the Hybrid Cloud model, where one must define their own -// endpoints. -func EnvironmentFromFile(location string) (unmarshaled Environment, err error) { - fileContents, err := os.ReadFile(location) - if err != nil { - return - } - - err = json.Unmarshal(fileContents, &unmarshaled) - - return -} - -// SetEnvironment updates the environment map with the specified values. -func SetEnvironment(name string, env Environment) { - environments[strings.ToUpper(name)] = env -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/metadata_environment.go b/vendor/github.com/Azure/go-autorest/autorest/azure/metadata_environment.go deleted file mode 100644 index f436a451..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/azure/metadata_environment.go +++ /dev/null @@ -1,245 +0,0 @@ -package azure - -import ( - "encoding/json" - "fmt" - "io" - "net/http" - "strings" - - "github.com/Azure/go-autorest/autorest" -) - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -type audience []string - -type authentication struct { - LoginEndpoint string `json:"loginEndpoint"` - Audiences audience `json:"audiences"` -} - -type environmentMetadataInfo struct { - GalleryEndpoint string `json:"galleryEndpoint"` - GraphEndpoint string `json:"graphEndpoint"` - PortalEndpoint string `json:"portalEndpoint"` - Authentication authentication `json:"authentication"` -} - -// EnvironmentProperty represent property names that clients can override -type EnvironmentProperty string - -const ( - // EnvironmentName ... - EnvironmentName EnvironmentProperty = "name" - // EnvironmentManagementPortalURL .. - EnvironmentManagementPortalURL EnvironmentProperty = "managementPortalURL" - // EnvironmentPublishSettingsURL ... - EnvironmentPublishSettingsURL EnvironmentProperty = "publishSettingsURL" - // EnvironmentServiceManagementEndpoint ... - EnvironmentServiceManagementEndpoint EnvironmentProperty = "serviceManagementEndpoint" - // EnvironmentResourceManagerEndpoint ... - EnvironmentResourceManagerEndpoint EnvironmentProperty = "resourceManagerEndpoint" - // EnvironmentActiveDirectoryEndpoint ... - EnvironmentActiveDirectoryEndpoint EnvironmentProperty = "activeDirectoryEndpoint" - // EnvironmentGalleryEndpoint ... - EnvironmentGalleryEndpoint EnvironmentProperty = "galleryEndpoint" - // EnvironmentKeyVaultEndpoint ... - EnvironmentKeyVaultEndpoint EnvironmentProperty = "keyVaultEndpoint" - // EnvironmentGraphEndpoint ... - EnvironmentGraphEndpoint EnvironmentProperty = "graphEndpoint" - // EnvironmentServiceBusEndpoint ... - EnvironmentServiceBusEndpoint EnvironmentProperty = "serviceBusEndpoint" - // EnvironmentBatchManagementEndpoint ... - EnvironmentBatchManagementEndpoint EnvironmentProperty = "batchManagementEndpoint" - // EnvironmentStorageEndpointSuffix ... - EnvironmentStorageEndpointSuffix EnvironmentProperty = "storageEndpointSuffix" - // EnvironmentSQLDatabaseDNSSuffix ... - EnvironmentSQLDatabaseDNSSuffix EnvironmentProperty = "sqlDatabaseDNSSuffix" - // EnvironmentTrafficManagerDNSSuffix ... - EnvironmentTrafficManagerDNSSuffix EnvironmentProperty = "trafficManagerDNSSuffix" - // EnvironmentKeyVaultDNSSuffix ... - EnvironmentKeyVaultDNSSuffix EnvironmentProperty = "keyVaultDNSSuffix" - // EnvironmentServiceBusEndpointSuffix ... - EnvironmentServiceBusEndpointSuffix EnvironmentProperty = "serviceBusEndpointSuffix" - // EnvironmentServiceManagementVMDNSSuffix ... - EnvironmentServiceManagementVMDNSSuffix EnvironmentProperty = "serviceManagementVMDNSSuffix" - // EnvironmentResourceManagerVMDNSSuffix ... - EnvironmentResourceManagerVMDNSSuffix EnvironmentProperty = "resourceManagerVMDNSSuffix" - // EnvironmentContainerRegistryDNSSuffix ... - EnvironmentContainerRegistryDNSSuffix EnvironmentProperty = "containerRegistryDNSSuffix" - // EnvironmentTokenAudience ... - EnvironmentTokenAudience EnvironmentProperty = "tokenAudience" -) - -// OverrideProperty represents property name and value that clients can override -type OverrideProperty struct { - Key EnvironmentProperty - Value string -} - -// EnvironmentFromURL loads an Environment from a URL -// This function is particularly useful in the Hybrid Cloud model, where one may define their own -// endpoints. -func EnvironmentFromURL(resourceManagerEndpoint string, properties ...OverrideProperty) (environment Environment, err error) { - var metadataEnvProperties environmentMetadataInfo - - if resourceManagerEndpoint == "" { - return environment, fmt.Errorf("Metadata resource manager endpoint is empty") - } - - if metadataEnvProperties, err = retrieveMetadataEnvironment(resourceManagerEndpoint); err != nil { - return environment, err - } - - // Give priority to user's override values - overrideProperties(&environment, properties) - - if environment.Name == "" { - environment.Name = "HybridEnvironment" - } - stampDNSSuffix := environment.StorageEndpointSuffix - if stampDNSSuffix == "" { - stampDNSSuffix = strings.TrimSuffix(strings.TrimPrefix(strings.Replace(resourceManagerEndpoint, strings.Split(resourceManagerEndpoint, ".")[0], "", 1), "."), "/") - environment.StorageEndpointSuffix = stampDNSSuffix - } - if environment.KeyVaultDNSSuffix == "" { - environment.KeyVaultDNSSuffix = fmt.Sprintf("%s.%s", "vault", stampDNSSuffix) - } - if environment.KeyVaultEndpoint == "" { - environment.KeyVaultEndpoint = fmt.Sprintf("%s%s", "https://", environment.KeyVaultDNSSuffix) - } - if environment.TokenAudience == "" { - environment.TokenAudience = metadataEnvProperties.Authentication.Audiences[0] - } - if environment.ActiveDirectoryEndpoint == "" { - environment.ActiveDirectoryEndpoint = metadataEnvProperties.Authentication.LoginEndpoint - } - if environment.ResourceManagerEndpoint == "" { - environment.ResourceManagerEndpoint = resourceManagerEndpoint - } - if environment.GalleryEndpoint == "" { - environment.GalleryEndpoint = metadataEnvProperties.GalleryEndpoint - } - if environment.GraphEndpoint == "" { - environment.GraphEndpoint = metadataEnvProperties.GraphEndpoint - } - - return environment, nil -} - -func overrideProperties(environment *Environment, properties []OverrideProperty) { - for _, property := range properties { - switch property.Key { - case EnvironmentName: - { - environment.Name = property.Value - } - case EnvironmentManagementPortalURL: - { - environment.ManagementPortalURL = property.Value - } - case EnvironmentPublishSettingsURL: - { - environment.PublishSettingsURL = property.Value - } - case EnvironmentServiceManagementEndpoint: - { - environment.ServiceManagementEndpoint = property.Value - } - case EnvironmentResourceManagerEndpoint: - { - environment.ResourceManagerEndpoint = property.Value - } - case EnvironmentActiveDirectoryEndpoint: - { - environment.ActiveDirectoryEndpoint = property.Value - } - case EnvironmentGalleryEndpoint: - { - environment.GalleryEndpoint = property.Value - } - case EnvironmentKeyVaultEndpoint: - { - environment.KeyVaultEndpoint = property.Value - } - case EnvironmentGraphEndpoint: - { - environment.GraphEndpoint = property.Value - } - case EnvironmentServiceBusEndpoint: - { - environment.ServiceBusEndpoint = property.Value - } - case EnvironmentBatchManagementEndpoint: - { - environment.BatchManagementEndpoint = property.Value - } - case EnvironmentStorageEndpointSuffix: - { - environment.StorageEndpointSuffix = property.Value - } - case EnvironmentSQLDatabaseDNSSuffix: - { - environment.SQLDatabaseDNSSuffix = property.Value - } - case EnvironmentTrafficManagerDNSSuffix: - { - environment.TrafficManagerDNSSuffix = property.Value - } - case EnvironmentKeyVaultDNSSuffix: - { - environment.KeyVaultDNSSuffix = property.Value - } - case EnvironmentServiceBusEndpointSuffix: - { - environment.ServiceBusEndpointSuffix = property.Value - } - case EnvironmentServiceManagementVMDNSSuffix: - { - environment.ServiceManagementVMDNSSuffix = property.Value - } - case EnvironmentResourceManagerVMDNSSuffix: - { - environment.ResourceManagerVMDNSSuffix = property.Value - } - case EnvironmentContainerRegistryDNSSuffix: - { - environment.ContainerRegistryDNSSuffix = property.Value - } - case EnvironmentTokenAudience: - { - environment.TokenAudience = property.Value - } - } - } -} - -func retrieveMetadataEnvironment(endpoint string) (environment environmentMetadataInfo, err error) { - client := autorest.NewClientWithUserAgent("") - managementEndpoint := fmt.Sprintf("%s%s", strings.TrimSuffix(endpoint, "/"), "/metadata/endpoints?api-version=1.0") - req, _ := http.NewRequest("GET", managementEndpoint, nil) - response, err := client.Do(req) - if err != nil { - return environment, err - } - defer response.Body.Close() - jsonResponse, err := io.ReadAll(response.Body) - if err != nil { - return environment, err - } - err = json.Unmarshal(jsonResponse, &environment) - return environment, err -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/azure/rp.go b/vendor/github.com/Azure/go-autorest/autorest/azure/rp.go deleted file mode 100644 index 5b52357f..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/azure/rp.go +++ /dev/null @@ -1,204 +0,0 @@ -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package azure - -import ( - "errors" - "fmt" - "net/http" - "net/url" - "strings" - "time" - - "github.com/Azure/go-autorest/autorest" -) - -// DoRetryWithRegistration tries to register the resource provider in case it is unregistered. -// It also handles request retries -func DoRetryWithRegistration(client autorest.Client) autorest.SendDecorator { - return func(s autorest.Sender) autorest.Sender { - return autorest.SenderFunc(func(r *http.Request) (resp *http.Response, err error) { - rr := autorest.NewRetriableRequest(r) - for currentAttempt := 0; currentAttempt < client.RetryAttempts; currentAttempt++ { - err = rr.Prepare() - if err != nil { - return resp, err - } - - resp, err = autorest.SendWithSender(s, rr.Request(), - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...), - ) - if err != nil { - return resp, err - } - - if resp.StatusCode != http.StatusConflict || client.SkipResourceProviderRegistration { - return resp, err - } - - var re RequestError - if strings.Contains(r.Header.Get("Content-Type"), "xml") { - // XML errors (e.g. Storage Data Plane) only return the inner object - err = autorest.Respond(resp, autorest.ByUnmarshallingXML(&re.ServiceError)) - } else { - err = autorest.Respond(resp, autorest.ByUnmarshallingJSON(&re)) - } - - if err != nil { - return resp, err - } - err = re - - if re.ServiceError != nil && re.ServiceError.Code == "MissingSubscriptionRegistration" { - regErr := register(client, r, re) - if regErr != nil { - return resp, fmt.Errorf("failed auto registering Resource Provider: %s. Original error: %w", regErr, err) - } - } - } - return resp, err - }) - } -} - -func getProvider(re RequestError) (string, error) { - if re.ServiceError != nil && len(re.ServiceError.Details) > 0 { - return re.ServiceError.Details[0]["target"].(string), nil - } - return "", errors.New("provider was not found in the response") -} - -func register(client autorest.Client, originalReq *http.Request, re RequestError) error { - subID := getSubscription(originalReq.URL.Path) - if subID == "" { - return errors.New("missing parameter subscriptionID to register resource provider") - } - providerName, err := getProvider(re) - if err != nil { - return fmt.Errorf("missing parameter provider to register resource provider: %s", err) - } - newURL := url.URL{ - Scheme: originalReq.URL.Scheme, - Host: originalReq.URL.Host, - } - - // taken from the resources SDK - // with almost identical code, this sections are easier to mantain - // It is also not a good idea to import the SDK here - // https://github.com/Azure/azure-sdk-for-go/blob/9f366792afa3e0ddaecdc860e793ba9d75e76c27/arm/resources/resources/providers.go#L252 - pathParameters := map[string]interface{}{ - "resourceProviderNamespace": autorest.Encode("path", providerName), - "subscriptionId": autorest.Encode("path", subID), - } - - const APIVersion = "2016-09-01" - queryParameters := map[string]interface{}{ - "api-version": APIVersion, - } - - preparer := autorest.CreatePreparer( - autorest.AsPost(), - autorest.WithBaseURL(newURL.String()), - autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/{resourceProviderNamespace}/register", pathParameters), - autorest.WithQueryParameters(queryParameters), - ) - - req, err := preparer.Prepare(&http.Request{}) - if err != nil { - return err - } - req = req.WithContext(originalReq.Context()) - - resp, err := autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...), - ) - if err != nil { - return err - } - - type Provider struct { - RegistrationState *string `json:"registrationState,omitempty"` - } - var provider Provider - - err = autorest.Respond( - resp, - WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByUnmarshallingJSON(&provider), - autorest.ByClosing(), - ) - if err != nil { - return err - } - - // poll for registered provisioning state - registrationStartTime := time.Now() - for err == nil && (client.PollingDuration == 0 || (client.PollingDuration != 0 && time.Since(registrationStartTime) < client.PollingDuration)) { - // taken from the resources SDK - // https://github.com/Azure/azure-sdk-for-go/blob/9f366792afa3e0ddaecdc860e793ba9d75e76c27/arm/resources/resources/providers.go#L45 - preparer := autorest.CreatePreparer( - autorest.AsGet(), - autorest.WithBaseURL(newURL.String()), - autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/{resourceProviderNamespace}", pathParameters), - autorest.WithQueryParameters(queryParameters), - ) - req, err = preparer.Prepare(&http.Request{}) - if err != nil { - return err - } - req = req.WithContext(originalReq.Context()) - - resp, err := autorest.SendWithSender(client, req, - autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...), - ) - if err != nil { - return err - } - - err = autorest.Respond( - resp, - WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByUnmarshallingJSON(&provider), - autorest.ByClosing(), - ) - if err != nil { - return err - } - - if provider.RegistrationState != nil && - *provider.RegistrationState == "Registered" { - break - } - - delayed := autorest.DelayWithRetryAfter(resp, originalReq.Context().Done()) - if !delayed && !autorest.DelayForBackoff(client.PollingDelay, 0, originalReq.Context().Done()) { - return originalReq.Context().Err() - } - } - if client.PollingDuration != 0 && !(time.Since(registrationStartTime) < client.PollingDuration) { - return errors.New("polling for resource provider registration has exceeded the polling duration") - } - return err -} - -func getSubscription(path string) string { - parts := strings.Split(path, "/") - for i, v := range parts { - if v == "subscriptions" && (i+1) < len(parts) { - return parts[i+1] - } - } - return "" -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/client.go b/vendor/github.com/Azure/go-autorest/autorest/client.go deleted file mode 100644 index b2f2357e..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/client.go +++ /dev/null @@ -1,327 +0,0 @@ -package autorest - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import ( - "bytes" - "crypto/tls" - "errors" - "fmt" - "io" - "log" - "net/http" - "strings" - "time" - - "github.com/Azure/go-autorest/logger" -) - -const ( - // DefaultPollingDelay is a reasonable delay between polling requests. - DefaultPollingDelay = 30 * time.Second - - // DefaultPollingDuration is a reasonable total polling duration. - DefaultPollingDuration = 15 * time.Minute - - // DefaultRetryAttempts is number of attempts for retry status codes (5xx). - DefaultRetryAttempts = 3 - - // DefaultRetryDuration is the duration to wait between retries. - DefaultRetryDuration = 30 * time.Second -) - -var ( - // StatusCodesForRetry are a defined group of status code for which the client will retry - StatusCodesForRetry = []int{ - http.StatusRequestTimeout, // 408 - http.StatusTooManyRequests, // 429 - http.StatusInternalServerError, // 500 - http.StatusBadGateway, // 502 - http.StatusServiceUnavailable, // 503 - http.StatusGatewayTimeout, // 504 - } -) - -const ( - requestFormat = `HTTP Request Begin =================================================== -%s -===================================================== HTTP Request End -` - responseFormat = `HTTP Response Begin =================================================== -%s -===================================================== HTTP Response End -` -) - -// Response serves as the base for all responses from generated clients. It provides access to the -// last http.Response. -type Response struct { - *http.Response `json:"-"` -} - -// IsHTTPStatus returns true if the returned HTTP status code matches the provided status code. -// If there was no response (i.e. the underlying http.Response is nil) the return value is false. -func (r Response) IsHTTPStatus(statusCode int) bool { - if r.Response == nil { - return false - } - return r.Response.StatusCode == statusCode -} - -// HasHTTPStatus returns true if the returned HTTP status code matches one of the provided status codes. -// If there was no response (i.e. the underlying http.Response is nil) or not status codes are provided -// the return value is false. -func (r Response) HasHTTPStatus(statusCodes ...int) bool { - return ResponseHasStatusCode(r.Response, statusCodes...) -} - -// LoggingInspector implements request and response inspectors that log the full request and -// response to a supplied log. -type LoggingInspector struct { - Logger *log.Logger -} - -// WithInspection returns a PrepareDecorator that emits the http.Request to the supplied logger. The -// body is restored after being emitted. -// -// Note: Since it reads the entire Body, this decorator should not be used where body streaming is -// important. It is best used to trace JSON or similar body values. -func (li LoggingInspector) WithInspection() PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - var body, b bytes.Buffer - - defer r.Body.Close() - - r.Body = io.NopCloser(io.TeeReader(r.Body, &body)) - if err := r.Write(&b); err != nil { - return nil, fmt.Errorf("Failed to write response: %v", err) - } - - li.Logger.Printf(requestFormat, b.String()) - - r.Body = io.NopCloser(&body) - return p.Prepare(r) - }) - } -} - -// ByInspecting returns a RespondDecorator that emits the http.Response to the supplied logger. The -// body is restored after being emitted. -// -// Note: Since it reads the entire Body, this decorator should not be used where body streaming is -// important. It is best used to trace JSON or similar body values. -func (li LoggingInspector) ByInspecting() RespondDecorator { - return func(r Responder) Responder { - return ResponderFunc(func(resp *http.Response) error { - var body, b bytes.Buffer - defer resp.Body.Close() - resp.Body = io.NopCloser(io.TeeReader(resp.Body, &body)) - if err := resp.Write(&b); err != nil { - return fmt.Errorf("Failed to write response: %v", err) - } - - li.Logger.Printf(responseFormat, b.String()) - - resp.Body = io.NopCloser(&body) - return r.Respond(resp) - }) - } -} - -// Client is the base for autorest generated clients. It provides default, "do nothing" -// implementations of an Authorizer, RequestInspector, and ResponseInspector. It also returns the -// standard, undecorated http.Client as a default Sender. -// -// Generated clients should also use Error (see NewError and NewErrorWithError) for errors and -// return responses that compose with Response. -// -// Most customization of generated clients is best achieved by supplying a custom Authorizer, custom -// RequestInspector, and / or custom ResponseInspector. Users may log requests, implement circuit -// breakers (see https://msdn.microsoft.com/en-us/library/dn589784.aspx) or otherwise influence -// sending the request by providing a decorated Sender. -type Client struct { - Authorizer Authorizer - Sender Sender - RequestInspector PrepareDecorator - ResponseInspector RespondDecorator - - // PollingDelay sets the polling frequency used in absence of a Retry-After HTTP header - PollingDelay time.Duration - - // PollingDuration sets the maximum polling time after which an error is returned. - // Setting this to zero will use the provided context to control the duration. - PollingDuration time.Duration - - // RetryAttempts sets the total number of times the client will attempt to make an HTTP request. - // Set the value to 1 to disable retries. DO NOT set the value to less than 1. - RetryAttempts int - - // RetryDuration sets the delay duration for retries. - RetryDuration time.Duration - - // UserAgent, if not empty, will be set as the HTTP User-Agent header on all requests sent - // through the Do method. - UserAgent string - - Jar http.CookieJar - - // Set to true to skip attempted registration of resource providers (false by default). - SkipResourceProviderRegistration bool - - // SendDecorators can be used to override the default chain of SendDecorators. - // This can be used to specify things like a custom retry SendDecorator. - // Set this to an empty slice to use no SendDecorators. - SendDecorators []SendDecorator -} - -// NewClientWithUserAgent returns an instance of a Client with the UserAgent set to the passed -// string. -func NewClientWithUserAgent(ua string) Client { - return newClient(ua, tls.RenegotiateNever) -} - -// ClientOptions contains various Client configuration options. -type ClientOptions struct { - // UserAgent is an optional user-agent string to append to the default user agent. - UserAgent string - - // Renegotiation is an optional setting to control client-side TLS renegotiation. - Renegotiation tls.RenegotiationSupport -} - -// NewClientWithOptions returns an instance of a Client with the specified values. -func NewClientWithOptions(options ClientOptions) Client { - return newClient(options.UserAgent, options.Renegotiation) -} - -func newClient(ua string, renegotiation tls.RenegotiationSupport) Client { - c := Client{ - PollingDelay: DefaultPollingDelay, - PollingDuration: DefaultPollingDuration, - RetryAttempts: DefaultRetryAttempts, - RetryDuration: DefaultRetryDuration, - UserAgent: UserAgent(), - } - c.Sender = c.sender(renegotiation) - c.AddToUserAgent(ua) - return c -} - -// AddToUserAgent adds an extension to the current user agent -func (c *Client) AddToUserAgent(extension string) error { - if extension != "" { - c.UserAgent = fmt.Sprintf("%s %s", c.UserAgent, extension) - return nil - } - return fmt.Errorf("Extension was empty, User Agent stayed as %s", c.UserAgent) -} - -// Do implements the Sender interface by invoking the active Sender after applying authorization. -// If Sender is not set, it uses a new instance of http.Client. In both cases it will, if UserAgent -// is set, apply set the User-Agent header. -func (c Client) Do(r *http.Request) (*http.Response, error) { - if r.UserAgent() == "" { - r, _ = Prepare(r, - WithUserAgent(c.UserAgent)) - } - // NOTE: c.WithInspection() must be last in the list so that it can inspect all preceding operations - r, err := Prepare(r, - c.WithAuthorization(), - c.WithInspection()) - if err != nil { - var resp *http.Response - if detErr, ok := err.(DetailedError); ok { - // if the authorization failed (e.g. invalid credentials) there will - // be a response associated with the error, be sure to return it. - resp = detErr.Response - } - return resp, NewErrorWithError(err, "autorest/Client", "Do", nil, "Preparing request failed") - } - logger.Instance.WriteRequest(r, logger.Filter{ - Header: func(k string, v []string) (bool, []string) { - // remove the auth token from the log - if strings.EqualFold(k, "Authorization") || strings.EqualFold(k, "Ocp-Apim-Subscription-Key") { - v = []string{"**REDACTED**"} - } - return true, v - }, - }) - resp, err := SendWithSender(c.sender(tls.RenegotiateNever), r) - if resp == nil && err == nil { - err = errors.New("autorest: received nil response and error") - } - logger.Instance.WriteResponse(resp, logger.Filter{}) - Respond(resp, c.ByInspecting()) - return resp, err -} - -// sender returns the Sender to which to send requests. -func (c Client) sender(renengotiation tls.RenegotiationSupport) Sender { - if c.Sender == nil { - return sender(renengotiation) - } - return c.Sender -} - -// WithAuthorization is a convenience method that returns the WithAuthorization PrepareDecorator -// from the current Authorizer. If not Authorizer is set, it uses the NullAuthorizer. -func (c Client) WithAuthorization() PrepareDecorator { - return c.authorizer().WithAuthorization() -} - -// authorizer returns the Authorizer to use. -func (c Client) authorizer() Authorizer { - if c.Authorizer == nil { - return NullAuthorizer{} - } - return c.Authorizer -} - -// WithInspection is a convenience method that passes the request to the supplied RequestInspector, -// if present, or returns the WithNothing PrepareDecorator otherwise. -func (c Client) WithInspection() PrepareDecorator { - if c.RequestInspector == nil { - return WithNothing() - } - return c.RequestInspector -} - -// ByInspecting is a convenience method that passes the response to the supplied ResponseInspector, -// if present, or returns the ByIgnoring RespondDecorator otherwise. -func (c Client) ByInspecting() RespondDecorator { - if c.ResponseInspector == nil { - return ByIgnoring() - } - return c.ResponseInspector -} - -// Send sends the provided http.Request using the client's Sender or the default sender. -// It returns the http.Response and possible error. It also accepts a, possibly empty, -// default set of SendDecorators used when sending the request. -// SendDecorators have the following precedence: -// 1. In a request's context via WithSendDecorators() -// 2. Specified on the client in SendDecorators -// 3. The default values specified in this method -func (c Client) Send(req *http.Request, decorators ...SendDecorator) (*http.Response, error) { - if c.SendDecorators != nil { - decorators = c.SendDecorators - } - inCtx := req.Context().Value(ctxSendDecorators{}) - if sd, ok := inCtx.([]SendDecorator); ok { - decorators = sd - } - return SendWithSender(c, req, decorators...) -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/date/LICENSE b/vendor/github.com/Azure/go-autorest/autorest/date/LICENSE deleted file mode 100644 index b9d6a27e..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/date/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2015 Microsoft Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/Azure/go-autorest/autorest/date/date.go b/vendor/github.com/Azure/go-autorest/autorest/date/date.go deleted file mode 100644 index c4571065..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/date/date.go +++ /dev/null @@ -1,96 +0,0 @@ -/* -Package date provides time.Time derivatives that conform to the Swagger.io (https://swagger.io/) -defined date formats: Date and DateTime. Both types may, in most cases, be used in lieu of -time.Time types. And both convert to time.Time through a ToTime method. -*/ -package date - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import ( - "fmt" - "time" -) - -const ( - fullDate = "2006-01-02" - fullDateJSON = `"2006-01-02"` - dateFormat = "%04d-%02d-%02d" - jsonFormat = `"%04d-%02d-%02d"` -) - -// Date defines a type similar to time.Time but assumes a layout of RFC3339 full-date (i.e., -// 2006-01-02). -type Date struct { - time.Time -} - -// ParseDate create a new Date from the passed string. -func ParseDate(date string) (d Date, err error) { - return parseDate(date, fullDate) -} - -func parseDate(date string, format string) (Date, error) { - d, err := time.Parse(format, date) - return Date{Time: d}, err -} - -// MarshalBinary preserves the Date as a byte array conforming to RFC3339 full-date (i.e., -// 2006-01-02). -func (d Date) MarshalBinary() ([]byte, error) { - return d.MarshalText() -} - -// UnmarshalBinary reconstitutes a Date saved as a byte array conforming to RFC3339 full-date (i.e., -// 2006-01-02). -func (d *Date) UnmarshalBinary(data []byte) error { - return d.UnmarshalText(data) -} - -// MarshalJSON preserves the Date as a JSON string conforming to RFC3339 full-date (i.e., -// 2006-01-02). -func (d Date) MarshalJSON() (json []byte, err error) { - return []byte(fmt.Sprintf(jsonFormat, d.Year(), d.Month(), d.Day())), nil -} - -// UnmarshalJSON reconstitutes the Date from a JSON string conforming to RFC3339 full-date (i.e., -// 2006-01-02). -func (d *Date) UnmarshalJSON(data []byte) (err error) { - d.Time, err = time.Parse(fullDateJSON, string(data)) - return err -} - -// MarshalText preserves the Date as a byte array conforming to RFC3339 full-date (i.e., -// 2006-01-02). -func (d Date) MarshalText() (text []byte, err error) { - return []byte(fmt.Sprintf(dateFormat, d.Year(), d.Month(), d.Day())), nil -} - -// UnmarshalText reconstitutes a Date saved as a byte array conforming to RFC3339 full-date (i.e., -// 2006-01-02). -func (d *Date) UnmarshalText(data []byte) (err error) { - d.Time, err = time.Parse(fullDate, string(data)) - return err -} - -// String returns the Date formatted as an RFC3339 full-date string (i.e., 2006-01-02). -func (d Date) String() string { - return fmt.Sprintf(dateFormat, d.Year(), d.Month(), d.Day()) -} - -// ToTime returns a Date as a time.Time -func (d Date) ToTime() time.Time { - return d.Time -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/date/go_mod_tidy_hack.go b/vendor/github.com/Azure/go-autorest/autorest/date/go_mod_tidy_hack.go deleted file mode 100644 index 4e054320..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/date/go_mod_tidy_hack.go +++ /dev/null @@ -1,24 +0,0 @@ -// +build modhack - -package date - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// This file, and the github.com/Azure/go-autorest import, won't actually become part of -// the resultant binary. - -// Necessary for safely adding multi-module repo. -// See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository -import _ "github.com/Azure/go-autorest" diff --git a/vendor/github.com/Azure/go-autorest/autorest/date/time.go b/vendor/github.com/Azure/go-autorest/autorest/date/time.go deleted file mode 100644 index b453fad0..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/date/time.go +++ /dev/null @@ -1,103 +0,0 @@ -package date - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import ( - "regexp" - "time" -) - -// Azure reports time in UTC but it doesn't include the 'Z' time zone suffix in some cases. -const ( - azureUtcFormatJSON = `"2006-01-02T15:04:05.999999999"` - azureUtcFormat = "2006-01-02T15:04:05.999999999" - rfc3339JSON = `"` + time.RFC3339Nano + `"` - rfc3339 = time.RFC3339Nano - tzOffsetRegex = `(Z|z|\+|-)(\d+:\d+)*"*$` -) - -// Time defines a type similar to time.Time but assumes a layout of RFC3339 date-time (i.e., -// 2006-01-02T15:04:05Z). -type Time struct { - time.Time -} - -// MarshalBinary preserves the Time as a byte array conforming to RFC3339 date-time (i.e., -// 2006-01-02T15:04:05Z). -func (t Time) MarshalBinary() ([]byte, error) { - return t.Time.MarshalText() -} - -// UnmarshalBinary reconstitutes a Time saved as a byte array conforming to RFC3339 date-time -// (i.e., 2006-01-02T15:04:05Z). -func (t *Time) UnmarshalBinary(data []byte) error { - return t.UnmarshalText(data) -} - -// MarshalJSON preserves the Time as a JSON string conforming to RFC3339 date-time (i.e., -// 2006-01-02T15:04:05Z). -func (t Time) MarshalJSON() (json []byte, err error) { - return t.Time.MarshalJSON() -} - -// UnmarshalJSON reconstitutes the Time from a JSON string conforming to RFC3339 date-time -// (i.e., 2006-01-02T15:04:05Z). -func (t *Time) UnmarshalJSON(data []byte) (err error) { - timeFormat := azureUtcFormatJSON - match, err := regexp.Match(tzOffsetRegex, data) - if err != nil { - return err - } else if match { - timeFormat = rfc3339JSON - } - t.Time, err = ParseTime(timeFormat, string(data)) - return err -} - -// MarshalText preserves the Time as a byte array conforming to RFC3339 date-time (i.e., -// 2006-01-02T15:04:05Z). -func (t Time) MarshalText() (text []byte, err error) { - return t.Time.MarshalText() -} - -// UnmarshalText reconstitutes a Time saved as a byte array conforming to RFC3339 date-time -// (i.e., 2006-01-02T15:04:05Z). -func (t *Time) UnmarshalText(data []byte) (err error) { - timeFormat := azureUtcFormat - match, err := regexp.Match(tzOffsetRegex, data) - if err != nil { - return err - } else if match { - timeFormat = rfc3339 - } - t.Time, err = ParseTime(timeFormat, string(data)) - return err -} - -// String returns the Time formatted as an RFC3339 date-time string (i.e., -// 2006-01-02T15:04:05Z). -func (t Time) String() string { - // Note: time.Time.String does not return an RFC3339 compliant string, time.Time.MarshalText does. - b, err := t.MarshalText() - if err != nil { - return "" - } - return string(b) -} - -// ToTime returns a Time as a time.Time -func (t Time) ToTime() time.Time { - return t.Time -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/date/timerfc1123.go b/vendor/github.com/Azure/go-autorest/autorest/date/timerfc1123.go deleted file mode 100644 index 48fb39ba..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/date/timerfc1123.go +++ /dev/null @@ -1,100 +0,0 @@ -package date - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import ( - "errors" - "time" -) - -const ( - rfc1123JSON = `"` + time.RFC1123 + `"` - rfc1123 = time.RFC1123 -) - -// TimeRFC1123 defines a type similar to time.Time but assumes a layout of RFC1123 date-time (i.e., -// Mon, 02 Jan 2006 15:04:05 MST). -type TimeRFC1123 struct { - time.Time -} - -// UnmarshalJSON reconstitutes the Time from a JSON string conforming to RFC1123 date-time -// (i.e., Mon, 02 Jan 2006 15:04:05 MST). -func (t *TimeRFC1123) UnmarshalJSON(data []byte) (err error) { - t.Time, err = ParseTime(rfc1123JSON, string(data)) - if err != nil { - return err - } - return nil -} - -// MarshalJSON preserves the Time as a JSON string conforming to RFC1123 date-time (i.e., -// Mon, 02 Jan 2006 15:04:05 MST). -func (t TimeRFC1123) MarshalJSON() ([]byte, error) { - if y := t.Year(); y < 0 || y >= 10000 { - return nil, errors.New("Time.MarshalJSON: year outside of range [0,9999]") - } - b := []byte(t.Format(rfc1123JSON)) - return b, nil -} - -// MarshalText preserves the Time as a byte array conforming to RFC1123 date-time (i.e., -// Mon, 02 Jan 2006 15:04:05 MST). -func (t TimeRFC1123) MarshalText() ([]byte, error) { - if y := t.Year(); y < 0 || y >= 10000 { - return nil, errors.New("Time.MarshalText: year outside of range [0,9999]") - } - - b := []byte(t.Format(rfc1123)) - return b, nil -} - -// UnmarshalText reconstitutes a Time saved as a byte array conforming to RFC1123 date-time -// (i.e., Mon, 02 Jan 2006 15:04:05 MST). -func (t *TimeRFC1123) UnmarshalText(data []byte) (err error) { - t.Time, err = ParseTime(rfc1123, string(data)) - if err != nil { - return err - } - return nil -} - -// MarshalBinary preserves the Time as a byte array conforming to RFC1123 date-time (i.e., -// Mon, 02 Jan 2006 15:04:05 MST). -func (t TimeRFC1123) MarshalBinary() ([]byte, error) { - return t.MarshalText() -} - -// UnmarshalBinary reconstitutes a Time saved as a byte array conforming to RFC1123 date-time -// (i.e., Mon, 02 Jan 2006 15:04:05 MST). -func (t *TimeRFC1123) UnmarshalBinary(data []byte) error { - return t.UnmarshalText(data) -} - -// ToTime returns a Time as a time.Time -func (t TimeRFC1123) ToTime() time.Time { - return t.Time -} - -// String returns the Time formatted as an RFC1123 date-time string (i.e., -// Mon, 02 Jan 2006 15:04:05 MST). -func (t TimeRFC1123) String() string { - // Note: time.Time.String does not return an RFC1123 compliant string, time.Time.MarshalText does. - b, err := t.MarshalText() - if err != nil { - return "" - } - return string(b) -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/date/unixtime.go b/vendor/github.com/Azure/go-autorest/autorest/date/unixtime.go deleted file mode 100644 index 7073959b..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/date/unixtime.go +++ /dev/null @@ -1,123 +0,0 @@ -package date - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import ( - "bytes" - "encoding/binary" - "encoding/json" - "time" -) - -// unixEpoch is the moment in time that should be treated as timestamp 0. -var unixEpoch = time.Date(1970, time.January, 1, 0, 0, 0, 0, time.UTC) - -// UnixTime marshals and unmarshals a time that is represented as the number -// of seconds (ignoring skip-seconds) since the Unix Epoch. -type UnixTime time.Time - -// Duration returns the time as a Duration since the UnixEpoch. -func (t UnixTime) Duration() time.Duration { - return time.Time(t).Sub(unixEpoch) -} - -// NewUnixTimeFromSeconds creates a UnixTime as a number of seconds from the UnixEpoch. -func NewUnixTimeFromSeconds(seconds float64) UnixTime { - return NewUnixTimeFromDuration(time.Duration(seconds * float64(time.Second))) -} - -// NewUnixTimeFromNanoseconds creates a UnixTime as a number of nanoseconds from the UnixEpoch. -func NewUnixTimeFromNanoseconds(nanoseconds int64) UnixTime { - return NewUnixTimeFromDuration(time.Duration(nanoseconds)) -} - -// NewUnixTimeFromDuration creates a UnixTime as a duration of time since the UnixEpoch. -func NewUnixTimeFromDuration(dur time.Duration) UnixTime { - return UnixTime(unixEpoch.Add(dur)) -} - -// UnixEpoch retreives the moment considered the Unix Epoch. I.e. The time represented by '0' -func UnixEpoch() time.Time { - return unixEpoch -} - -// MarshalJSON preserves the UnixTime as a JSON number conforming to Unix Timestamp requirements. -// (i.e. the number of seconds since midnight January 1st, 1970 not considering leap seconds.) -func (t UnixTime) MarshalJSON() ([]byte, error) { - buffer := &bytes.Buffer{} - enc := json.NewEncoder(buffer) - err := enc.Encode(float64(time.Time(t).UnixNano()) / 1e9) - if err != nil { - return nil, err - } - return buffer.Bytes(), nil -} - -// UnmarshalJSON reconstitures a UnixTime saved as a JSON number of the number of seconds since -// midnight January 1st, 1970. -func (t *UnixTime) UnmarshalJSON(text []byte) error { - dec := json.NewDecoder(bytes.NewReader(text)) - - var secondsSinceEpoch float64 - if err := dec.Decode(&secondsSinceEpoch); err != nil { - return err - } - - *t = NewUnixTimeFromSeconds(secondsSinceEpoch) - - return nil -} - -// MarshalText stores the number of seconds since the Unix Epoch as a textual floating point number. -func (t UnixTime) MarshalText() ([]byte, error) { - cast := time.Time(t) - return cast.MarshalText() -} - -// UnmarshalText populates a UnixTime with a value stored textually as a floating point number of seconds since the Unix Epoch. -func (t *UnixTime) UnmarshalText(raw []byte) error { - var unmarshaled time.Time - - if err := unmarshaled.UnmarshalText(raw); err != nil { - return err - } - - *t = UnixTime(unmarshaled) - return nil -} - -// MarshalBinary converts a UnixTime into a binary.LittleEndian float64 of nanoseconds since the epoch. -func (t UnixTime) MarshalBinary() ([]byte, error) { - buf := &bytes.Buffer{} - - payload := int64(t.Duration()) - - if err := binary.Write(buf, binary.LittleEndian, &payload); err != nil { - return nil, err - } - - return buf.Bytes(), nil -} - -// UnmarshalBinary converts a from a binary.LittleEndian float64 of nanoseconds since the epoch into a UnixTime. -func (t *UnixTime) UnmarshalBinary(raw []byte) error { - var nanosecondsSinceEpoch int64 - - if err := binary.Read(bytes.NewReader(raw), binary.LittleEndian, &nanosecondsSinceEpoch); err != nil { - return err - } - *t = NewUnixTimeFromNanoseconds(nanosecondsSinceEpoch) - return nil -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/date/utility.go b/vendor/github.com/Azure/go-autorest/autorest/date/utility.go deleted file mode 100644 index 12addf0e..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/date/utility.go +++ /dev/null @@ -1,25 +0,0 @@ -package date - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import ( - "strings" - "time" -) - -// ParseTime to parse Time string to specified format. -func ParseTime(format string, t string) (d time.Time, err error) { - return time.Parse(format, strings.ToUpper(t)) -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/error.go b/vendor/github.com/Azure/go-autorest/autorest/error.go deleted file mode 100644 index 35098eda..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/error.go +++ /dev/null @@ -1,103 +0,0 @@ -package autorest - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import ( - "fmt" - "net/http" -) - -const ( - // UndefinedStatusCode is used when HTTP status code is not available for an error. - UndefinedStatusCode = 0 -) - -// DetailedError encloses a error with details of the package, method, and associated HTTP -// status code (if any). -type DetailedError struct { - Original error - - // PackageType is the package type of the object emitting the error. For types, the value - // matches that produced the the '%T' format specifier of the fmt package. For other elements, - // such as functions, it is just the package name (e.g., "autorest"). - PackageType string - - // Method is the name of the method raising the error. - Method string - - // StatusCode is the HTTP Response StatusCode (if non-zero) that led to the error. - StatusCode interface{} - - // Message is the error message. - Message string - - // Service Error is the response body of failed API in bytes - ServiceError []byte - - // Response is the response object that was returned during failure if applicable. - Response *http.Response -} - -// NewError creates a new Error conforming object from the passed packageType, method, and -// message. message is treated as a format string to which the optional args apply. -func NewError(packageType string, method string, message string, args ...interface{}) DetailedError { - return NewErrorWithError(nil, packageType, method, nil, message, args...) -} - -// NewErrorWithResponse creates a new Error conforming object from the passed -// packageType, method, statusCode of the given resp (UndefinedStatusCode if -// resp is nil), and message. message is treated as a format string to which the -// optional args apply. -func NewErrorWithResponse(packageType string, method string, resp *http.Response, message string, args ...interface{}) DetailedError { - return NewErrorWithError(nil, packageType, method, resp, message, args...) -} - -// NewErrorWithError creates a new Error conforming object from the -// passed packageType, method, statusCode of the given resp (UndefinedStatusCode -// if resp is nil), message, and original error. message is treated as a format -// string to which the optional args apply. -func NewErrorWithError(original error, packageType string, method string, resp *http.Response, message string, args ...interface{}) DetailedError { - if v, ok := original.(DetailedError); ok { - return v - } - - statusCode := UndefinedStatusCode - if resp != nil { - statusCode = resp.StatusCode - } - - return DetailedError{ - Original: original, - PackageType: packageType, - Method: method, - StatusCode: statusCode, - Message: fmt.Sprintf(message, args...), - Response: resp, - } -} - -// Error returns a formatted containing all available details (i.e., PackageType, Method, -// StatusCode, Message, and original error (if any)). -func (e DetailedError) Error() string { - if e.Original == nil { - return fmt.Sprintf("%s#%s: %s: StatusCode=%d", e.PackageType, e.Method, e.Message, e.StatusCode) - } - return fmt.Sprintf("%s#%s: %s: StatusCode=%d -- Original Error: %v", e.PackageType, e.Method, e.Message, e.StatusCode, e.Original) -} - -// Unwrap returns the original error. -func (e DetailedError) Unwrap() error { - return e.Original -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/go_mod_tidy_hack.go b/vendor/github.com/Azure/go-autorest/autorest/go_mod_tidy_hack.go deleted file mode 100644 index 792f82d4..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/go_mod_tidy_hack.go +++ /dev/null @@ -1,25 +0,0 @@ -//go:build modhack -// +build modhack - -package autorest - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// This file, and the github.com/Azure/go-autorest import, won't actually become part of -// the resultant binary. - -// Necessary for safely adding multi-module repo. -// See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository -import _ "github.com/Azure/go-autorest" diff --git a/vendor/github.com/Azure/go-autorest/autorest/preparer.go b/vendor/github.com/Azure/go-autorest/autorest/preparer.go deleted file mode 100644 index f6de8c5e..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/preparer.go +++ /dev/null @@ -1,548 +0,0 @@ -package autorest - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import ( - "bytes" - "context" - "encoding/json" - "encoding/xml" - "fmt" - "io" - "mime/multipart" - "net/http" - "net/url" - "strings" -) - -const ( - mimeTypeJSON = "application/json" - mimeTypeOctetStream = "application/octet-stream" - mimeTypeFormPost = "application/x-www-form-urlencoded" - - headerAuthorization = "Authorization" - headerAuxAuthorization = "x-ms-authorization-auxiliary" - headerContentType = "Content-Type" - headerUserAgent = "User-Agent" -) - -// used as a key type in context.WithValue() -type ctxPrepareDecorators struct{} - -// WithPrepareDecorators adds the specified PrepareDecorators to the provided context. -// If no PrepareDecorators are provided the context is unchanged. -func WithPrepareDecorators(ctx context.Context, prepareDecorator []PrepareDecorator) context.Context { - if len(prepareDecorator) == 0 { - return ctx - } - return context.WithValue(ctx, ctxPrepareDecorators{}, prepareDecorator) -} - -// GetPrepareDecorators returns the PrepareDecorators in the provided context or the provided default PrepareDecorators. -func GetPrepareDecorators(ctx context.Context, defaultPrepareDecorators ...PrepareDecorator) []PrepareDecorator { - inCtx := ctx.Value(ctxPrepareDecorators{}) - if pd, ok := inCtx.([]PrepareDecorator); ok { - return pd - } - return defaultPrepareDecorators -} - -// Preparer is the interface that wraps the Prepare method. -// -// Prepare accepts and possibly modifies an http.Request (e.g., adding Headers). Implementations -// must ensure to not share or hold per-invocation state since Preparers may be shared and re-used. -type Preparer interface { - Prepare(*http.Request) (*http.Request, error) -} - -// PreparerFunc is a method that implements the Preparer interface. -type PreparerFunc func(*http.Request) (*http.Request, error) - -// Prepare implements the Preparer interface on PreparerFunc. -func (pf PreparerFunc) Prepare(r *http.Request) (*http.Request, error) { - return pf(r) -} - -// PrepareDecorator takes and possibly decorates, by wrapping, a Preparer. Decorators may affect the -// http.Request and pass it along or, first, pass the http.Request along then affect the result. -type PrepareDecorator func(Preparer) Preparer - -// CreatePreparer creates, decorates, and returns a Preparer. -// Without decorators, the returned Preparer returns the passed http.Request unmodified. -// Preparers are safe to share and re-use. -func CreatePreparer(decorators ...PrepareDecorator) Preparer { - return DecoratePreparer( - Preparer(PreparerFunc(func(r *http.Request) (*http.Request, error) { return r, nil })), - decorators...) -} - -// DecoratePreparer accepts a Preparer and a, possibly empty, set of PrepareDecorators, which it -// applies to the Preparer. Decorators are applied in the order received, but their affect upon the -// request depends on whether they are a pre-decorator (change the http.Request and then pass it -// along) or a post-decorator (pass the http.Request along and alter it on return). -func DecoratePreparer(p Preparer, decorators ...PrepareDecorator) Preparer { - for _, decorate := range decorators { - p = decorate(p) - } - return p -} - -// Prepare accepts an http.Request and a, possibly empty, set of PrepareDecorators. -// It creates a Preparer from the decorators which it then applies to the passed http.Request. -func Prepare(r *http.Request, decorators ...PrepareDecorator) (*http.Request, error) { - if r == nil { - return nil, NewError("autorest", "Prepare", "Invoked without an http.Request") - } - return CreatePreparer(decorators...).Prepare(r) -} - -// WithNothing returns a "do nothing" PrepareDecorator that makes no changes to the passed -// http.Request. -func WithNothing() PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - return p.Prepare(r) - }) - } -} - -// WithHeader returns a PrepareDecorator that sets the specified HTTP header of the http.Request to -// the passed value. It canonicalizes the passed header name (via http.CanonicalHeaderKey) before -// adding the header. -func WithHeader(header string, value string) PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err == nil { - setHeader(r, http.CanonicalHeaderKey(header), value) - } - return r, err - }) - } -} - -// WithHeaders returns a PrepareDecorator that sets the specified HTTP headers of the http.Request to -// the passed value. It canonicalizes the passed headers name (via http.CanonicalHeaderKey) before -// adding them. -func WithHeaders(headers map[string]interface{}) PrepareDecorator { - h := ensureValueStrings(headers) - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err == nil { - if r.Header == nil { - r.Header = make(http.Header) - } - - for name, value := range h { - r.Header.Set(http.CanonicalHeaderKey(name), value) - } - } - return r, err - }) - } -} - -// WithBearerAuthorization returns a PrepareDecorator that adds an HTTP Authorization header whose -// value is "Bearer " followed by the supplied token. -func WithBearerAuthorization(token string) PrepareDecorator { - return WithHeader(headerAuthorization, fmt.Sprintf("Bearer %s", token)) -} - -// AsContentType returns a PrepareDecorator that adds an HTTP Content-Type header whose value -// is the passed contentType. -func AsContentType(contentType string) PrepareDecorator { - return WithHeader(headerContentType, contentType) -} - -// WithUserAgent returns a PrepareDecorator that adds an HTTP User-Agent header whose value is the -// passed string. -func WithUserAgent(ua string) PrepareDecorator { - return WithHeader(headerUserAgent, ua) -} - -// AsFormURLEncoded returns a PrepareDecorator that adds an HTTP Content-Type header whose value is -// "application/x-www-form-urlencoded". -func AsFormURLEncoded() PrepareDecorator { - return AsContentType(mimeTypeFormPost) -} - -// AsJSON returns a PrepareDecorator that adds an HTTP Content-Type header whose value is -// "application/json". -func AsJSON() PrepareDecorator { - return AsContentType(mimeTypeJSON) -} - -// AsOctetStream returns a PrepareDecorator that adds the "application/octet-stream" Content-Type header. -func AsOctetStream() PrepareDecorator { - return AsContentType(mimeTypeOctetStream) -} - -// WithMethod returns a PrepareDecorator that sets the HTTP method of the passed request. The -// decorator does not validate that the passed method string is a known HTTP method. -func WithMethod(method string) PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r.Method = method - return p.Prepare(r) - }) - } -} - -// AsDelete returns a PrepareDecorator that sets the HTTP method to DELETE. -func AsDelete() PrepareDecorator { return WithMethod("DELETE") } - -// AsGet returns a PrepareDecorator that sets the HTTP method to GET. -func AsGet() PrepareDecorator { return WithMethod("GET") } - -// AsHead returns a PrepareDecorator that sets the HTTP method to HEAD. -func AsHead() PrepareDecorator { return WithMethod("HEAD") } - -// AsMerge returns a PrepareDecorator that sets the HTTP method to MERGE. -func AsMerge() PrepareDecorator { return WithMethod("MERGE") } - -// AsOptions returns a PrepareDecorator that sets the HTTP method to OPTIONS. -func AsOptions() PrepareDecorator { return WithMethod("OPTIONS") } - -// AsPatch returns a PrepareDecorator that sets the HTTP method to PATCH. -func AsPatch() PrepareDecorator { return WithMethod("PATCH") } - -// AsPost returns a PrepareDecorator that sets the HTTP method to POST. -func AsPost() PrepareDecorator { return WithMethod("POST") } - -// AsPut returns a PrepareDecorator that sets the HTTP method to PUT. -func AsPut() PrepareDecorator { return WithMethod("PUT") } - -// WithBaseURL returns a PrepareDecorator that populates the http.Request with a url.URL constructed -// from the supplied baseUrl. Query parameters will be encoded as required. -func WithBaseURL(baseURL string) PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err == nil { - var u *url.URL - if u, err = url.Parse(baseURL); err != nil { - return r, err - } - if u.Scheme == "" { - return r, fmt.Errorf("autorest: No scheme detected in URL %s", baseURL) - } - if u.RawQuery != "" { - // handle unencoded semicolons (ideally the server would send them already encoded) - u.RawQuery = strings.Replace(u.RawQuery, ";", "%3B", -1) - q, err := url.ParseQuery(u.RawQuery) - if err != nil { - return r, err - } - u.RawQuery = q.Encode() - } - r.URL = u - } - return r, err - }) - } -} - -// WithBytes returns a PrepareDecorator that takes a list of bytes -// which passes the bytes directly to the body -func WithBytes(input *[]byte) PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err == nil { - if input == nil { - return r, fmt.Errorf("Input Bytes was nil") - } - - r.ContentLength = int64(len(*input)) - r.Body = io.NopCloser(bytes.NewReader(*input)) - } - return r, err - }) - } -} - -// WithCustomBaseURL returns a PrepareDecorator that replaces brace-enclosed keys within the -// request base URL (i.e., http.Request.URL) with the corresponding values from the passed map. -func WithCustomBaseURL(baseURL string, urlParameters map[string]interface{}) PrepareDecorator { - parameters := ensureValueStrings(urlParameters) - for key, value := range parameters { - baseURL = strings.Replace(baseURL, "{"+key+"}", value, -1) - } - return WithBaseURL(baseURL) -} - -// WithFormData returns a PrepareDecoratore that "URL encodes" (e.g., bar=baz&foo=quux) into the -// http.Request body. -func WithFormData(v url.Values) PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err == nil { - s := v.Encode() - - setHeader(r, http.CanonicalHeaderKey(headerContentType), mimeTypeFormPost) - r.ContentLength = int64(len(s)) - r.Body = io.NopCloser(strings.NewReader(s)) - } - return r, err - }) - } -} - -// WithMultiPartFormData returns a PrepareDecoratore that "URL encodes" (e.g., bar=baz&foo=quux) form parameters -// into the http.Request body. -func WithMultiPartFormData(formDataParameters map[string]interface{}) PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err == nil { - var body bytes.Buffer - writer := multipart.NewWriter(&body) - for key, value := range formDataParameters { - if rc, ok := value.(io.ReadCloser); ok { - var fd io.Writer - if fd, err = writer.CreateFormFile(key, key); err != nil { - return r, err - } - if _, err = io.Copy(fd, rc); err != nil { - return r, err - } - } else { - if err = writer.WriteField(key, ensureValueString(value)); err != nil { - return r, err - } - } - } - if err = writer.Close(); err != nil { - return r, err - } - setHeader(r, http.CanonicalHeaderKey(headerContentType), writer.FormDataContentType()) - r.Body = io.NopCloser(bytes.NewReader(body.Bytes())) - r.ContentLength = int64(body.Len()) - return r, err - } - return r, err - }) - } -} - -// WithFile returns a PrepareDecorator that sends file in request body. -func WithFile(f io.ReadCloser) PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err == nil { - b, err := io.ReadAll(f) - if err != nil { - return r, err - } - r.Body = io.NopCloser(bytes.NewReader(b)) - r.ContentLength = int64(len(b)) - } - return r, err - }) - } -} - -// WithBool returns a PrepareDecorator that encodes the passed bool into the body of the request -// and sets the Content-Length header. -func WithBool(v bool) PrepareDecorator { - return WithString(fmt.Sprintf("%v", v)) -} - -// WithFloat32 returns a PrepareDecorator that encodes the passed float32 into the body of the -// request and sets the Content-Length header. -func WithFloat32(v float32) PrepareDecorator { - return WithString(fmt.Sprintf("%v", v)) -} - -// WithFloat64 returns a PrepareDecorator that encodes the passed float64 into the body of the -// request and sets the Content-Length header. -func WithFloat64(v float64) PrepareDecorator { - return WithString(fmt.Sprintf("%v", v)) -} - -// WithInt32 returns a PrepareDecorator that encodes the passed int32 into the body of the request -// and sets the Content-Length header. -func WithInt32(v int32) PrepareDecorator { - return WithString(fmt.Sprintf("%v", v)) -} - -// WithInt64 returns a PrepareDecorator that encodes the passed int64 into the body of the request -// and sets the Content-Length header. -func WithInt64(v int64) PrepareDecorator { - return WithString(fmt.Sprintf("%v", v)) -} - -// WithString returns a PrepareDecorator that encodes the passed string into the body of the request -// and sets the Content-Length header. -func WithString(v string) PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err == nil { - r.ContentLength = int64(len(v)) - r.Body = io.NopCloser(strings.NewReader(v)) - } - return r, err - }) - } -} - -// WithJSON returns a PrepareDecorator that encodes the data passed as JSON into the body of the -// request and sets the Content-Length header. -func WithJSON(v interface{}) PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err == nil { - b, err := json.Marshal(v) - if err == nil { - r.ContentLength = int64(len(b)) - r.Body = io.NopCloser(bytes.NewReader(b)) - } - } - return r, err - }) - } -} - -// WithXML returns a PrepareDecorator that encodes the data passed as XML into the body of the -// request and sets the Content-Length header. -func WithXML(v interface{}) PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err == nil { - b, err := xml.Marshal(v) - if err == nil { - // we have to tack on an XML header - withHeader := xml.Header + string(b) - bytesWithHeader := []byte(withHeader) - - r.ContentLength = int64(len(bytesWithHeader)) - setHeader(r, headerContentLength, fmt.Sprintf("%d", len(bytesWithHeader))) - r.Body = io.NopCloser(bytes.NewReader(bytesWithHeader)) - } - } - return r, err - }) - } -} - -// WithPath returns a PrepareDecorator that adds the supplied path to the request URL. If the path -// is absolute (that is, it begins with a "/"), it replaces the existing path. -func WithPath(path string) PrepareDecorator { - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err == nil { - if r.URL == nil { - return r, NewError("autorest", "WithPath", "Invoked with a nil URL") - } - if r.URL, err = parseURL(r.URL, path); err != nil { - return r, err - } - } - return r, err - }) - } -} - -// WithEscapedPathParameters returns a PrepareDecorator that replaces brace-enclosed keys within the -// request path (i.e., http.Request.URL.Path) with the corresponding values from the passed map. The -// values will be escaped (aka URL encoded) before insertion into the path. -func WithEscapedPathParameters(path string, pathParameters map[string]interface{}) PrepareDecorator { - parameters := escapeValueStrings(ensureValueStrings(pathParameters)) - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err == nil { - if r.URL == nil { - return r, NewError("autorest", "WithEscapedPathParameters", "Invoked with a nil URL") - } - for key, value := range parameters { - path = strings.Replace(path, "{"+key+"}", value, -1) - } - if r.URL, err = parseURL(r.URL, path); err != nil { - return r, err - } - } - return r, err - }) - } -} - -// WithPathParameters returns a PrepareDecorator that replaces brace-enclosed keys within the -// request path (i.e., http.Request.URL.Path) with the corresponding values from the passed map. -func WithPathParameters(path string, pathParameters map[string]interface{}) PrepareDecorator { - parameters := ensureValueStrings(pathParameters) - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err == nil { - if r.URL == nil { - return r, NewError("autorest", "WithPathParameters", "Invoked with a nil URL") - } - for key, value := range parameters { - path = strings.Replace(path, "{"+key+"}", value, -1) - } - - if r.URL, err = parseURL(r.URL, path); err != nil { - return r, err - } - } - return r, err - }) - } -} - -func parseURL(u *url.URL, path string) (*url.URL, error) { - p := strings.TrimRight(u.String(), "/") - if !strings.HasPrefix(path, "/") { - path = "/" + path - } - return url.Parse(p + path) -} - -// WithQueryParameters returns a PrepareDecorators that encodes and applies the query parameters -// given in the supplied map (i.e., key=value). -func WithQueryParameters(queryParameters map[string]interface{}) PrepareDecorator { - parameters := MapToValues(queryParameters) - return func(p Preparer) Preparer { - return PreparerFunc(func(r *http.Request) (*http.Request, error) { - r, err := p.Prepare(r) - if err == nil { - if r.URL == nil { - return r, NewError("autorest", "WithQueryParameters", "Invoked with a nil URL") - } - v := r.URL.Query() - for key, value := range parameters { - for i := range value { - d, err := url.QueryUnescape(value[i]) - if err != nil { - return r, err - } - value[i] = d - } - v[key] = value - } - r.URL.RawQuery = v.Encode() - } - return r, err - }) - } -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/responder.go b/vendor/github.com/Azure/go-autorest/autorest/responder.go deleted file mode 100644 index 69d4b2b6..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/responder.go +++ /dev/null @@ -1,268 +0,0 @@ -package autorest - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import ( - "bytes" - "encoding/json" - "encoding/xml" - "fmt" - "io" - "net/http" - "strings" -) - -// Responder is the interface that wraps the Respond method. -// -// Respond accepts and reacts to an http.Response. Implementations must ensure to not share or hold -// state since Responders may be shared and re-used. -type Responder interface { - Respond(*http.Response) error -} - -// ResponderFunc is a method that implements the Responder interface. -type ResponderFunc func(*http.Response) error - -// Respond implements the Responder interface on ResponderFunc. -func (rf ResponderFunc) Respond(r *http.Response) error { - return rf(r) -} - -// RespondDecorator takes and possibly decorates, by wrapping, a Responder. Decorators may react to -// the http.Response and pass it along or, first, pass the http.Response along then react. -type RespondDecorator func(Responder) Responder - -// CreateResponder creates, decorates, and returns a Responder. Without decorators, the returned -// Responder returns the passed http.Response unmodified. Responders may or may not be safe to share -// and re-used: It depends on the applied decorators. For example, a standard decorator that closes -// the response body is fine to share whereas a decorator that reads the body into a passed struct -// is not. -// -// To prevent memory leaks, ensure that at least one Responder closes the response body. -func CreateResponder(decorators ...RespondDecorator) Responder { - return DecorateResponder( - Responder(ResponderFunc(func(r *http.Response) error { return nil })), - decorators...) -} - -// DecorateResponder accepts a Responder and a, possibly empty, set of RespondDecorators, which it -// applies to the Responder. Decorators are applied in the order received, but their affect upon the -// request depends on whether they are a pre-decorator (react to the http.Response and then pass it -// along) or a post-decorator (pass the http.Response along and then react). -func DecorateResponder(r Responder, decorators ...RespondDecorator) Responder { - for _, decorate := range decorators { - r = decorate(r) - } - return r -} - -// Respond accepts an http.Response and a, possibly empty, set of RespondDecorators. -// It creates a Responder from the decorators it then applies to the passed http.Response. -func Respond(r *http.Response, decorators ...RespondDecorator) error { - if r == nil { - return nil - } - return CreateResponder(decorators...).Respond(r) -} - -// ByIgnoring returns a RespondDecorator that ignores the passed http.Response passing it unexamined -// to the next RespondDecorator. -func ByIgnoring() RespondDecorator { - return func(r Responder) Responder { - return ResponderFunc(func(resp *http.Response) error { - return r.Respond(resp) - }) - } -} - -// ByCopying copies the contents of the http.Response Body into the passed bytes.Buffer as -// the Body is read. -func ByCopying(b *bytes.Buffer) RespondDecorator { - return func(r Responder) Responder { - return ResponderFunc(func(resp *http.Response) error { - err := r.Respond(resp) - if err == nil && resp != nil && resp.Body != nil { - resp.Body = TeeReadCloser(resp.Body, b) - } - return err - }) - } -} - -// ByDiscardingBody returns a RespondDecorator that first invokes the passed Responder after which -// it copies the remaining bytes (if any) in the response body to ioutil.Discard. Since the passed -// Responder is invoked prior to discarding the response body, the decorator may occur anywhere -// within the set. -func ByDiscardingBody() RespondDecorator { - return func(r Responder) Responder { - return ResponderFunc(func(resp *http.Response) error { - err := r.Respond(resp) - if err == nil && resp != nil && resp.Body != nil { - if _, err := io.Copy(io.Discard, resp.Body); err != nil { - return fmt.Errorf("Error discarding the response body: %v", err) - } - } - return err - }) - } -} - -// ByClosing returns a RespondDecorator that first invokes the passed Responder after which it -// closes the response body. Since the passed Responder is invoked prior to closing the response -// body, the decorator may occur anywhere within the set. -func ByClosing() RespondDecorator { - return func(r Responder) Responder { - return ResponderFunc(func(resp *http.Response) error { - err := r.Respond(resp) - if resp != nil && resp.Body != nil { - if err := resp.Body.Close(); err != nil { - return fmt.Errorf("Error closing the response body: %v", err) - } - } - return err - }) - } -} - -// ByClosingIfError returns a RespondDecorator that first invokes the passed Responder after which -// it closes the response if the passed Responder returns an error and the response body exists. -func ByClosingIfError() RespondDecorator { - return func(r Responder) Responder { - return ResponderFunc(func(resp *http.Response) error { - err := r.Respond(resp) - if err != nil && resp != nil && resp.Body != nil { - if err := resp.Body.Close(); err != nil { - return fmt.Errorf("Error closing the response body: %v", err) - } - } - return err - }) - } -} - -// ByUnmarshallingBytes returns a RespondDecorator that copies the Bytes returned in the -// response Body into the value pointed to by v. -func ByUnmarshallingBytes(v *[]byte) RespondDecorator { - return func(r Responder) Responder { - return ResponderFunc(func(resp *http.Response) error { - err := r.Respond(resp) - if err == nil { - bytes, errInner := io.ReadAll(resp.Body) - if errInner != nil { - err = fmt.Errorf("Error occurred reading http.Response#Body - Error = '%v'", errInner) - } else { - *v = bytes - } - } - return err - }) - } -} - -// ByUnmarshallingJSON returns a RespondDecorator that decodes a JSON document returned in the -// response Body into the value pointed to by v. -func ByUnmarshallingJSON(v interface{}) RespondDecorator { - return func(r Responder) Responder { - return ResponderFunc(func(resp *http.Response) error { - err := r.Respond(resp) - if err == nil { - b, errInner := io.ReadAll(resp.Body) - // Some responses might include a BOM, remove for successful unmarshalling - b = bytes.TrimPrefix(b, []byte("\xef\xbb\xbf")) - if errInner != nil { - err = fmt.Errorf("Error occurred reading http.Response#Body - Error = '%v'", errInner) - } else if len(strings.Trim(string(b), " ")) > 0 { - errInner = json.Unmarshal(b, v) - if errInner != nil { - err = fmt.Errorf("Error occurred unmarshalling JSON - Error = '%v' JSON = '%s'", errInner, string(b)) - } - } - } - return err - }) - } -} - -// ByUnmarshallingXML returns a RespondDecorator that decodes a XML document returned in the -// response Body into the value pointed to by v. -func ByUnmarshallingXML(v interface{}) RespondDecorator { - return func(r Responder) Responder { - return ResponderFunc(func(resp *http.Response) error { - err := r.Respond(resp) - if err == nil { - b, errInner := io.ReadAll(resp.Body) - if errInner != nil { - err = fmt.Errorf("Error occurred reading http.Response#Body - Error = '%v'", errInner) - } else { - errInner = xml.Unmarshal(b, v) - if errInner != nil { - err = fmt.Errorf("Error occurred unmarshalling Xml - Error = '%v' Xml = '%s'", errInner, string(b)) - } - } - } - return err - }) - } -} - -// WithErrorUnlessStatusCode returns a RespondDecorator that emits an error unless the response -// StatusCode is among the set passed. On error, response body is fully read into a buffer and -// presented in the returned error, as well as in the response body. -func WithErrorUnlessStatusCode(codes ...int) RespondDecorator { - return func(r Responder) Responder { - return ResponderFunc(func(resp *http.Response) error { - err := r.Respond(resp) - if err == nil && !ResponseHasStatusCode(resp, codes...) { - derr := NewErrorWithResponse("autorest", "WithErrorUnlessStatusCode", resp, "%v %v failed with %s", - resp.Request.Method, - resp.Request.URL, - resp.Status) - if resp.Body != nil { - defer resp.Body.Close() - b, _ := io.ReadAll(resp.Body) - derr.ServiceError = b - resp.Body = io.NopCloser(bytes.NewReader(b)) - } - err = derr - } - return err - }) - } -} - -// WithErrorUnlessOK returns a RespondDecorator that emits an error if the response StatusCode is -// anything other than HTTP 200. -func WithErrorUnlessOK() RespondDecorator { - return WithErrorUnlessStatusCode(http.StatusOK) -} - -// ExtractHeader extracts all values of the specified header from the http.Response. It returns an -// empty string slice if the passed http.Response is nil or the header does not exist. -func ExtractHeader(header string, resp *http.Response) []string { - if resp != nil && resp.Header != nil { - return resp.Header[http.CanonicalHeaderKey(header)] - } - return nil -} - -// ExtractHeaderValue extracts the first value of the specified header from the http.Response. It -// returns an empty string if the passed http.Response is nil or the header does not exist. -func ExtractHeaderValue(header string, resp *http.Response) string { - h := ExtractHeader(header, resp) - if len(h) > 0 { - return h[0] - } - return "" -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/retriablerequest.go b/vendor/github.com/Azure/go-autorest/autorest/retriablerequest.go deleted file mode 100644 index 7634b0f5..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/retriablerequest.go +++ /dev/null @@ -1,51 +0,0 @@ -package autorest - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import ( - "bytes" - "io" - "net/http" -) - -// NewRetriableRequest returns a wrapper around an HTTP request that support retry logic. -func NewRetriableRequest(req *http.Request) *RetriableRequest { - return &RetriableRequest{req: req} -} - -// Request returns the wrapped HTTP request. -func (rr *RetriableRequest) Request() *http.Request { - return rr.req -} - -func (rr *RetriableRequest) prepareFromByteReader() (err error) { - // fall back to making a copy (only do this once) - b := []byte{} - if rr.req.ContentLength > 0 { - b = make([]byte, rr.req.ContentLength) - _, err = io.ReadFull(rr.req.Body, b) - if err != nil { - return err - } - } else { - b, err = io.ReadAll(rr.req.Body) - if err != nil { - return err - } - } - rr.br = bytes.NewReader(b) - rr.req.Body = io.NopCloser(rr.br) - return err -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.7.go b/vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.7.go deleted file mode 100644 index 8340bda4..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.7.go +++ /dev/null @@ -1,55 +0,0 @@ -//go:build !go1.8 -// +build !go1.8 - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package autorest - -import ( - "bytes" - "io" - "net/http" -) - -// RetriableRequest provides facilities for retrying an HTTP request. -type RetriableRequest struct { - req *http.Request - br *bytes.Reader -} - -// Prepare signals that the request is about to be sent. -func (rr *RetriableRequest) Prepare() (err error) { - // preserve the request body; this is to support retry logic as - // the underlying transport will always close the reqeust body - if rr.req.Body != nil && rr.req.Body != http.NoBody { - if rr.br != nil { - _, err = rr.br.Seek(0, 0 /*io.SeekStart*/) - rr.req.Body = io.NopCloser(rr.br) - } - if err != nil { - return err - } - if rr.br == nil { - // fall back to making a copy (only do this once) - err = rr.prepareFromByteReader() - } - } - return err -} - -func removeRequestBody(req *http.Request) { - req.Body = nil - req.ContentLength = 0 -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.8.go b/vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.8.go deleted file mode 100644 index e36d4b04..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.8.go +++ /dev/null @@ -1,66 +0,0 @@ -//go:build go1.8 -// +build go1.8 - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package autorest - -import ( - "bytes" - "io" - "net/http" -) - -// RetriableRequest provides facilities for retrying an HTTP request. -type RetriableRequest struct { - req *http.Request - rc io.ReadCloser - br *bytes.Reader -} - -// Prepare signals that the request is about to be sent. -func (rr *RetriableRequest) Prepare() (err error) { - // preserve the request body; this is to support retry logic as - // the underlying transport will always close the reqeust body - if rr.req.Body != nil && rr.req.Body != http.NoBody { - if rr.rc != nil { - rr.req.Body = rr.rc - } else if rr.br != nil { - _, err = rr.br.Seek(0, io.SeekStart) - rr.req.Body = io.NopCloser(rr.br) - } - if err != nil { - return err - } - if rr.req.GetBody != nil { - // this will allow us to preserve the body without having to - // make a copy. note we need to do this on each iteration - rr.rc, err = rr.req.GetBody() - if err != nil { - return err - } - } else if rr.br == nil { - // fall back to making a copy (only do this once) - err = rr.prepareFromByteReader() - } - } - return err -} - -func removeRequestBody(req *http.Request) { - req.Body = nil - req.GetBody = nil - req.ContentLength = 0 -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/sender.go b/vendor/github.com/Azure/go-autorest/autorest/sender.go deleted file mode 100644 index 118de814..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/sender.go +++ /dev/null @@ -1,458 +0,0 @@ -package autorest - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import ( - "context" - "crypto/tls" - "fmt" - "log" - "math" - "net" - "net/http" - "net/http/cookiejar" - "strconv" - "sync" - "time" - - "github.com/Azure/go-autorest/logger" - "github.com/Azure/go-autorest/tracing" -) - -// there is one sender per TLS renegotiation type, i.e. count of tls.RenegotiationSupport enums -const defaultSendersCount = 3 - -type defaultSender struct { - sender Sender - init *sync.Once -} - -// each type of sender will be created on demand in sender() -var defaultSenders [defaultSendersCount]defaultSender - -func init() { - for i := 0; i < defaultSendersCount; i++ { - defaultSenders[i].init = &sync.Once{} - } -} - -// used as a key type in context.WithValue() -type ctxSendDecorators struct{} - -// WithSendDecorators adds the specified SendDecorators to the provided context. -// If no SendDecorators are provided the context is unchanged. -func WithSendDecorators(ctx context.Context, sendDecorator []SendDecorator) context.Context { - if len(sendDecorator) == 0 { - return ctx - } - return context.WithValue(ctx, ctxSendDecorators{}, sendDecorator) -} - -// GetSendDecorators returns the SendDecorators in the provided context or the provided default SendDecorators. -func GetSendDecorators(ctx context.Context, defaultSendDecorators ...SendDecorator) []SendDecorator { - inCtx := ctx.Value(ctxSendDecorators{}) - if sd, ok := inCtx.([]SendDecorator); ok { - return sd - } - return defaultSendDecorators -} - -// Sender is the interface that wraps the Do method to send HTTP requests. -// -// The standard http.Client conforms to this interface. -type Sender interface { - Do(*http.Request) (*http.Response, error) -} - -// SenderFunc is a method that implements the Sender interface. -type SenderFunc func(*http.Request) (*http.Response, error) - -// Do implements the Sender interface on SenderFunc. -func (sf SenderFunc) Do(r *http.Request) (*http.Response, error) { - return sf(r) -} - -// SendDecorator takes and possibly decorates, by wrapping, a Sender. Decorators may affect the -// http.Request and pass it along or, first, pass the http.Request along then react to the -// http.Response result. -type SendDecorator func(Sender) Sender - -// CreateSender creates, decorates, and returns, as a Sender, the default http.Client. -func CreateSender(decorators ...SendDecorator) Sender { - return DecorateSender(sender(tls.RenegotiateNever), decorators...) -} - -// DecorateSender accepts a Sender and a, possibly empty, set of SendDecorators, which is applies to -// the Sender. Decorators are applied in the order received, but their affect upon the request -// depends on whether they are a pre-decorator (change the http.Request and then pass it along) or a -// post-decorator (pass the http.Request along and react to the results in http.Response). -func DecorateSender(s Sender, decorators ...SendDecorator) Sender { - for _, decorate := range decorators { - s = decorate(s) - } - return s -} - -// Send sends, by means of the default http.Client, the passed http.Request, returning the -// http.Response and possible error. It also accepts a, possibly empty, set of SendDecorators which -// it will apply the http.Client before invoking the Do method. -// -// Send is a convenience method and not recommended for production. Advanced users should use -// SendWithSender, passing and sharing their own Sender (e.g., instance of http.Client). -// -// Send will not poll or retry requests. -func Send(r *http.Request, decorators ...SendDecorator) (*http.Response, error) { - return SendWithSender(sender(tls.RenegotiateNever), r, decorators...) -} - -// SendWithSender sends the passed http.Request, through the provided Sender, returning the -// http.Response and possible error. It also accepts a, possibly empty, set of SendDecorators which -// it will apply the http.Client before invoking the Do method. -// -// SendWithSender will not poll or retry requests. -func SendWithSender(s Sender, r *http.Request, decorators ...SendDecorator) (*http.Response, error) { - return DecorateSender(s, decorators...).Do(r) -} - -func sender(renengotiation tls.RenegotiationSupport) Sender { - // note that we can't init defaultSenders in init() since it will - // execute before calling code has had a chance to enable tracing - defaultSenders[renengotiation].init.Do(func() { - // copied from http.DefaultTransport with a TLS minimum version. - transport := &http.Transport{ - Proxy: http.ProxyFromEnvironment, - DialContext: (&net.Dialer{ - Timeout: 30 * time.Second, - KeepAlive: 30 * time.Second, - }).DialContext, - ForceAttemptHTTP2: true, - MaxIdleConns: 100, - IdleConnTimeout: 90 * time.Second, - TLSHandshakeTimeout: 10 * time.Second, - ExpectContinueTimeout: 1 * time.Second, - TLSClientConfig: &tls.Config{ - MinVersion: tls.VersionTLS12, - Renegotiation: renengotiation, - }, - } - var roundTripper http.RoundTripper = transport - if tracing.IsEnabled() { - roundTripper = tracing.NewTransport(transport) - } - j, _ := cookiejar.New(nil) - defaultSenders[renengotiation].sender = &http.Client{Jar: j, Transport: roundTripper} - }) - return defaultSenders[renengotiation].sender -} - -// AfterDelay returns a SendDecorator that delays for the passed time.Duration before -// invoking the Sender. The delay may be terminated by closing the optional channel on the -// http.Request. If canceled, no further Senders are invoked. -func AfterDelay(d time.Duration) SendDecorator { - return func(s Sender) Sender { - return SenderFunc(func(r *http.Request) (*http.Response, error) { - if !DelayForBackoff(d, 0, r.Context().Done()) { - return nil, fmt.Errorf("autorest: AfterDelay canceled before full delay") - } - return s.Do(r) - }) - } -} - -// AsIs returns a SendDecorator that invokes the passed Sender without modifying the http.Request. -func AsIs() SendDecorator { - return func(s Sender) Sender { - return SenderFunc(func(r *http.Request) (*http.Response, error) { - return s.Do(r) - }) - } -} - -// DoCloseIfError returns a SendDecorator that first invokes the passed Sender after which -// it closes the response if the passed Sender returns an error and the response body exists. -func DoCloseIfError() SendDecorator { - return func(s Sender) Sender { - return SenderFunc(func(r *http.Request) (*http.Response, error) { - resp, err := s.Do(r) - if err != nil { - Respond(resp, ByDiscardingBody(), ByClosing()) - } - return resp, err - }) - } -} - -// DoErrorIfStatusCode returns a SendDecorator that emits an error if the response StatusCode is -// among the set passed. Since these are artificial errors, the response body may still require -// closing. -func DoErrorIfStatusCode(codes ...int) SendDecorator { - return func(s Sender) Sender { - return SenderFunc(func(r *http.Request) (*http.Response, error) { - resp, err := s.Do(r) - if err == nil && ResponseHasStatusCode(resp, codes...) { - err = NewErrorWithResponse("autorest", "DoErrorIfStatusCode", resp, "%v %v failed with %s", - resp.Request.Method, - resp.Request.URL, - resp.Status) - } - return resp, err - }) - } -} - -// DoErrorUnlessStatusCode returns a SendDecorator that emits an error unless the response -// StatusCode is among the set passed. Since these are artificial errors, the response body -// may still require closing. -func DoErrorUnlessStatusCode(codes ...int) SendDecorator { - return func(s Sender) Sender { - return SenderFunc(func(r *http.Request) (*http.Response, error) { - resp, err := s.Do(r) - if err == nil && !ResponseHasStatusCode(resp, codes...) { - err = NewErrorWithResponse("autorest", "DoErrorUnlessStatusCode", resp, "%v %v failed with %s", - resp.Request.Method, - resp.Request.URL, - resp.Status) - } - return resp, err - }) - } -} - -// DoPollForStatusCodes returns a SendDecorator that polls if the http.Response contains one of the -// passed status codes. It expects the http.Response to contain a Location header providing the -// URL at which to poll (using GET) and will poll until the time passed is equal to or greater than -// the supplied duration. It will delay between requests for the duration specified in the -// RetryAfter header or, if the header is absent, the passed delay. Polling may be canceled by -// closing the optional channel on the http.Request. -func DoPollForStatusCodes(duration time.Duration, delay time.Duration, codes ...int) SendDecorator { - return func(s Sender) Sender { - return SenderFunc(func(r *http.Request) (resp *http.Response, err error) { - resp, err = s.Do(r) - - if err == nil && ResponseHasStatusCode(resp, codes...) { - r, err = NewPollingRequestWithContext(r.Context(), resp) - - for err == nil && ResponseHasStatusCode(resp, codes...) { - Respond(resp, - ByDiscardingBody(), - ByClosing()) - resp, err = SendWithSender(s, r, - AfterDelay(GetRetryAfter(resp, delay))) - } - } - - return resp, err - }) - } -} - -// DoRetryForAttempts returns a SendDecorator that retries a failed request for up to the specified -// number of attempts, exponentially backing off between requests using the supplied backoff -// time.Duration (which may be zero). Retrying may be canceled by closing the optional channel on -// the http.Request. -func DoRetryForAttempts(attempts int, backoff time.Duration) SendDecorator { - return func(s Sender) Sender { - return SenderFunc(func(r *http.Request) (resp *http.Response, err error) { - rr := NewRetriableRequest(r) - for attempt := 0; attempt < attempts; attempt++ { - err = rr.Prepare() - if err != nil { - return resp, err - } - DrainResponseBody(resp) - resp, err = s.Do(rr.Request()) - if err == nil { - return resp, err - } - logger.Instance.Writef(logger.LogError, "DoRetryForAttempts: received error for attempt %d: %v\n", attempt+1, err) - if !DelayForBackoff(backoff, attempt, r.Context().Done()) { - return nil, r.Context().Err() - } - } - return resp, err - }) - } -} - -// Count429AsRetry indicates that a 429 response should be included as a retry attempt. -var Count429AsRetry = true - -// Max429Delay is the maximum duration to wait between retries on a 429 if no Retry-After header was received. -var Max429Delay time.Duration - -// DoRetryForStatusCodes returns a SendDecorator that retries for specified statusCodes for up to the specified -// number of attempts, exponentially backing off between requests using the supplied backoff -// time.Duration (which may be zero). Retrying may be canceled by cancelling the context on the http.Request. -// NOTE: Code http.StatusTooManyRequests (429) will *not* be counted against the number of attempts. -func DoRetryForStatusCodes(attempts int, backoff time.Duration, codes ...int) SendDecorator { - return func(s Sender) Sender { - return SenderFunc(func(r *http.Request) (*http.Response, error) { - return doRetryForStatusCodesImpl(s, r, Count429AsRetry, attempts, backoff, 0, codes...) - }) - } -} - -// DoRetryForStatusCodesWithCap returns a SendDecorator that retries for specified statusCodes for up to the -// specified number of attempts, exponentially backing off between requests using the supplied backoff -// time.Duration (which may be zero). To cap the maximum possible delay between iterations specify a value greater -// than zero for cap. Retrying may be canceled by cancelling the context on the http.Request. -func DoRetryForStatusCodesWithCap(attempts int, backoff, cap time.Duration, codes ...int) SendDecorator { - return func(s Sender) Sender { - return SenderFunc(func(r *http.Request) (*http.Response, error) { - return doRetryForStatusCodesImpl(s, r, Count429AsRetry, attempts, backoff, cap, codes...) - }) - } -} - -func doRetryForStatusCodesImpl(s Sender, r *http.Request, count429 bool, attempts int, backoff, cap time.Duration, codes ...int) (resp *http.Response, err error) { - rr := NewRetriableRequest(r) - // Increment to add the first call (attempts denotes number of retries) - for attempt, delayCount := 0, 0; attempt < attempts+1; { - err = rr.Prepare() - if err != nil { - return - } - DrainResponseBody(resp) - resp, err = s.Do(rr.Request()) - // we want to retry if err is not nil (e.g. transient network failure). note that for failed authentication - // resp and err will both have a value, so in this case we don't want to retry as it will never succeed. - if err == nil && !ResponseHasStatusCode(resp, codes...) || IsTokenRefreshError(err) { - return resp, err - } - if err != nil { - logger.Instance.Writef(logger.LogError, "DoRetryForStatusCodes: received error for attempt %d: %v\n", attempt+1, err) - } - delayed := DelayWithRetryAfter(resp, r.Context().Done()) - // if this was a 429 set the delay cap as specified. - // applicable only in the absence of a retry-after header. - if resp != nil && resp.StatusCode == http.StatusTooManyRequests { - cap = Max429Delay - } - if !delayed && !DelayForBackoffWithCap(backoff, cap, delayCount, r.Context().Done()) { - return resp, r.Context().Err() - } - // when count429 == false don't count a 429 against the number - // of attempts so that we continue to retry until it succeeds - if count429 || (resp == nil || resp.StatusCode != http.StatusTooManyRequests) { - attempt++ - } - // delay count is tracked separately from attempts to - // ensure that 429 participates in exponential back-off - delayCount++ - } - return resp, err -} - -// DelayWithRetryAfter invokes time.After for the duration specified in the "Retry-After" header. -// The value of Retry-After can be either the number of seconds or a date in RFC1123 format. -// The function returns true after successfully waiting for the specified duration. If there is -// no Retry-After header or the wait is cancelled the return value is false. -func DelayWithRetryAfter(resp *http.Response, cancel <-chan struct{}) bool { - if resp == nil { - return false - } - var dur time.Duration - ra := resp.Header.Get("Retry-After") - if retryAfter, _ := strconv.Atoi(ra); retryAfter > 0 { - dur = time.Duration(retryAfter) * time.Second - } else if t, err := time.Parse(time.RFC1123, ra); err == nil { - dur = t.Sub(time.Now()) - } - if dur > 0 { - select { - case <-time.After(dur): - return true - case <-cancel: - return false - } - } - return false -} - -// DoRetryForDuration returns a SendDecorator that retries the request until the total time is equal -// to or greater than the specified duration, exponentially backing off between requests using the -// supplied backoff time.Duration (which may be zero). Retrying may be canceled by closing the -// optional channel on the http.Request. -func DoRetryForDuration(d time.Duration, backoff time.Duration) SendDecorator { - return func(s Sender) Sender { - return SenderFunc(func(r *http.Request) (resp *http.Response, err error) { - rr := NewRetriableRequest(r) - end := time.Now().Add(d) - for attempt := 0; time.Now().Before(end); attempt++ { - err = rr.Prepare() - if err != nil { - return resp, err - } - DrainResponseBody(resp) - resp, err = s.Do(rr.Request()) - if err == nil { - return resp, err - } - logger.Instance.Writef(logger.LogError, "DoRetryForDuration: received error for attempt %d: %v\n", attempt+1, err) - if !DelayForBackoff(backoff, attempt, r.Context().Done()) { - return nil, r.Context().Err() - } - } - return resp, err - }) - } -} - -// WithLogging returns a SendDecorator that implements simple before and after logging of the -// request. -func WithLogging(logger *log.Logger) SendDecorator { - return func(s Sender) Sender { - return SenderFunc(func(r *http.Request) (*http.Response, error) { - logger.Printf("Sending %s %s", r.Method, r.URL) - resp, err := s.Do(r) - if err != nil { - logger.Printf("%s %s received error '%v'", r.Method, r.URL, err) - } else { - logger.Printf("%s %s received %s", r.Method, r.URL, resp.Status) - } - return resp, err - }) - } -} - -// DelayForBackoff invokes time.After for the supplied backoff duration raised to the power of -// passed attempt (i.e., an exponential backoff delay). Backoff duration is in seconds and can set -// to zero for no delay. The delay may be canceled by closing the passed channel. If terminated early, -// returns false. -// Note: Passing attempt 1 will result in doubling "backoff" duration. Treat this as a zero-based attempt -// count. -func DelayForBackoff(backoff time.Duration, attempt int, cancel <-chan struct{}) bool { - return DelayForBackoffWithCap(backoff, 0, attempt, cancel) -} - -// DelayForBackoffWithCap invokes time.After for the supplied backoff duration raised to the power of -// passed attempt (i.e., an exponential backoff delay). Backoff duration is in seconds and can set -// to zero for no delay. To cap the maximum possible delay specify a value greater than zero for cap. -// The delay may be canceled by closing the passed channel. If terminated early, returns false. -// Note: Passing attempt 1 will result in doubling "backoff" duration. Treat this as a zero-based attempt -// count. -func DelayForBackoffWithCap(backoff, cap time.Duration, attempt int, cancel <-chan struct{}) bool { - d := time.Duration(backoff.Seconds()*math.Pow(2, float64(attempt))) * time.Second - if cap > 0 && d > cap { - d = cap - } - logger.Instance.Writef(logger.LogInfo, "DelayForBackoffWithCap: sleeping for %s\n", d) - select { - case <-time.After(d): - return true - case <-cancel: - return false - } -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/to/LICENSE b/vendor/github.com/Azure/go-autorest/autorest/to/LICENSE deleted file mode 100644 index b9d6a27e..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/to/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2015 Microsoft Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/Azure/go-autorest/autorest/to/convert.go b/vendor/github.com/Azure/go-autorest/autorest/to/convert.go deleted file mode 100644 index 86694bd2..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/to/convert.go +++ /dev/null @@ -1,152 +0,0 @@ -/* -Package to provides helpers to ease working with pointer values of marshalled structures. -*/ -package to - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// String returns a string value for the passed string pointer. It returns the empty string if the -// pointer is nil. -func String(s *string) string { - if s != nil { - return *s - } - return "" -} - -// StringPtr returns a pointer to the passed string. -func StringPtr(s string) *string { - return &s -} - -// StringSlice returns a string slice value for the passed string slice pointer. It returns a nil -// slice if the pointer is nil. -func StringSlice(s *[]string) []string { - if s != nil { - return *s - } - return nil -} - -// StringSlicePtr returns a pointer to the passed string slice. -func StringSlicePtr(s []string) *[]string { - return &s -} - -// StringMap returns a map of strings built from the map of string pointers. The empty string is -// used for nil pointers. -func StringMap(msp map[string]*string) map[string]string { - ms := make(map[string]string, len(msp)) - for k, sp := range msp { - if sp != nil { - ms[k] = *sp - } else { - ms[k] = "" - } - } - return ms -} - -// StringMapPtr returns a pointer to a map of string pointers built from the passed map of strings. -func StringMapPtr(ms map[string]string) *map[string]*string { - msp := make(map[string]*string, len(ms)) - for k, s := range ms { - msp[k] = StringPtr(s) - } - return &msp -} - -// Bool returns a bool value for the passed bool pointer. It returns false if the pointer is nil. -func Bool(b *bool) bool { - if b != nil { - return *b - } - return false -} - -// BoolPtr returns a pointer to the passed bool. -func BoolPtr(b bool) *bool { - return &b -} - -// Int returns an int value for the passed int pointer. It returns 0 if the pointer is nil. -func Int(i *int) int { - if i != nil { - return *i - } - return 0 -} - -// IntPtr returns a pointer to the passed int. -func IntPtr(i int) *int { - return &i -} - -// Int32 returns an int value for the passed int pointer. It returns 0 if the pointer is nil. -func Int32(i *int32) int32 { - if i != nil { - return *i - } - return 0 -} - -// Int32Ptr returns a pointer to the passed int32. -func Int32Ptr(i int32) *int32 { - return &i -} - -// Int64 returns an int value for the passed int pointer. It returns 0 if the pointer is nil. -func Int64(i *int64) int64 { - if i != nil { - return *i - } - return 0 -} - -// Int64Ptr returns a pointer to the passed int64. -func Int64Ptr(i int64) *int64 { - return &i -} - -// Float32 returns an int value for the passed int pointer. It returns 0.0 if the pointer is nil. -func Float32(i *float32) float32 { - if i != nil { - return *i - } - return 0.0 -} - -// Float32Ptr returns a pointer to the passed float32. -func Float32Ptr(i float32) *float32 { - return &i -} - -// Float64 returns an int value for the passed int pointer. It returns 0.0 if the pointer is nil. -func Float64(i *float64) float64 { - if i != nil { - return *i - } - return 0.0 -} - -// Float64Ptr returns a pointer to the passed float64. -func Float64Ptr(i float64) *float64 { - return &i -} - -// ByteSlicePtr returns a pointer to the passed byte slice. -func ByteSlicePtr(b []byte) *[]byte { - return &b -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/to/go_mod_tidy_hack.go b/vendor/github.com/Azure/go-autorest/autorest/to/go_mod_tidy_hack.go deleted file mode 100644 index b7310f6b..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/to/go_mod_tidy_hack.go +++ /dev/null @@ -1,24 +0,0 @@ -// +build modhack - -package to - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// This file, and the github.com/Azure/go-autorest import, won't actually become part of -// the resultant binary. - -// Necessary for safely adding multi-module repo. -// See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository -import _ "github.com/Azure/go-autorest" diff --git a/vendor/github.com/Azure/go-autorest/autorest/utility.go b/vendor/github.com/Azure/go-autorest/autorest/utility.go deleted file mode 100644 index 8c5eb5db..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/utility.go +++ /dev/null @@ -1,231 +0,0 @@ -package autorest - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import ( - "bytes" - "encoding/json" - "encoding/xml" - "fmt" - "io" - "net" - "net/http" - "net/url" - "reflect" - "strings" -) - -// EncodedAs is a series of constants specifying various data encodings -type EncodedAs string - -const ( - // EncodedAsJSON states that data is encoded as JSON - EncodedAsJSON EncodedAs = "JSON" - - // EncodedAsXML states that data is encoded as Xml - EncodedAsXML EncodedAs = "XML" -) - -// Decoder defines the decoding method json.Decoder and xml.Decoder share -type Decoder interface { - Decode(v interface{}) error -} - -// NewDecoder creates a new decoder appropriate to the passed encoding. -// encodedAs specifies the type of encoding and r supplies the io.Reader containing the -// encoded data. -func NewDecoder(encodedAs EncodedAs, r io.Reader) Decoder { - if encodedAs == EncodedAsJSON { - return json.NewDecoder(r) - } else if encodedAs == EncodedAsXML { - return xml.NewDecoder(r) - } - return nil -} - -// CopyAndDecode decodes the data from the passed io.Reader while making a copy. Having a copy -// is especially useful if there is a chance the data will fail to decode. -// encodedAs specifies the expected encoding, r provides the io.Reader to the data, and v -// is the decoding destination. -func CopyAndDecode(encodedAs EncodedAs, r io.Reader, v interface{}) (b bytes.Buffer, err error) { - err = NewDecoder(encodedAs, io.TeeReader(r, &b)).Decode(v) - return -} - -// TeeReadCloser returns a ReadCloser that writes to w what it reads from rc. -// It utilizes io.TeeReader to copy the data read and has the same behavior when reading. -// Further, when it is closed, it ensures that rc is closed as well. -func TeeReadCloser(rc io.ReadCloser, w io.Writer) io.ReadCloser { - return &teeReadCloser{rc, io.TeeReader(rc, w)} -} - -type teeReadCloser struct { - rc io.ReadCloser - r io.Reader -} - -func (t *teeReadCloser) Read(p []byte) (int, error) { - return t.r.Read(p) -} - -func (t *teeReadCloser) Close() error { - return t.rc.Close() -} - -func containsInt(ints []int, n int) bool { - for _, i := range ints { - if i == n { - return true - } - } - return false -} - -func escapeValueStrings(m map[string]string) map[string]string { - for key, value := range m { - m[key] = url.QueryEscape(value) - } - return m -} - -func ensureValueStrings(mapOfInterface map[string]interface{}) map[string]string { - mapOfStrings := make(map[string]string) - for key, value := range mapOfInterface { - mapOfStrings[key] = ensureValueString(value) - } - return mapOfStrings -} - -func ensureValueString(value interface{}) string { - if value == nil { - return "" - } - switch v := value.(type) { - case string: - return v - case []byte: - return string(v) - default: - return fmt.Sprintf("%v", v) - } -} - -// MapToValues method converts map[string]interface{} to url.Values. -func MapToValues(m map[string]interface{}) url.Values { - v := url.Values{} - for key, value := range m { - x := reflect.ValueOf(value) - if x.Kind() == reflect.Array || x.Kind() == reflect.Slice { - for i := 0; i < x.Len(); i++ { - v.Add(key, ensureValueString(x.Index(i))) - } - } else { - v.Add(key, ensureValueString(value)) - } - } - return v -} - -// AsStringSlice method converts interface{} to []string. -// s must be of type slice or array or an error is returned. -// Each element of s will be converted to its string representation. -func AsStringSlice(s interface{}) ([]string, error) { - v := reflect.ValueOf(s) - if v.Kind() != reflect.Slice && v.Kind() != reflect.Array { - return nil, NewError("autorest", "AsStringSlice", "the value's type is not a slice or array.") - } - stringSlice := make([]string, 0, v.Len()) - - for i := 0; i < v.Len(); i++ { - stringSlice = append(stringSlice, fmt.Sprintf("%v", v.Index(i))) - } - return stringSlice, nil -} - -// String method converts interface v to string. If interface is a list, it -// joins list elements using the separator. Note that only sep[0] will be used for -// joining if any separator is specified. -func String(v interface{}, sep ...string) string { - if len(sep) == 0 { - return ensureValueString(v) - } - stringSlice, ok := v.([]string) - if ok == false { - var err error - stringSlice, err = AsStringSlice(v) - if err != nil { - panic(fmt.Sprintf("autorest: Couldn't convert value to a string %s.", err)) - } - } - return ensureValueString(strings.Join(stringSlice, sep[0])) -} - -// Encode method encodes url path and query parameters. -func Encode(location string, v interface{}, sep ...string) string { - s := String(v, sep...) - switch strings.ToLower(location) { - case "path": - return pathEscape(s) - case "query": - return queryEscape(s) - default: - return s - } -} - -func pathEscape(s string) string { - return strings.Replace(url.QueryEscape(s), "+", "%20", -1) -} - -func queryEscape(s string) string { - return url.QueryEscape(s) -} - -// ChangeToGet turns the specified http.Request into a GET (it assumes it wasn't). -// This is mainly useful for long-running operations that use the Azure-AsyncOperation -// header, so we change the initial PUT into a GET to retrieve the final result. -func ChangeToGet(req *http.Request) *http.Request { - req.Method = "GET" - req.Body = nil - req.ContentLength = 0 - req.Header.Del("Content-Length") - return req -} - -// IsTemporaryNetworkError returns true if the specified error is a temporary network error or false -// if it's not. If the error doesn't implement the net.Error interface the return value is true. -func IsTemporaryNetworkError(err error) bool { - if netErr, ok := err.(net.Error); !ok || (ok && netErr.Temporary()) { - return true - } - return false -} - -// DrainResponseBody reads the response body then closes it. -func DrainResponseBody(resp *http.Response) error { - if resp != nil && resp.Body != nil { - _, err := io.Copy(io.Discard, resp.Body) - resp.Body.Close() - return err - } - return nil -} - -func setHeader(r *http.Request, key, value string) { - if r.Header == nil { - r.Header = make(http.Header) - } - r.Header.Set(key, value) -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/utility_1.13.go b/vendor/github.com/Azure/go-autorest/autorest/utility_1.13.go deleted file mode 100644 index 3133fcc0..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/utility_1.13.go +++ /dev/null @@ -1,30 +0,0 @@ -//go:build go1.13 -// +build go1.13 - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package autorest - -import ( - "errors" - - "github.com/Azure/go-autorest/autorest/adal" -) - -// IsTokenRefreshError returns true if the specified error implements the TokenRefreshError interface. -func IsTokenRefreshError(err error) bool { - var tre adal.TokenRefreshError - return errors.As(err, &tre) -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/utility_legacy.go b/vendor/github.com/Azure/go-autorest/autorest/utility_legacy.go deleted file mode 100644 index 851e152d..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/utility_legacy.go +++ /dev/null @@ -1,32 +0,0 @@ -//go:build !go1.13 -// +build !go1.13 - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package autorest - -import "github.com/Azure/go-autorest/autorest/adal" - -// IsTokenRefreshError returns true if the specified error implements the TokenRefreshError -// interface. If err is a DetailedError it will walk the chain of Original errors. -func IsTokenRefreshError(err error) bool { - if _, ok := err.(adal.TokenRefreshError); ok { - return true - } - if de, ok := err.(DetailedError); ok { - return IsTokenRefreshError(de.Original) - } - return false -} diff --git a/vendor/github.com/Azure/go-autorest/autorest/version.go b/vendor/github.com/Azure/go-autorest/autorest/version.go deleted file mode 100644 index 713e2358..00000000 --- a/vendor/github.com/Azure/go-autorest/autorest/version.go +++ /dev/null @@ -1,41 +0,0 @@ -package autorest - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import ( - "fmt" - "runtime" -) - -const number = "v14.2.1" - -var ( - userAgent = fmt.Sprintf("Go/%s (%s-%s) go-autorest/%s", - runtime.Version(), - runtime.GOARCH, - runtime.GOOS, - number, - ) -) - -// UserAgent returns a string containing the Go version, system architecture and OS, and the go-autorest version. -func UserAgent() string { - return userAgent -} - -// Version returns the semantic version (see http://semver.org). -func Version() string { - return number -} diff --git a/vendor/github.com/Azure/go-autorest/azure-pipelines.yml b/vendor/github.com/Azure/go-autorest/azure-pipelines.yml deleted file mode 100644 index 6fb8404f..00000000 --- a/vendor/github.com/Azure/go-autorest/azure-pipelines.yml +++ /dev/null @@ -1,105 +0,0 @@ -variables: - GOPATH: '$(system.defaultWorkingDirectory)/work' - sdkPath: '$(GOPATH)/src/github.com/$(build.repository.name)' - -jobs: - - job: 'goautorest' - displayName: 'Run go-autorest CI Checks' - - strategy: - matrix: - Linux_Go113: - vm.image: 'ubuntu-18.04' - go.version: '1.13' - Linux_Go114: - vm.image: 'ubuntu-18.04' - go.version: '1.14' - - pool: - vmImage: '$(vm.image)' - - steps: - - task: GoTool@0 - inputs: - version: '$(go.version)' - displayName: "Select Go Version" - - - script: | - set -e - mkdir -p '$(GOPATH)/bin' - mkdir -p '$(sdkPath)' - shopt -s extglob - mv !(work) '$(sdkPath)' - echo '##vso[task.prependpath]$(GOPATH)/bin' - displayName: 'Create Go Workspace' - - - script: | - set -e - curl -sSL https://raw.githubusercontent.com/golang/dep/master/install.sh | sh - dep ensure -v - go install ./vendor/golang.org/x/lint/golint - go get github.com/jstemmer/go-junit-report - go get github.com/axw/gocov/gocov - go get github.com/AlekSi/gocov-xml - go get -u github.com/matm/gocov-html - workingDirectory: '$(sdkPath)' - displayName: 'Install Dependencies' - - - script: | - go vet ./autorest/... - go vet ./logger/... - go vet ./tracing/... - workingDirectory: '$(sdkPath)' - displayName: 'Vet' - - - script: | - go build -v ./autorest/... - go build -v ./logger/... - go build -v ./tracing/... - workingDirectory: '$(sdkPath)' - displayName: 'Build' - - - script: | - set -e - go test -race -v -coverprofile=coverage.txt -covermode atomic ./autorest/... ./logger/... ./tracing/... 2>&1 | go-junit-report > report.xml - gocov convert coverage.txt > coverage.json - gocov-xml < coverage.json > coverage.xml - gocov-html < coverage.json > coverage.html - workingDirectory: '$(sdkPath)' - displayName: 'Run Tests' - - - script: grep -L -r --include *.go --exclude-dir vendor -P "Copyright (\d{4}|\(c\)) Microsoft" ./ | tee >&2 - workingDirectory: '$(sdkPath)' - displayName: 'Copyright Header Check' - failOnStderr: true - condition: succeededOrFailed() - - - script: | - gofmt -s -l -w ./autorest/. >&2 - gofmt -s -l -w ./logger/. >&2 - gofmt -s -l -w ./tracing/. >&2 - workingDirectory: '$(sdkPath)' - displayName: 'Format Check' - failOnStderr: true - condition: succeededOrFailed() - - - script: | - golint ./autorest/... >&2 - golint ./logger/... >&2 - golint ./tracing/... >&2 - workingDirectory: '$(sdkPath)' - displayName: 'Linter Check' - failOnStderr: true - condition: succeededOrFailed() - - - task: PublishTestResults@2 - inputs: - testRunner: JUnit - testResultsFiles: $(sdkPath)/report.xml - failTaskOnFailedTests: true - - - task: PublishCodeCoverageResults@1 - inputs: - codeCoverageTool: Cobertura - summaryFileLocation: $(sdkPath)/coverage.xml - additionalCodeCoverageFiles: $(sdkPath)/coverage.html diff --git a/vendor/github.com/Azure/go-autorest/doc.go b/vendor/github.com/Azure/go-autorest/doc.go deleted file mode 100644 index 99ae6ca9..00000000 --- a/vendor/github.com/Azure/go-autorest/doc.go +++ /dev/null @@ -1,18 +0,0 @@ -/* -Package go-autorest provides an HTTP request client for use with Autorest-generated API client packages. -*/ -package go_autorest - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. diff --git a/vendor/github.com/Azure/go-autorest/logger/LICENSE b/vendor/github.com/Azure/go-autorest/logger/LICENSE deleted file mode 100644 index b9d6a27e..00000000 --- a/vendor/github.com/Azure/go-autorest/logger/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2015 Microsoft Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/Azure/go-autorest/logger/go_mod_tidy_hack.go b/vendor/github.com/Azure/go-autorest/logger/go_mod_tidy_hack.go deleted file mode 100644 index 0aa27680..00000000 --- a/vendor/github.com/Azure/go-autorest/logger/go_mod_tidy_hack.go +++ /dev/null @@ -1,24 +0,0 @@ -// +build modhack - -package logger - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// This file, and the github.com/Azure/go-autorest import, won't actually become part of -// the resultant binary. - -// Necessary for safely adding multi-module repo. -// See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository -import _ "github.com/Azure/go-autorest" diff --git a/vendor/github.com/Azure/go-autorest/logger/logger.go b/vendor/github.com/Azure/go-autorest/logger/logger.go deleted file mode 100644 index 2f5d8cc1..00000000 --- a/vendor/github.com/Azure/go-autorest/logger/logger.go +++ /dev/null @@ -1,337 +0,0 @@ -package logger - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import ( - "bytes" - "fmt" - "io" - "io/ioutil" - "net/http" - "net/url" - "os" - "strings" - "sync" - "time" -) - -// LevelType tells a logger the minimum level to log. When code reports a log entry, -// the LogLevel indicates the level of the log entry. The logger only records entries -// whose level is at least the level it was told to log. See the Log* constants. -// For example, if a logger is configured with LogError, then LogError, LogPanic, -// and LogFatal entries will be logged; lower level entries are ignored. -type LevelType uint32 - -const ( - // LogNone tells a logger not to log any entries passed to it. - LogNone LevelType = iota - - // LogFatal tells a logger to log all LogFatal entries passed to it. - LogFatal - - // LogPanic tells a logger to log all LogPanic and LogFatal entries passed to it. - LogPanic - - // LogError tells a logger to log all LogError, LogPanic and LogFatal entries passed to it. - LogError - - // LogWarning tells a logger to log all LogWarning, LogError, LogPanic and LogFatal entries passed to it. - LogWarning - - // LogInfo tells a logger to log all LogInfo, LogWarning, LogError, LogPanic and LogFatal entries passed to it. - LogInfo - - // LogDebug tells a logger to log all LogDebug, LogInfo, LogWarning, LogError, LogPanic and LogFatal entries passed to it. - LogDebug - - // LogAuth is a special case of LogDebug, it tells a logger to also log the body of an authentication request and response. - // NOTE: this can disclose sensitive information, use with care. - LogAuth -) - -const ( - logNone = "NONE" - logFatal = "FATAL" - logPanic = "PANIC" - logError = "ERROR" - logWarning = "WARNING" - logInfo = "INFO" - logDebug = "DEBUG" - logAuth = "AUTH" - logUnknown = "UNKNOWN" -) - -// ParseLevel converts the specified string into the corresponding LevelType. -func ParseLevel(s string) (lt LevelType, err error) { - switch strings.ToUpper(s) { - case logFatal: - lt = LogFatal - case logPanic: - lt = LogPanic - case logError: - lt = LogError - case logWarning: - lt = LogWarning - case logInfo: - lt = LogInfo - case logDebug: - lt = LogDebug - case logAuth: - lt = LogAuth - default: - err = fmt.Errorf("bad log level '%s'", s) - } - return -} - -// String implements the stringer interface for LevelType. -func (lt LevelType) String() string { - switch lt { - case LogNone: - return logNone - case LogFatal: - return logFatal - case LogPanic: - return logPanic - case LogError: - return logError - case LogWarning: - return logWarning - case LogInfo: - return logInfo - case LogDebug: - return logDebug - case LogAuth: - return logAuth - default: - return logUnknown - } -} - -// Filter defines functions for filtering HTTP request/response content. -type Filter struct { - // URL returns a potentially modified string representation of a request URL. - URL func(u *url.URL) string - - // Header returns a potentially modified set of values for the specified key. - // To completely exclude the header key/values return false. - Header func(key string, val []string) (bool, []string) - - // Body returns a potentially modified request/response body. - Body func(b []byte) []byte -} - -func (f Filter) processURL(u *url.URL) string { - if f.URL == nil { - return u.String() - } - return f.URL(u) -} - -func (f Filter) processHeader(k string, val []string) (bool, []string) { - if f.Header == nil { - return true, val - } - return f.Header(k, val) -} - -func (f Filter) processBody(b []byte) []byte { - if f.Body == nil { - return b - } - return f.Body(b) -} - -// Writer defines methods for writing to a logging facility. -type Writer interface { - // Writeln writes the specified message with the standard log entry header and new-line character. - Writeln(level LevelType, message string) - - // Writef writes the specified format specifier with the standard log entry header and no new-line character. - Writef(level LevelType, format string, a ...interface{}) - - // WriteRequest writes the specified HTTP request to the logger if the log level is greater than - // or equal to LogInfo. The request body, if set, is logged at level LogDebug or higher. - // Custom filters can be specified to exclude URL, header, and/or body content from the log. - // By default no request content is excluded. - WriteRequest(req *http.Request, filter Filter) - - // WriteResponse writes the specified HTTP response to the logger if the log level is greater than - // or equal to LogInfo. The response body, if set, is logged at level LogDebug or higher. - // Custom filters can be specified to exclude URL, header, and/or body content from the log. - // By default no response content is excluded. - WriteResponse(resp *http.Response, filter Filter) -} - -// Instance is the default log writer initialized during package init. -// This can be replaced with a custom implementation as required. -var Instance Writer - -// default log level -var logLevel = LogNone - -// Level returns the value specified in AZURE_GO_AUTOREST_LOG_LEVEL. -// If no value was specified the default value is LogNone. -// Custom loggers can call this to retrieve the configured log level. -func Level() LevelType { - return logLevel -} - -func init() { - // separated for testing purposes - initDefaultLogger() -} - -func initDefaultLogger() { - // init with nilLogger so callers don't have to do a nil check on Default - Instance = nilLogger{} - llStr := strings.ToLower(os.Getenv("AZURE_GO_SDK_LOG_LEVEL")) - if llStr == "" { - return - } - var err error - logLevel, err = ParseLevel(llStr) - if err != nil { - fmt.Fprintf(os.Stderr, "go-autorest: failed to parse log level: %s\n", err.Error()) - return - } - if logLevel == LogNone { - return - } - // default to stderr - dest := os.Stderr - lfStr := os.Getenv("AZURE_GO_SDK_LOG_FILE") - if strings.EqualFold(lfStr, "stdout") { - dest = os.Stdout - } else if lfStr != "" { - lf, err := os.Create(lfStr) - if err == nil { - dest = lf - } else { - fmt.Fprintf(os.Stderr, "go-autorest: failed to create log file, using stderr: %s\n", err.Error()) - } - } - Instance = fileLogger{ - logLevel: logLevel, - mu: &sync.Mutex{}, - logFile: dest, - } -} - -// the nil logger does nothing -type nilLogger struct{} - -func (nilLogger) Writeln(LevelType, string) {} - -func (nilLogger) Writef(LevelType, string, ...interface{}) {} - -func (nilLogger) WriteRequest(*http.Request, Filter) {} - -func (nilLogger) WriteResponse(*http.Response, Filter) {} - -// A File is used instead of a Logger so the stream can be flushed after every write. -type fileLogger struct { - logLevel LevelType - mu *sync.Mutex // for synchronizing writes to logFile - logFile *os.File -} - -func (fl fileLogger) Writeln(level LevelType, message string) { - fl.Writef(level, "%s\n", message) -} - -func (fl fileLogger) Writef(level LevelType, format string, a ...interface{}) { - if fl.logLevel >= level { - fl.mu.Lock() - defer fl.mu.Unlock() - fmt.Fprintf(fl.logFile, "%s %s", entryHeader(level), fmt.Sprintf(format, a...)) - fl.logFile.Sync() - } -} - -func (fl fileLogger) WriteRequest(req *http.Request, filter Filter) { - if req == nil || fl.logLevel < LogInfo { - return - } - b := &bytes.Buffer{} - fmt.Fprintf(b, "%s REQUEST: %s %s\n", entryHeader(LogInfo), req.Method, filter.processURL(req.URL)) - // dump headers - for k, v := range req.Header { - if ok, mv := filter.processHeader(k, v); ok { - fmt.Fprintf(b, "%s: %s\n", k, strings.Join(mv, ",")) - } - } - if fl.shouldLogBody(req.Header, req.Body) { - // dump body - body, err := ioutil.ReadAll(req.Body) - if err == nil { - fmt.Fprintln(b, string(filter.processBody(body))) - if nc, ok := req.Body.(io.Seeker); ok { - // rewind to the beginning - nc.Seek(0, io.SeekStart) - } else { - // recreate the body - req.Body = ioutil.NopCloser(bytes.NewReader(body)) - } - } else { - fmt.Fprintf(b, "failed to read body: %v\n", err) - } - } - fl.mu.Lock() - defer fl.mu.Unlock() - fmt.Fprint(fl.logFile, b.String()) - fl.logFile.Sync() -} - -func (fl fileLogger) WriteResponse(resp *http.Response, filter Filter) { - if resp == nil || fl.logLevel < LogInfo { - return - } - b := &bytes.Buffer{} - fmt.Fprintf(b, "%s RESPONSE: %d %s\n", entryHeader(LogInfo), resp.StatusCode, filter.processURL(resp.Request.URL)) - // dump headers - for k, v := range resp.Header { - if ok, mv := filter.processHeader(k, v); ok { - fmt.Fprintf(b, "%s: %s\n", k, strings.Join(mv, ",")) - } - } - if fl.shouldLogBody(resp.Header, resp.Body) { - // dump body - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err == nil { - fmt.Fprintln(b, string(filter.processBody(body))) - resp.Body = ioutil.NopCloser(bytes.NewReader(body)) - } else { - fmt.Fprintf(b, "failed to read body: %v\n", err) - } - } - fl.mu.Lock() - defer fl.mu.Unlock() - fmt.Fprint(fl.logFile, b.String()) - fl.logFile.Sync() -} - -// returns true if the provided body should be included in the log -func (fl fileLogger) shouldLogBody(header http.Header, body io.ReadCloser) bool { - ct := header.Get("Content-Type") - return fl.logLevel >= LogDebug && body != nil && !strings.Contains(ct, "application/octet-stream") -} - -// creates standard header for log entries, it contains a timestamp and the log level -func entryHeader(level LevelType) string { - // this format provides a fixed number of digits so the size of the timestamp is constant - return fmt.Sprintf("(%s) %s:", time.Now().Format("2006-01-02T15:04:05.0000000Z07:00"), level.String()) -} diff --git a/vendor/github.com/Azure/go-autorest/tracing/LICENSE b/vendor/github.com/Azure/go-autorest/tracing/LICENSE deleted file mode 100644 index b9d6a27e..00000000 --- a/vendor/github.com/Azure/go-autorest/tracing/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2015 Microsoft Corporation - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/Azure/go-autorest/tracing/go_mod_tidy_hack.go b/vendor/github.com/Azure/go-autorest/tracing/go_mod_tidy_hack.go deleted file mode 100644 index e163975c..00000000 --- a/vendor/github.com/Azure/go-autorest/tracing/go_mod_tidy_hack.go +++ /dev/null @@ -1,24 +0,0 @@ -// +build modhack - -package tracing - -// Copyright 2017 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// This file, and the github.com/Azure/go-autorest import, won't actually become part of -// the resultant binary. - -// Necessary for safely adding multi-module repo. -// See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository -import _ "github.com/Azure/go-autorest" diff --git a/vendor/github.com/Azure/go-autorest/tracing/tracing.go b/vendor/github.com/Azure/go-autorest/tracing/tracing.go deleted file mode 100644 index 0e7a6e96..00000000 --- a/vendor/github.com/Azure/go-autorest/tracing/tracing.go +++ /dev/null @@ -1,67 +0,0 @@ -package tracing - -// Copyright 2018 Microsoft Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import ( - "context" - "net/http" -) - -// Tracer represents an HTTP tracing facility. -type Tracer interface { - NewTransport(base *http.Transport) http.RoundTripper - StartSpan(ctx context.Context, name string) context.Context - EndSpan(ctx context.Context, httpStatusCode int, err error) -} - -var ( - tracer Tracer -) - -// Register will register the provided Tracer. Pass nil to unregister a Tracer. -func Register(t Tracer) { - tracer = t -} - -// IsEnabled returns true if a Tracer has been registered. -func IsEnabled() bool { - return tracer != nil -} - -// NewTransport creates a new instrumenting http.RoundTripper for the -// registered Tracer. If no Tracer has been registered it returns nil. -func NewTransport(base *http.Transport) http.RoundTripper { - if tracer != nil { - return tracer.NewTransport(base) - } - return nil -} - -// StartSpan starts a trace span with the specified name, associating it with the -// provided context. Has no effect if a Tracer has not been registered. -func StartSpan(ctx context.Context, name string) context.Context { - if tracer != nil { - return tracer.StartSpan(ctx, name) - } - return ctx -} - -// EndSpan ends a previously started span stored in the context. -// Has no effect if a Tracer has not been registered. -func EndSpan(ctx context.Context, httpStatusCode int, err error) { - if tracer != nil { - tracer.EndSpan(ctx, httpStatusCode, err) - } -} diff --git a/vendor/github.com/DataDog/appsec-internal-go/LICENSE b/vendor/github.com/DataDog/appsec-internal-go/LICENSE deleted file mode 100644 index 9301dd7a..00000000 --- a/vendor/github.com/DataDog/appsec-internal-go/LICENSE +++ /dev/null @@ -1,200 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2016-present Datadog, Inc. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/DataDog/appsec-internal-go/appsec/config.go b/vendor/github.com/DataDog/appsec-internal-go/appsec/config.go deleted file mode 100644 index 3cfed5bc..00000000 --- a/vendor/github.com/DataDog/appsec-internal-go/appsec/config.go +++ /dev/null @@ -1,203 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2023-present Datadog, Inc. - -package appsec - -import ( - "os" - "regexp" - "strconv" - "time" - "unicode" - "unicode/utf8" - - "github.com/DataDog/appsec-internal-go/log" -) - -// Configuration environment variables -const ( - // EnvAPISecEnabled is the env var used to enable API Security - EnvAPISecEnabled = "DD_API_SECURITY_ENABLED" - // EnvAPISecSampleRate is the env var used to set the sampling rate of API Security schema extraction - EnvAPISecSampleRate = "DD_API_SECURITY_REQUEST_SAMPLE_RATE" - // EnvObfuscatorKey is the env var used to provide the WAF key obfuscation regexp - EnvObfuscatorKey = "DD_APPSEC_OBFUSCATION_PARAMETER_KEY_REGEXP" - // EnvObfuscatorValue is the env var used to provide the WAF value obfuscation regexp - EnvObfuscatorValue = "DD_APPSEC_OBFUSCATION_PARAMETER_VALUE_REGEXP" - // EnvWAFTimeout is the env var used to specify the timeout value for a WAF run - EnvWAFTimeout = "DD_APPSEC_WAF_TIMEOUT" - // EnvTraceRateLimit is the env var used to set the ASM trace limiting rate - EnvTraceRateLimit = "DD_APPSEC_TRACE_RATE_LIMIT" - // EnvRules is the env var used to provide a path to a local security rule file - EnvRules = "DD_APPSEC_RULES" - // EnvRASPEnabled is the env var used to enable/disable RASP functionalities for ASM - EnvRASPEnabled = "DD_APPSEC_RASP_ENABLED" -) - -// Configuration constants and default values -const ( - // DefaultAPISecSampleRate is the default rate at which API Security schemas are extracted from requests - DefaultAPISecSampleRate = .1 - // DefaultObfuscatorKeyRegex is the default regexp used to obfuscate keys - DefaultObfuscatorKeyRegex = `(?i)pass|pw(?:or)?d|secret|(?:api|private|public|access)[_-]?key|token|consumer[_-]?(?:id|key|secret)|sign(?:ed|ature)|bearer|authorization|jsessionid|phpsessid|asp\.net[_-]sessionid|sid|jwt` - // DefaultObfuscatorValueRegex is the default regexp used to obfuscate values - DefaultObfuscatorValueRegex = `(?i)(?:p(?:ass)?w(?:or)?d|pass(?:[_-]?phrase)?|secret(?:[_-]?key)?|(?:(?:api|private|public|access)[_-]?)key(?:[_-]?id)?|(?:(?:auth|access|id|refresh)[_-]?)?token|consumer[_-]?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?|jsessionid|phpsessid|asp\.net(?:[_-]|-)sessionid|sid|jwt)(?:\s*=[^;]|"\s*:\s*"[^"]+")|bearer\s+[a-z0-9\._\-]+|token:[a-z0-9]{13}|gh[opsu]_[0-9a-zA-Z]{36}|ey[I-L][\w=-]+\.ey[I-L][\w=-]+(?:\.[\w.+\/=-]+)?|[\-]{5}BEGIN[a-z\s]+PRIVATE\sKEY[\-]{5}[^\-]+[\-]{5}END[a-z\s]+PRIVATE\sKEY|ssh-rsa\s*[a-z0-9\/\.+]{100,}` - // DefaultWAFTimeout is the default time limit past which a WAF run will timeout - DefaultWAFTimeout = time.Millisecond - // DefaultTraceRate is the default limit (trace/sec) past which ASM traces are sampled out - DefaultTraceRate uint = 100 // up to 100 appsec traces/s -) - -// APISecConfig holds the configuration for API Security schemas reporting -// It is used to enabled/disable the feature as well as to configure the rate -// at which schemas get reported, -type APISecConfig struct { - Enabled bool - SampleRate float64 -} - -// ObfuscatorConfig wraps the key and value regexp to be passed to the WAF to perform obfuscation. -type ObfuscatorConfig struct { - KeyRegex string - ValueRegex string -} - -// NewAPISecConfig creates and returns a new API Security configuration by reading the env -func NewAPISecConfig() APISecConfig { - return APISecConfig{ - Enabled: boolEnv(EnvAPISecEnabled, true), - SampleRate: readAPISecuritySampleRate(), - } -} -func readAPISecuritySampleRate() float64 { - value := os.Getenv(EnvAPISecSampleRate) - rate, err := strconv.ParseFloat(value, 64) - if err != nil { - logEnvVarParsingError(EnvAPISecSampleRate, value, err, DefaultAPISecSampleRate) - return DefaultAPISecSampleRate - } - // Clamp the value so that 0.0 <= rate <= 1.0 - if rate < 0. { - rate = 0. - } else if rate > 1. { - rate = 1. - } - return rate -} - -// RASPEnabled returns true if RASP functionalities are enabled through the env, or if DD_APPSEC_RASP_ENABLED -// is not set -func RASPEnabled() bool { - return boolEnv(EnvRASPEnabled, true) -} - -// NewObfuscatorConfig creates and returns a new WAF obfuscator configuration by reading the env -func NewObfuscatorConfig() ObfuscatorConfig { - keyRE := readObfuscatorConfigRegexp(EnvObfuscatorKey, DefaultObfuscatorKeyRegex) - valueRE := readObfuscatorConfigRegexp(EnvObfuscatorValue, DefaultObfuscatorValueRegex) - return ObfuscatorConfig{KeyRegex: keyRE, ValueRegex: valueRE} -} - -func readObfuscatorConfigRegexp(name, defaultValue string) string { - val, present := os.LookupEnv(name) - if !present { - log.Debug("appsec: %s not defined, starting with the default obfuscator regular expression", name) - return defaultValue - } - if _, err := regexp.Compile(val); err != nil { - logUnexpectedEnvVarValue(name, val, "could not compile the configured obfuscator regular expression", defaultValue) - return defaultValue - } - log.Debug("appsec: starting with the configured obfuscator regular expression %s", name) - return val -} - -// WAFTimeoutFromEnv reads and parses the WAF timeout value set through the env -// If not set, it defaults to `DefaultWAFTimeout` -func WAFTimeoutFromEnv() (timeout time.Duration) { - timeout = DefaultWAFTimeout - value := os.Getenv(EnvWAFTimeout) - if value == "" { - return - } - - // Check if the value ends with a letter, which means the user has - // specified their own time duration unit(s) such as 1s200ms. - // Otherwise, default to microseconds. - if lastRune, _ := utf8.DecodeLastRuneInString(value); !unicode.IsLetter(lastRune) { - value += "us" // Add the default microsecond time-duration suffix - } - - parsed, err := time.ParseDuration(value) - if err != nil { - logEnvVarParsingError(EnvWAFTimeout, value, err, timeout) - return - } - if parsed <= 0 { - logUnexpectedEnvVarValue(EnvWAFTimeout, parsed, "expecting a strictly positive duration", timeout) - return - } - return parsed -} - -// RateLimitFromEnv reads and parses the trace rate limit set through the env -// If not set, it defaults to `DefaultTraceRate` -func RateLimitFromEnv() (rate uint) { - rate = DefaultTraceRate - value := os.Getenv(EnvTraceRateLimit) - if value == "" { - return rate - } - parsed, err := strconv.ParseUint(value, 10, 0) - if err != nil { - logEnvVarParsingError(EnvTraceRateLimit, value, err, rate) - return - } - if parsed == 0 { - logUnexpectedEnvVarValue(EnvTraceRateLimit, parsed, "expecting a value strictly greater than 0", rate) - return - } - return uint(parsed) -} - -// RulesFromEnv returns the security rules provided through the environment -// If the env var is not set, the default recommended rules are returned instead -func RulesFromEnv() ([]byte, error) { - filepath := os.Getenv(EnvRules) - if filepath == "" { - log.Debug("appsec: using the default built-in recommended security rules") - return DefaultRuleset() - } - buf, err := os.ReadFile(filepath) - if err != nil { - if os.IsNotExist(err) { - err = log.Errorf("appsec: could not find the rules file in path %s: %w.", filepath, err) - } - return nil, err - } - log.Debug("appsec: using the security rules from file %s", filepath) - return buf, nil -} - -func logEnvVarParsingError(name, value string, err error, defaultValue any) { - log.Debug("appsec: could not parse the env var %s=%s as a duration: %v. Using default value %v.", name, value, err, defaultValue) -} - -func logUnexpectedEnvVarValue(name string, value any, reason string, defaultValue any) { - log.Debug("appsec: unexpected configuration value of %s=%v: %s. Using default value %v.", name, value, reason, defaultValue) -} - -func boolEnv(key string, def bool) bool { - strVal, ok := os.LookupEnv(key) - if !ok { - return def - } - v, err := strconv.ParseBool(strVal) - if err != nil { - logEnvVarParsingError(key, strVal, err, def) - return def - } - return v -} diff --git a/vendor/github.com/DataDog/appsec-internal-go/appsec/embed.go b/vendor/github.com/DataDog/appsec-internal-go/appsec/embed.go deleted file mode 100644 index 2d6da7df..00000000 --- a/vendor/github.com/DataDog/appsec-internal-go/appsec/embed.go +++ /dev/null @@ -1,14 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package appsec - -import _ "embed" // Blank import comment for golint compliance - -// StaticRecommendedRules holds the recommended AppSec security rules (v1.13.2) -// Source: https://github.com/DataDog/appsec-event-rules/blob/1.13.2/build/recommended.json -// -//go:embed rules.json -var StaticRecommendedRules string diff --git a/vendor/github.com/DataDog/appsec-internal-go/appsec/rules.go b/vendor/github.com/DataDog/appsec-internal-go/appsec/rules.go deleted file mode 100644 index 29a46bf2..00000000 --- a/vendor/github.com/DataDog/appsec-internal-go/appsec/rules.go +++ /dev/null @@ -1,26 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2023-present Datadog, Inc. -package appsec - -import "encoding/json" - -// DefaultRuleset returns the marshaled default recommended security rules for AppSec -func DefaultRuleset() ([]byte, error) { - rules, err := DefaultRulesetMap() - if err != nil { - return nil, err - } - return json.Marshal(rules) -} - -// DefaultRulesetMap returns the unmarshaled default recommended security rules for AppSec -func DefaultRulesetMap() (map[string]any, error) { - var rules map[string]any - if err := json.Unmarshal([]byte(StaticRecommendedRules), &rules); err != nil { - return nil, err - } - - return rules, nil -} diff --git a/vendor/github.com/DataDog/appsec-internal-go/appsec/rules.json b/vendor/github.com/DataDog/appsec-internal-go/appsec/rules.json deleted file mode 100644 index d0e486c6..00000000 --- a/vendor/github.com/DataDog/appsec-internal-go/appsec/rules.json +++ /dev/null @@ -1,9779 +0,0 @@ -{ - "version": "2.2", - "metadata": { - "rules_version": "1.13.2" - }, - "rules": [ - { - "id": "blk-001-001", - "name": "Block IP Addresses", - "tags": { - "type": "block_ip", - "category": "security_response" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "http.client_ip" - } - ], - "data": "blocked_ips" - }, - "operator": "ip_match" - } - ], - "transformers": [], - "on_match": [ - "block" - ] - }, - { - "id": "blk-001-002", - "name": "Block User Addresses", - "tags": { - "type": "block_user", - "category": "security_response" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "usr.id" - } - ], - "data": "blocked_users" - }, - "operator": "exact_match" - } - ], - "transformers": [], - "on_match": [ - "block" - ] - }, - { - "id": "crs-913-110", - "name": "Acunetix", - "tags": { - "type": "commercial_scanner", - "crs_id": "913110", - "category": "attack_attempt", - "tool_name": "Acunetix", - "cwe": "200", - "capec": "1000/118/169", - "confidence": "0" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies" - } - ], - "list": [ - "acunetix-product", - "(acunetix web vulnerability scanner", - "acunetix-scanning-agreement", - "acunetix-user-agreement", - "md5(acunetix_wvs_security_test)" - ] - }, - "operator": "phrase_match" - } - ], - "transformers": [ - "lowercase" - ] - }, - { - "id": "crs-913-120", - "name": "Known security scanner filename/argument", - "tags": { - "type": "security_scanner", - "crs_id": "913120", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "list": [ - "/.adsensepostnottherenonobook", - "/hello.html", - "/actsensepostnottherenonotive", - "/acunetix-wvs-test-for-some-inexistent-file", - "/antidisestablishmentarianism", - "/appscan_fingerprint/mac_address", - "/arachni-", - "/cybercop", - "/nessus_is_probing_you_", - "/nessustest", - "/netsparker-", - "/rfiinc.txt", - "/thereisnowaythat-you-canbethere", - "/w3af/remotefileinclude.html", - "appscan_fingerprint", - "w00tw00t.at.isc.sans.dfind", - "w00tw00t.at.blackhats.romanian.anti-sec" - ], - "options": { - "enforce_word_boundary": true - } - }, - "operator": "phrase_match" - } - ], - "transformers": [ - "lowercase" - ] - }, - { - "id": "crs-920-260", - "name": "Unicode Full/Half Width Abuse Attack Attempt", - "tags": { - "type": "http_protocol_violation", - "crs_id": "920260", - "category": "attack_attempt", - "cwe": "176", - "capec": "1000/255/153/267/71", - "confidence": "0" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.uri.raw" - } - ], - "regex": "\\%u[fF]{2}[0-9a-fA-F]{2}", - "options": { - "case_sensitive": true, - "min_length": 6 - } - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "crs-921-110", - "name": "HTTP Request Smuggling Attack", - "tags": { - "type": "http_protocol_violation", - "crs_id": "921110", - "category": "attack_attempt", - "cwe": "444", - "capec": "1000/210/272/220/33" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - } - ], - "regex": "(?:get|post|head|options|connect|put|delete|trace|track|patch|propfind|propatch|mkcol|copy|move|lock|unlock)\\s+[^\\s]+\\s+http/\\d", - "options": { - "case_sensitive": true, - "min_length": 12 - } - }, - "operator": "match_regex" - } - ], - "transformers": [ - "lowercase" - ] - }, - { - "id": "crs-921-160", - "name": "HTTP Header Injection Attack via payload (CR/LF and header-name detected)", - "tags": { - "type": "http_protocol_violation", - "crs_id": "921160", - "category": "attack_attempt", - "cwe": "113", - "capec": "1000/210/272/220/105" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.path_params" - } - ], - "regex": "[\\n\\r]+(?:refresh|(?:set-)?cookie|(?:x-)?(?:forwarded-(?:for|host|server)|via|remote-ip|remote-addr|originating-IP))\\s*:", - "options": { - "case_sensitive": true, - "min_length": 3 - } - }, - "operator": "match_regex" - } - ], - "transformers": [ - "lowercase" - ] - }, - { - "id": "crs-930-100", - "name": "Obfuscated Path Traversal Attack (/../)", - "tags": { - "type": "lfi", - "crs_id": "930100", - "category": "attack_attempt", - "cwe": "22", - "capec": "1000/255/153/126", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.uri.raw" - }, - { - "address": "server.request.headers.no_cookies" - } - ], - "regex": "(?:%(?:c(?:0%(?:[2aq]f|5c|9v)|1%(?:[19p]c|8s|af))|2(?:5(?:c(?:0%25af|1%259c)|2f|5c)|%46|f)|(?:(?:f(?:8%8)?0%8|e)0%80%a|bg%q)f|%3(?:2(?:%(?:%6|4)6|F)|5%%63)|u(?:221[56]|002f|EFC8|F025)|1u|5c)|0x(?:2f|5c)|\\/|\\x5c)(?:%(?:(?:f(?:(?:c%80|8)%8)?0%8|e)0%80%ae|2(?:(?:5(?:c0%25a|2))?e|%45)|u(?:(?:002|ff0)e|2024)|%32(?:%(?:%6|4)5|E)|c0(?:%[256aef]e|\\.))|\\.(?:%0[01])?|0x2e){2,3}(?:%(?:c(?:0%(?:[2aq]f|5c|9v)|1%(?:[19p]c|8s|af))|2(?:5(?:c(?:0%25af|1%259c)|2f|5c)|%46|f)|(?:(?:f(?:8%8)?0%8|e)0%80%a|bg%q)f|%3(?:2(?:%(?:%6|4)6|F)|5%%63)|u(?:221[56]|002f|EFC8|F025)|1u|5c)|0x(?:2f|5c)|\\/|\\x5c)", - "options": { - "min_length": 4 - } - }, - "operator": "match_regex" - } - ], - "transformers": [ - "normalizePath" - ] - }, - { - "id": "crs-930-110", - "name": "Simple Path Traversal Attack (/../)", - "tags": { - "type": "lfi", - "crs_id": "930110", - "category": "attack_attempt", - "cwe": "22", - "capec": "1000/255/153/126", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.uri.raw" - }, - { - "address": "server.request.headers.no_cookies" - } - ], - "regex": "(?:(?:^|[\\x5c/])\\.{2,3}[\\x5c/]|[\\x5c/]\\.{2,3}(?:[\\x5c/]|$))", - "options": { - "case_sensitive": true, - "min_length": 3 - } - }, - "operator": "match_regex" - } - ], - "transformers": [ - "removeNulls" - ] - }, - { - "id": "crs-930-120", - "name": "OS File Access Attempt", - "tags": { - "type": "lfi", - "crs_id": "930120", - "category": "attack_attempt", - "cwe": "22", - "capec": "1000/255/153/126", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "list": [ - "/.htaccess", - "/.htdigest", - "/.htpasswd", - "/.addressbook", - "/.aptitude/config", - ".aws/config", - ".aws/credentials", - "/.bash_config", - "/.bash_history", - "/.bash_logout", - "/.bash_profile", - "/.bashrc", - ".cache/notify-osd.log", - ".config/odesk/odesk team.conf", - "/.cshrc", - "/.dockerignore", - ".drush/", - "/.eslintignore", - "/.fbcindex", - "/.forward", - "/.git", - ".git/", - "/.gitattributes", - "/.gitconfig", - ".gnupg/", - ".hplip/hplip.conf", - "/.ksh_history", - "/.lesshst", - ".lftp/", - "/.lhistory", - "/.lldb-history", - ".local/share/mc/", - "/.lynx_cookies", - "/.my.cnf", - "/.mysql_history", - "/.nano_history", - "/.node_repl_history", - "/.pearrc", - "/.pgpass", - "/.php_history", - "/.pinerc", - ".pki/", - "/.proclog", - "/.procmailrc", - "/.psql_history", - "/.python_history", - "/.rediscli_history", - "/.rhistory", - "/.rhosts", - "/.sh_history", - "/.sqlite_history", - ".ssh/authorized_keys", - ".ssh/config", - ".ssh/id_dsa", - ".ssh/id_dsa.pub", - ".ssh/id_rsa", - ".ssh/id_rsa.pub", - ".ssh/identity", - ".ssh/identity.pub", - ".ssh/id_ecdsa", - ".ssh/id_ecdsa.pub", - ".ssh/known_hosts", - ".subversion/auth", - ".subversion/config", - ".subversion/servers", - ".tconn/tconn.conf", - "/.tcshrc", - ".vidalia/vidalia.conf", - "/.viminfo", - "/.vimrc", - "/.www_acl", - "/.wwwacl", - "/.xauthority", - "/.zhistory", - "/.zshrc", - "/.zsh_history", - "/.nsconfig", - "data/elasticsearch", - "data/kafka", - "etc/ansible", - "etc/bind", - "etc/centos-release", - "etc/centos-release-upstream", - "etc/clam.d", - "etc/elasticsearch", - "etc/freshclam.conf", - "etc/gshadow", - "etc/gshadow-", - "etc/httpd", - "etc/kafka", - "etc/kibana", - "etc/logstash", - "etc/lvm", - "etc/mongod.conf", - "etc/my.cnf", - "etc/nuxeo.conf", - "etc/pki", - "etc/postfix", - "etc/scw-release", - "etc/subgid", - "etc/subgid-", - "etc/sudoers.d", - "etc/sysconfig", - "etc/system-release-cpe", - "opt/nuxeo", - "opt/tomcat", - "tmp/kafka-logs", - "usr/lib/rpm/rpm.log", - "var/data/elasticsearch", - "var/lib/elasticsearch", - "etc/.java", - "etc/acpi", - "etc/alsa", - "etc/alternatives", - "etc/apache2", - "etc/apm", - "etc/apparmor", - "etc/apparmor.d", - "etc/apport", - "etc/apt", - "etc/asciidoc", - "etc/avahi", - "etc/bash_completion.d", - "etc/binfmt.d", - "etc/bluetooth", - "etc/bonobo-activation", - "etc/brltty", - "etc/ca-certificates", - "etc/calendar", - "etc/chatscripts", - "etc/chromium-browser", - "etc/clamav", - "etc/cni", - "etc/console-setup", - "etc/coraza-waf", - "etc/cracklib", - "etc/cron.d", - "etc/cron.daily", - "etc/cron.hourly", - "etc/cron.monthly", - "etc/cron.weekly", - "etc/cups", - "etc/cups.save", - "etc/cupshelpers", - "etc/dbus-1", - "etc/dconf", - "etc/default", - "etc/depmod.d", - "etc/dhcp", - "etc/dictionaries-common", - "etc/dkms", - "etc/dnsmasq.d", - "etc/dockeretc/dpkg", - "etc/emacs", - "etc/environment.d", - "etc/fail2ban", - "etc/firebird", - "etc/firefox", - "etc/fonts", - "etc/fwupd", - "etc/gconf", - "etc/gdb", - "etc/gdm3", - "etc/geoclue", - "etc/ghostscript", - "etc/gimp", - "etc/glvnd", - "etc/gnome", - "etc/gnome-vfs-2.0", - "etc/gnucash", - "etc/gnustep", - "etc/groff", - "etc/grub.d", - "etc/gss", - "etc/gtk-2.0", - "etc/gtk-3.0", - "etc/hp", - "etc/ifplugd", - "etc/imagemagick-6", - "etc/init", - "etc/init.d", - "etc/initramfs-tools", - "etc/insserv.conf.d", - "etc/iproute2", - "etc/iptables", - "etc/java", - "etc/java-11-openjdk", - "etc/java-17-oracle", - "etc/java-8-openjdk", - "etc/kernel", - "etc/ld.so.conf.d", - "etc/ldap", - "etc/libblockdev", - "etc/libibverbs.d", - "etc/libnl-3", - "etc/libpaper.d", - "etc/libreoffice", - "etc/lighttpd", - "etc/logcheck", - "etc/logrotate.d", - "etc/lynx", - "etc/mail", - "etc/mc", - "etc/menu", - "etc/menu-methods", - "etc/modprobe.d", - "etc/modsecurity", - "etc/modules-load.d", - "etc/monit", - "etc/mono", - "etc/mplayer", - "etc/mpv", - "etc/muttrc.d", - "etc/mysql", - "etc/netplan", - "etc/network", - "etc/networkd-dispatcher", - "etc/networkmanager", - "etc/newt", - "etc/nghttpx", - "etc/nikto", - "etc/odbcdatasources", - "etc/openal", - "etc/openmpi", - "etc/opt", - "etc/osync", - "etc/packagekit", - "etc/pam.d", - "etc/pcmcia", - "etc/perl", - "etc/php", - "etc/pki", - "etc/pm", - "etc/polkit-1", - "etc/postfix", - "etc/ppp", - "etc/profile.d", - "etc/proftpd", - "etc/pulse", - "etc/python", - "etc/rc0.d", - "etc/rc1.d", - "etc/rc2.d", - "etc/rc3.d", - "etc/rc4.d", - "etc/rc5.d", - "etc/rc6.d", - "etc/rcs.d", - "etc/resolvconf", - "etc/rsyslog.d", - "etc/samba", - "etc/sane.d", - "etc/security", - "etc/selinux", - "etc/sensors.d", - "etc/sgml", - "etc/signon-ui", - "etc/skel", - "etc/snmp", - "etc/sound", - "etc/spamassassin", - "etc/speech-dispatcher", - "etc/ssh", - "etc/ssl", - "etc/sudoers.d", - "etc/sysctl.d", - "etc/sysstat", - "etc/systemd", - "etc/terminfo", - "etc/texmf", - "etc/thermald", - "etc/thnuclnt", - "etc/thunderbird", - "etc/timidity", - "etc/tmpfiles.d", - "etc/ubuntu-advantage", - "etc/udev", - "etc/udisks2", - "etc/ufw", - "etc/update-manager", - "etc/update-motd.d", - "etc/update-notifier", - "etc/upower", - "etc/urlview", - "etc/usb_modeswitch.d", - "etc/vim", - "etc/vmware", - "etc/vmware-installer", - "etc/vmware-vix", - "etc/vulkan", - "etc/w3m", - "etc/wireshark", - "etc/wpa_supplicant", - "etc/x11", - "etc/xdg", - "etc/xml", - "etc/redis.conf", - "etc/redis-sentinel.conf", - "etc/php.ini", - "bin/php.ini", - "etc/httpd/php.ini", - "usr/lib/php.ini", - "usr/lib/php/php.ini", - "usr/local/etc/php.ini", - "usr/local/lib/php.ini", - "usr/local/php/lib/php.ini", - "usr/local/php4/lib/php.ini", - "usr/local/php5/lib/php.ini", - "usr/local/apache/conf/php.ini", - "etc/php4.4/fcgi/php.ini", - "etc/php4/apache/php.ini", - "etc/php4/apache2/php.ini", - "etc/php5/apache/php.ini", - "etc/php5/apache2/php.ini", - "etc/php/php.ini", - "etc/php/php4/php.ini", - "etc/php/apache/php.ini", - "etc/php/apache2/php.ini", - "web/conf/php.ini", - "usr/local/zend/etc/php.ini", - "opt/xampp/etc/php.ini", - "var/local/www/conf/php.ini", - "etc/php/cgi/php.ini", - "etc/php4/cgi/php.ini", - "etc/php5/cgi/php.ini", - "home2/bin/stable/apache/php.ini", - "home/bin/stable/apache/php.ini", - "etc/httpd/conf.d/php.conf", - "php5/php.ini", - "php4/php.ini", - "php/php.ini", - "windows/php.ini", - "winnt/php.ini", - "apache/php/php.ini", - "xampp/apache/bin/php.ini", - "netserver/bin/stable/apache/php.ini", - "volumes/macintosh_hd1/usr/local/php/lib/php.ini", - "etc/mono/1.0/machine.config", - "etc/mono/2.0/machine.config", - "etc/mono/2.0/web.config", - "etc/mono/config", - "usr/local/cpanel/logs/stats_log", - "usr/local/cpanel/logs/access_log", - "usr/local/cpanel/logs/error_log", - "usr/local/cpanel/logs/license_log", - "usr/local/cpanel/logs/login_log", - "var/cpanel/cpanel.config", - "usr/local/psa/admin/logs/httpsd_access_log", - "usr/local/psa/admin/logs/panel.log", - "usr/local/psa/admin/conf/php.ini", - "etc/sw-cp-server/applications.d/plesk.conf", - "usr/local/psa/admin/conf/site_isolation_settings.ini", - "usr/local/sb/config", - "etc/sw-cp-server/applications.d/00-sso-cpserver.conf", - "etc/sso/sso_config.ini", - "etc/mysql/conf.d/old_passwords.cnf", - "var/mysql.log", - "var/mysql-bin.index", - "var/data/mysql-bin.index", - "program files/mysql/mysql server 5.0/data/{host}.err", - "program files/mysql/mysql server 5.0/data/mysql.log", - "program files/mysql/mysql server 5.0/data/mysql.err", - "program files/mysql/mysql server 5.0/data/mysql-bin.log", - "program files/mysql/mysql server 5.0/data/mysql-bin.index", - "program files/mysql/data/{host}.err", - "program files/mysql/data/mysql.log", - "program files/mysql/data/mysql.err", - "program files/mysql/data/mysql-bin.log", - "program files/mysql/data/mysql-bin.index", - "mysql/data/{host}.err", - "mysql/data/mysql.log", - "mysql/data/mysql.err", - "mysql/data/mysql-bin.log", - "mysql/data/mysql-bin.index", - "usr/local/mysql/data/mysql.log", - "usr/local/mysql/data/mysql.err", - "usr/local/mysql/data/mysql-bin.log", - "usr/local/mysql/data/mysql-slow.log", - "usr/local/mysql/data/mysqlderror.log", - "usr/local/mysql/data/{host}.err", - "usr/local/mysql/data/mysql-bin.index", - "var/lib/mysql/my.cnf", - "etc/mysql/my.cnf", - "etc/my.cnf", - "program files/mysql/mysql server 5.0/my.ini", - "program files/mysql/mysql server 5.0/my.cnf", - "program files/mysql/my.ini", - "program files/mysql/my.cnf", - "mysql/my.ini", - "mysql/my.cnf", - "mysql/bin/my.ini", - "var/postgresql/log/postgresql.log", - "usr/internet/pgsql/data/postmaster.log", - "usr/local/pgsql/data/postgresql.log", - "usr/local/pgsql/data/pg_log", - "postgresql/log/pgadmin.log", - "var/lib/pgsql/data/postgresql.conf", - "var/postgresql/db/postgresql.conf", - "var/nm2/postgresql.conf", - "usr/local/pgsql/data/postgresql.conf", - "usr/local/pgsql/data/pg_hba.conf", - "usr/internet/pgsql/data/pg_hba.conf", - "usr/local/pgsql/data/passwd", - "usr/local/pgsql/bin/pg_passwd", - "etc/postgresql/postgresql.conf", - "etc/postgresql/pg_hba.conf", - "home/postgres/data/postgresql.conf", - "home/postgres/data/pg_version", - "home/postgres/data/pg_ident.conf", - "home/postgres/data/pg_hba.conf", - "program files/postgresql/8.3/data/pg_hba.conf", - "program files/postgresql/8.3/data/pg_ident.conf", - "program files/postgresql/8.3/data/postgresql.conf", - "program files/postgresql/8.4/data/pg_hba.conf", - "program files/postgresql/8.4/data/pg_ident.conf", - "program files/postgresql/8.4/data/postgresql.conf", - "program files/postgresql/9.0/data/pg_hba.conf", - "program files/postgresql/9.0/data/pg_ident.conf", - "program files/postgresql/9.0/data/postgresql.conf", - "program files/postgresql/9.1/data/pg_hba.conf", - "program files/postgresql/9.1/data/pg_ident.conf", - "program files/postgresql/9.1/data/postgresql.conf", - "wamp/logs/access.log", - "wamp/logs/apache_error.log", - "wamp/logs/genquery.log", - "wamp/logs/mysql.log", - "wamp/logs/slowquery.log", - "wamp/bin/apache/apache2.2.22/logs/access.log", - "wamp/bin/apache/apache2.2.22/logs/error.log", - "wamp/bin/apache/apache2.2.21/logs/access.log", - "wamp/bin/apache/apache2.2.21/logs/error.log", - "wamp/bin/mysql/mysql5.5.24/data/mysql-bin.index", - "wamp/bin/mysql/mysql5.5.16/data/mysql-bin.index", - "wamp/bin/apache/apache2.2.21/conf/httpd.conf", - "wamp/bin/apache/apache2.2.22/conf/httpd.conf", - "wamp/bin/apache/apache2.2.21/wampserver.conf", - "wamp/bin/apache/apache2.2.22/wampserver.conf", - "wamp/bin/apache/apache2.2.22/conf/wampserver.conf", - "wamp/bin/mysql/mysql5.5.24/my.ini", - "wamp/bin/mysql/mysql5.5.24/wampserver.conf", - "wamp/bin/mysql/mysql5.5.16/my.ini", - "wamp/bin/mysql/mysql5.5.16/wampserver.conf", - "wamp/bin/php/php5.3.8/php.ini", - "wamp/bin/php/php5.4.3/php.ini", - "xampp/apache/logs/access.log", - "xampp/apache/logs/error.log", - "xampp/mysql/data/mysql-bin.index", - "xampp/mysql/data/mysql.err", - "xampp/mysql/data/{host}.err", - "xampp/sendmail/sendmail.log", - "xampp/apache/conf/httpd.conf", - "xampp/filezillaftp/filezilla server.xml", - "xampp/mercurymail/mercury.ini", - "xampp/php/php.ini", - "xampp/phpmyadmin/config.inc.php", - "xampp/sendmail/sendmail.ini", - "xampp/webalizer/webalizer.conf", - "opt/lampp/etc/httpd.conf", - "xampp/htdocs/aca.txt", - "xampp/htdocs/admin.php", - "xampp/htdocs/leer.txt", - "usr/local/apache/logs/audit_log", - "usr/local/apache2/logs/audit_log", - "logs/security_debug_log", - "logs/security_log", - "usr/local/apache/conf/modsec.conf", - "usr/local/apache2/conf/modsec.conf", - "winnt/system32/logfiles/msftpsvc", - "winnt/system32/logfiles/msftpsvc1", - "winnt/system32/logfiles/msftpsvc2", - "windows/system32/logfiles/msftpsvc", - "windows/system32/logfiles/msftpsvc1", - "windows/system32/logfiles/msftpsvc2", - "etc/logrotate.d/proftpd", - "www/logs/proftpd.system.log", - "etc/pam.d/proftpd", - "etc/proftp.conf", - "etc/protpd/proftpd.conf", - "etc/vhcs2/proftpd/proftpd.conf", - "etc/proftpd/modules.conf", - "etc/vsftpd.chroot_list", - "etc/logrotate.d/vsftpd.log", - "etc/vsftpd/vsftpd.conf", - "etc/vsftpd.conf", - "etc/chrootusers", - "var/adm/log/xferlog", - "etc/wu-ftpd/ftpaccess", - "etc/wu-ftpd/ftphosts", - "etc/wu-ftpd/ftpusers", - "logs/pure-ftpd.log", - "usr/sbin/pure-config.pl", - "usr/etc/pure-ftpd.conf", - "etc/pure-ftpd/pure-ftpd.conf", - "usr/local/etc/pure-ftpd.conf", - "usr/local/etc/pureftpd.pdb", - "usr/local/pureftpd/etc/pureftpd.pdb", - "usr/local/pureftpd/sbin/pure-config.pl", - "usr/local/pureftpd/etc/pure-ftpd.conf", - "etc/pure-ftpd.conf", - "etc/pure-ftpd/pure-ftpd.pdb", - "etc/pureftpd.pdb", - "etc/pureftpd.passwd", - "etc/pure-ftpd/pureftpd.pdb", - "usr/ports/ftp/pure-ftpd/pure-ftpd.conf", - "usr/ports/ftp/pure-ftpd/pureftpd.pdb", - "usr/ports/ftp/pure-ftpd/pureftpd.passwd", - "usr/ports/net/pure-ftpd/pure-ftpd.conf", - "usr/ports/net/pure-ftpd/pureftpd.pdb", - "usr/ports/net/pure-ftpd/pureftpd.passwd", - "usr/pkgsrc/net/pureftpd/pure-ftpd.conf", - "usr/pkgsrc/net/pureftpd/pureftpd.pdb", - "usr/pkgsrc/net/pureftpd/pureftpd.passwd", - "usr/ports/contrib/pure-ftpd/pure-ftpd.conf", - "usr/ports/contrib/pure-ftpd/pureftpd.pdb", - "usr/ports/contrib/pure-ftpd/pureftpd.passwd", - "usr/sbin/mudlogd", - "etc/muddleftpd/mudlog", - "etc/muddleftpd.com", - "etc/muddleftpd/mudlogd.conf", - "etc/muddleftpd/muddleftpd.conf", - "usr/sbin/mudpasswd", - "etc/muddleftpd/muddleftpd.passwd", - "etc/muddleftpd/passwd", - "etc/logrotate.d/ftp", - "etc/ftpchroot", - "etc/ftphosts", - "etc/ftpusers", - "winnt/system32/logfiles/smtpsvc", - "winnt/system32/logfiles/smtpsvc1", - "winnt/system32/logfiles/smtpsvc2", - "winnt/system32/logfiles/smtpsvc3", - "winnt/system32/logfiles/smtpsvc4", - "winnt/system32/logfiles/smtpsvc5", - "windows/system32/logfiles/smtpsvc", - "windows/system32/logfiles/smtpsvc1", - "windows/system32/logfiles/smtpsvc2", - "windows/system32/logfiles/smtpsvc3", - "windows/system32/logfiles/smtpsvc4", - "windows/system32/logfiles/smtpsvc5", - "etc/osxhttpd/osxhttpd.conf", - "system/library/webobjects/adaptors/apache2.2/apache.conf", - "etc/apache2/sites-available/default", - "etc/apache2/sites-available/default-ssl", - "etc/apache2/sites-enabled/000-default", - "etc/apache2/sites-enabled/default", - "etc/apache2/apache2.conf", - "etc/apache2/ports.conf", - "usr/local/etc/apache/httpd.conf", - "usr/pkg/etc/httpd/httpd.conf", - "usr/pkg/etc/httpd/httpd-default.conf", - "usr/pkg/etc/httpd/httpd-vhosts.conf", - "etc/httpd/mod_php.conf", - "etc/httpd/extra/httpd-ssl.conf", - "etc/rc.d/rc.httpd", - "usr/local/apache/conf/httpd.conf.default", - "usr/local/apache/conf/access.conf", - "usr/local/apache22/conf/httpd.conf", - "usr/local/apache22/httpd.conf", - "usr/local/etc/apache22/conf/httpd.conf", - "usr/local/apps/apache22/conf/httpd.conf", - "etc/apache22/conf/httpd.conf", - "etc/apache22/httpd.conf", - "opt/apache22/conf/httpd.conf", - "usr/local/etc/apache2/vhosts.conf", - "usr/local/apache/conf/vhosts.conf", - "usr/local/apache2/conf/vhosts.conf", - "usr/local/apache/conf/vhosts-custom.conf", - "usr/local/apache2/conf/vhosts-custom.conf", - "etc/apache/default-server.conf", - "etc/apache2/default-server.conf", - "usr/local/apache2/conf/extra/httpd-ssl.conf", - "usr/local/apache2/conf/ssl.conf", - "etc/httpd/conf.d", - "usr/local/etc/apache22/httpd.conf", - "usr/local/etc/apache2/httpd.conf", - "etc/apache2/httpd2.conf", - "etc/apache2/ssl-global.conf", - "etc/apache2/vhosts.d/00_default_vhost.conf", - "apache/conf/httpd.conf", - "etc/apache/httpd.conf", - "etc/httpd/conf", - "http/httpd.conf", - "usr/local/apache1.3/conf/httpd.conf", - "usr/local/etc/httpd/conf", - "var/apache/conf/httpd.conf", - "var/www/conf", - "www/apache/conf/httpd.conf", - "www/conf/httpd.conf", - "etc/init.d", - "etc/apache/access.conf", - "etc/rc.conf", - "www/logs/freebsddiary-error.log", - "www/logs/freebsddiary-access_log", - "library/webserver/documents/index.html", - "library/webserver/documents/index.htm", - "library/webserver/documents/default.html", - "library/webserver/documents/default.htm", - "library/webserver/documents/index.php", - "library/webserver/documents/default.php", - "usr/local/etc/webmin/miniserv.conf", - "etc/webmin/miniserv.conf", - "usr/local/etc/webmin/miniserv.users", - "etc/webmin/miniserv.users", - "winnt/system32/logfiles/w3svc/inetsvn1.log", - "winnt/system32/logfiles/w3svc1/inetsvn1.log", - "winnt/system32/logfiles/w3svc2/inetsvn1.log", - "winnt/system32/logfiles/w3svc3/inetsvn1.log", - "windows/system32/logfiles/w3svc/inetsvn1.log", - "windows/system32/logfiles/w3svc1/inetsvn1.log", - "windows/system32/logfiles/w3svc2/inetsvn1.log", - "windows/system32/logfiles/w3svc3/inetsvn1.log", - "apache/logs/error.log", - "apache/logs/access.log", - "apache2/logs/error.log", - "apache2/logs/access.log", - "logs/error.log", - "logs/access.log", - "etc/httpd/logs/access_log", - "etc/httpd/logs/access.log", - "etc/httpd/logs/error_log", - "etc/httpd/logs/error.log", - "usr/local/apache/logs/access_log", - "usr/local/apache/logs/access.log", - "usr/local/apache/logs/error_log", - "usr/local/apache/logs/error.log", - "usr/local/apache2/logs/access_log", - "usr/local/apache2/logs/access.log", - "usr/local/apache2/logs/error_log", - "usr/local/apache2/logs/error.log", - "var/www/logs/access_log", - "var/www/logs/access.log", - "var/www/logs/error_log", - "var/www/logs/error.log", - "opt/lampp/logs/access_log", - "opt/lampp/logs/error_log", - "opt/xampp/logs/access_log", - "opt/xampp/logs/error_log", - "opt/lampp/logs/access.log", - "opt/lampp/logs/error.log", - "opt/xampp/logs/access.log", - "opt/xampp/logs/error.log", - "program files/apache group/apache/logs/access.log", - "program files/apache group/apache/logs/error.log", - "program files/apache software foundation/apache2.2/logs/error.log", - "program files/apache software foundation/apache2.2/logs/access.log", - "opt/apache/apache.conf", - "opt/apache/conf/apache.conf", - "opt/apache2/apache.conf", - "opt/apache2/conf/apache.conf", - "opt/httpd/apache.conf", - "opt/httpd/conf/apache.conf", - "etc/httpd/apache.conf", - "etc/apache2/apache.conf", - "etc/httpd/conf/apache.conf", - "usr/local/apache/apache.conf", - "usr/local/apache/conf/apache.conf", - "usr/local/apache2/apache.conf", - "usr/local/apache2/conf/apache.conf", - "usr/local/php/apache.conf.php", - "usr/local/php4/apache.conf.php", - "usr/local/php5/apache.conf.php", - "usr/local/php/apache.conf", - "usr/local/php4/apache.conf", - "usr/local/php5/apache.conf", - "private/etc/httpd/apache.conf", - "opt/apache/apache2.conf", - "opt/apache/conf/apache2.conf", - "opt/apache2/apache2.conf", - "opt/apache2/conf/apache2.conf", - "opt/httpd/apache2.conf", - "opt/httpd/conf/apache2.conf", - "etc/httpd/apache2.conf", - "etc/httpd/conf/apache2.conf", - "usr/local/apache/apache2.conf", - "usr/local/apache/conf/apache2.conf", - "usr/local/apache2/apache2.conf", - "usr/local/apache2/conf/apache2.conf", - "usr/local/php/apache2.conf.php", - "usr/local/php4/apache2.conf.php", - "usr/local/php5/apache2.conf.php", - "usr/local/php/apache2.conf", - "usr/local/php4/apache2.conf", - "usr/local/php5/apache2.conf", - "private/etc/httpd/apache2.conf", - "usr/local/apache/conf/httpd.conf", - "usr/local/apache2/conf/httpd.conf", - "etc/httpd/conf/httpd.conf", - "etc/apache/apache.conf", - "etc/apache/conf/httpd.conf", - "etc/apache2/httpd.conf", - "usr/apache2/conf/httpd.conf", - "usr/apache/conf/httpd.conf", - "usr/local/etc/apache/conf/httpd.conf", - "usr/local/apache/httpd.conf", - "usr/local/apache2/httpd.conf", - "usr/local/httpd/conf/httpd.conf", - "usr/local/etc/apache2/conf/httpd.conf", - "usr/local/etc/httpd/conf/httpd.conf", - "usr/local/apps/apache2/conf/httpd.conf", - "usr/local/apps/apache/conf/httpd.conf", - "usr/local/php/httpd.conf.php", - "usr/local/php4/httpd.conf.php", - "usr/local/php5/httpd.conf.php", - "usr/local/php/httpd.conf", - "usr/local/php4/httpd.conf", - "usr/local/php5/httpd.conf", - "etc/apache2/conf/httpd.conf", - "etc/http/conf/httpd.conf", - "etc/httpd/httpd.conf", - "etc/http/httpd.conf", - "etc/httpd.conf", - "opt/apache/conf/httpd.conf", - "opt/apache2/conf/httpd.conf", - "var/www/conf/httpd.conf", - "private/etc/httpd/httpd.conf", - "private/etc/httpd/httpd.conf.default", - "etc/apache2/vhosts.d/default_vhost.include", - "etc/apache2/conf.d/charset", - "etc/apache2/conf.d/security", - "etc/apache2/envvars", - "etc/apache2/mods-available/autoindex.conf", - "etc/apache2/mods-available/deflate.conf", - "etc/apache2/mods-available/dir.conf", - "etc/apache2/mods-available/mem_cache.conf", - "etc/apache2/mods-available/mime.conf", - "etc/apache2/mods-available/proxy.conf", - "etc/apache2/mods-available/setenvif.conf", - "etc/apache2/mods-available/ssl.conf", - "etc/apache2/mods-enabled/alias.conf", - "etc/apache2/mods-enabled/deflate.conf", - "etc/apache2/mods-enabled/dir.conf", - "etc/apache2/mods-enabled/mime.conf", - "etc/apache2/mods-enabled/negotiation.conf", - "etc/apache2/mods-enabled/php5.conf", - "etc/apache2/mods-enabled/status.conf", - "program files/apache group/apache/conf/httpd.conf", - "program files/apache group/apache2/conf/httpd.conf", - "program files/xampp/apache/conf/apache.conf", - "program files/xampp/apache/conf/apache2.conf", - "program files/xampp/apache/conf/httpd.conf", - "program files/apache group/apache/apache.conf", - "program files/apache group/apache/conf/apache.conf", - "program files/apache group/apache2/conf/apache.conf", - "program files/apache group/apache/apache2.conf", - "program files/apache group/apache/conf/apache2.conf", - "program files/apache group/apache2/conf/apache2.conf", - "program files/apache software foundation/apache2.2/conf/httpd.conf", - "volumes/macintosh_hd1/opt/httpd/conf/httpd.conf", - "volumes/macintosh_hd1/opt/apache/conf/httpd.conf", - "volumes/macintosh_hd1/opt/apache2/conf/httpd.conf", - "volumes/macintosh_hd1/usr/local/php/httpd.conf.php", - "volumes/macintosh_hd1/usr/local/php4/httpd.conf.php", - "volumes/macintosh_hd1/usr/local/php5/httpd.conf.php", - "volumes/webbackup/opt/apache2/conf/httpd.conf", - "volumes/webbackup/private/etc/httpd/httpd.conf", - "volumes/webbackup/private/etc/httpd/httpd.conf.default", - "usr/local/etc/apache/vhosts.conf", - "usr/local/jakarta/tomcat/conf/jakarta.conf", - "usr/local/jakarta/tomcat/conf/server.xml", - "usr/local/jakarta/tomcat/conf/context.xml", - "usr/local/jakarta/tomcat/conf/workers.properties", - "usr/local/jakarta/tomcat/conf/logging.properties", - "usr/local/jakarta/dist/tomcat/conf/jakarta.conf", - "usr/local/jakarta/dist/tomcat/conf/server.xml", - "usr/local/jakarta/dist/tomcat/conf/context.xml", - "usr/local/jakarta/dist/tomcat/conf/workers.properties", - "usr/local/jakarta/dist/tomcat/conf/logging.properties", - "usr/share/tomcat6/conf/server.xml", - "usr/share/tomcat6/conf/context.xml", - "usr/share/tomcat6/conf/workers.properties", - "usr/share/tomcat6/conf/logging.properties", - "var/cpanel/tomcat.options", - "usr/local/jakarta/tomcat/logs/catalina.out", - "usr/local/jakarta/tomcat/logs/catalina.err", - "opt/tomcat/logs/catalina.out", - "opt/tomcat/logs/catalina.err", - "usr/share/logs/catalina.out", - "usr/share/logs/catalina.err", - "usr/share/tomcat/logs/catalina.out", - "usr/share/tomcat/logs/catalina.err", - "usr/share/tomcat6/logs/catalina.out", - "usr/share/tomcat6/logs/catalina.err", - "usr/local/apache/logs/mod_jk.log", - "usr/local/jakarta/tomcat/logs/mod_jk.log", - "usr/local/jakarta/dist/tomcat/logs/mod_jk.log", - "opt/[jboss]/server/default/conf/jboss-minimal.xml", - "opt/[jboss]/server/default/conf/jboss-service.xml", - "opt/[jboss]/server/default/conf/jndi.properties", - "opt/[jboss]/server/default/conf/log4j.xml", - "opt/[jboss]/server/default/conf/login-config.xml", - "opt/[jboss]/server/default/conf/standardjaws.xml", - "opt/[jboss]/server/default/conf/standardjboss.xml", - "opt/[jboss]/server/default/conf/server.log.properties", - "opt/[jboss]/server/default/deploy/jboss-logging.xml", - "usr/local/[jboss]/server/default/conf/jboss-minimal.xml", - "usr/local/[jboss]/server/default/conf/jboss-service.xml", - "usr/local/[jboss]/server/default/conf/jndi.properties", - "usr/local/[jboss]/server/default/conf/log4j.xml", - "usr/local/[jboss]/server/default/conf/login-config.xml", - "usr/local/[jboss]/server/default/conf/standardjaws.xml", - "usr/local/[jboss]/server/default/conf/standardjboss.xml", - "usr/local/[jboss]/server/default/conf/server.log.properties", - "usr/local/[jboss]/server/default/deploy/jboss-logging.xml", - "private/tmp/[jboss]/server/default/conf/jboss-minimal.xml", - "private/tmp/[jboss]/server/default/conf/jboss-service.xml", - "private/tmp/[jboss]/server/default/conf/jndi.properties", - "private/tmp/[jboss]/server/default/conf/log4j.xml", - "private/tmp/[jboss]/server/default/conf/login-config.xml", - "private/tmp/[jboss]/server/default/conf/standardjaws.xml", - "private/tmp/[jboss]/server/default/conf/standardjboss.xml", - "private/tmp/[jboss]/server/default/conf/server.log.properties", - "private/tmp/[jboss]/server/default/deploy/jboss-logging.xml", - "tmp/[jboss]/server/default/conf/jboss-minimal.xml", - "tmp/[jboss]/server/default/conf/jboss-service.xml", - "tmp/[jboss]/server/default/conf/jndi.properties", - "tmp/[jboss]/server/default/conf/log4j.xml", - "tmp/[jboss]/server/default/conf/login-config.xml", - "tmp/[jboss]/server/default/conf/standardjaws.xml", - "tmp/[jboss]/server/default/conf/standardjboss.xml", - "tmp/[jboss]/server/default/conf/server.log.properties", - "tmp/[jboss]/server/default/deploy/jboss-logging.xml", - "program files/[jboss]/server/default/conf/jboss-minimal.xml", - "program files/[jboss]/server/default/conf/jboss-service.xml", - "program files/[jboss]/server/default/conf/jndi.properties", - "program files/[jboss]/server/default/conf/log4j.xml", - "program files/[jboss]/server/default/conf/login-config.xml", - "program files/[jboss]/server/default/conf/standardjaws.xml", - "program files/[jboss]/server/default/conf/standardjboss.xml", - "program files/[jboss]/server/default/conf/server.log.properties", - "program files/[jboss]/server/default/deploy/jboss-logging.xml", - "[jboss]/server/default/conf/jboss-minimal.xml", - "[jboss]/server/default/conf/jboss-service.xml", - "[jboss]/server/default/conf/jndi.properties", - "[jboss]/server/default/conf/log4j.xml", - "[jboss]/server/default/conf/login-config.xml", - "[jboss]/server/default/conf/standardjaws.xml", - "[jboss]/server/default/conf/standardjboss.xml", - "[jboss]/server/default/conf/server.log.properties", - "[jboss]/server/default/deploy/jboss-logging.xml", - "opt/[jboss]/server/default/log/server.log", - "opt/[jboss]/server/default/log/boot.log", - "usr/local/[jboss]/server/default/log/server.log", - "usr/local/[jboss]/server/default/log/boot.log", - "private/tmp/[jboss]/server/default/log/server.log", - "private/tmp/[jboss]/server/default/log/boot.log", - "tmp/[jboss]/server/default/log/server.log", - "tmp/[jboss]/server/default/log/boot.log", - "program files/[jboss]/server/default/log/server.log", - "program files/[jboss]/server/default/log/boot.log", - "[jboss]/server/default/log/server.log", - "[jboss]/server/default/log/boot.log", - "var/lighttpd.log", - "var/logs/access.log", - "usr/local/apache2/logs/lighttpd.error.log", - "usr/local/apache2/logs/lighttpd.log", - "usr/local/apache/logs/lighttpd.error.log", - "usr/local/apache/logs/lighttpd.log", - "usr/local/lighttpd/log/lighttpd.error.log", - "usr/local/lighttpd/log/access.log", - "usr/home/user/var/log/lighttpd.error.log", - "usr/home/user/var/log/apache.log", - "home/user/lighttpd/lighttpd.conf", - "usr/home/user/lighttpd/lighttpd.conf", - "etc/lighttpd/lighthttpd.conf", - "usr/local/etc/lighttpd.conf", - "usr/local/lighttpd/conf/lighttpd.conf", - "usr/local/etc/lighttpd.conf.new", - "var/www/.lighttpdpassword", - "logs/access_log", - "logs/error_log", - "etc/nginx/nginx.conf", - "usr/local/etc/nginx/nginx.conf", - "usr/local/nginx/conf/nginx.conf", - "usr/local/zeus/web/global.cfg", - "usr/local/zeus/web/log/errors", - "opt/lsws/conf/httpd_conf.xml", - "usr/local/lsws/conf/httpd_conf.xml", - "opt/lsws/logs/error.log", - "opt/lsws/logs/access.log", - "usr/local/lsws/logs/error.log", - "usr/local/logs/access.log", - "usr/local/samba/lib/log.user", - "usr/local/logs/samba.log", - "etc/samba/netlogon", - "etc/smbpasswd", - "etc/smb.conf", - "etc/samba/dhcp.conf", - "etc/samba/smb.conf", - "etc/samba/samba.conf", - "etc/samba/smb.conf.user", - "etc/samba/smbpasswd", - "etc/samba/smbusers", - "etc/samba/private/smbpasswd", - "usr/local/etc/smb.conf", - "usr/local/samba/lib/smb.conf.user", - "etc/dhcp3/dhclient.conf", - "etc/dhcp3/dhcpd.conf", - "etc/dhcp/dhclient.conf", - "program files/vidalia bundle/polipo/polipo.conf", - "etc/tor/tor-tsocks.conf", - "etc/stunnel/stunnel.conf", - "etc/tsocks.conf", - "etc/tinyproxy/tinyproxy.conf", - "etc/miredo-server.conf", - "etc/miredo.conf", - "etc/miredo/miredo-server.conf", - "etc/miredo/miredo.conf", - "etc/wicd/dhclient.conf.template.default", - "etc/wicd/manager-settings.conf", - "etc/wicd/wired-settings.conf", - "etc/wicd/wireless-settings.conf", - "etc/ipfw.rules", - "etc/ipfw.conf", - "etc/firewall.rules", - "winnt/system32/logfiles/firewall/pfirewall.log", - "winnt/system32/logfiles/firewall/pfirewall.log.old", - "windows/system32/logfiles/firewall/pfirewall.log", - "windows/system32/logfiles/firewall/pfirewall.log.old", - "etc/clamav/clamd.conf", - "etc/clamav/freshclam.conf", - "etc/x11/xorg.conf", - "etc/x11/xorg.conf-vesa", - "etc/x11/xorg.conf-vmware", - "etc/x11/xorg.conf.beforevmwaretoolsinstall", - "etc/x11/xorg.conf.orig", - "etc/bluetooth/input.conf", - "etc/bluetooth/main.conf", - "etc/bluetooth/network.conf", - "etc/bluetooth/rfcomm.conf", - "etc/bash_completion.d/debconf", - "root/.bash_logout", - "root/.bash_history", - "root/.bash_config", - "root/.bashrc", - "etc/bash.bashrc", - "var/adm/syslog", - "var/adm/sulog", - "var/adm/utmp", - "var/adm/utmpx", - "var/adm/wtmp", - "var/adm/wtmpx", - "var/adm/lastlog/username", - "usr/spool/lp/log", - "var/adm/lp/lpd-errs", - "usr/lib/cron/log", - "var/adm/loginlog", - "var/adm/pacct", - "var/adm/dtmp", - "var/adm/acct/sum/loginlog", - "var/adm/x0msgs", - "var/adm/crash/vmcore", - "var/adm/crash/unix", - "etc/newsyslog.conf", - "var/adm/qacct", - "var/adm/ras/errlog", - "var/adm/ras/bootlog", - "var/adm/cron/log", - "etc/utmp", - "etc/security/lastlog", - "etc/security/failedlogin", - "usr/spool/mqueue/syslog", - "var/adm/messages", - "var/adm/aculogs", - "var/adm/aculog", - "var/adm/vold.log", - "var/adm/log/asppp.log", - "var/lp/logs/lpsched", - "var/lp/logs/lpnet", - "var/lp/logs/requests", - "var/cron/log", - "var/saf/_log", - "var/saf/port/log", - "tmp/access.log", - "etc/sensors.conf", - "etc/sensors3.conf", - "etc/host.conf", - "etc/pam.conf", - "etc/resolv.conf", - "etc/apt/apt.conf", - "etc/inetd.conf", - "etc/syslog.conf", - "etc/sysctl.conf", - "etc/sysctl.d/10-console-messages.conf", - "etc/sysctl.d/10-network-security.conf", - "etc/sysctl.d/10-process-security.conf", - "etc/sysctl.d/wine.sysctl.conf", - "etc/security/access.conf", - "etc/security/group.conf", - "etc/security/limits.conf", - "etc/security/namespace.conf", - "etc/security/pam_env.conf", - "etc/security/sepermit.conf", - "etc/security/time.conf", - "etc/ssh/sshd_config", - "etc/adduser.conf", - "etc/deluser.conf", - "etc/avahi/avahi-daemon.conf", - "etc/ca-certificates.conf", - "etc/ca-certificates.conf.dpkg-old", - "etc/casper.conf", - "etc/chkrootkit.conf", - "etc/debconf.conf", - "etc/dns2tcpd.conf", - "etc/e2fsck.conf", - "etc/esound/esd.conf", - "etc/etter.conf", - "etc/fuse.conf", - "etc/foremost.conf", - "etc/hdparm.conf", - "etc/kernel-img.conf", - "etc/kernel-pkg.conf", - "etc/ld.so.conf", - "etc/ltrace.conf", - "etc/mail/sendmail.conf", - "etc/manpath.config", - "etc/kbd/config", - "etc/ldap/ldap.conf", - "etc/logrotate.conf", - "etc/mtools.conf", - "etc/smi.conf", - "etc/updatedb.conf", - "etc/pulse/client.conf", - "usr/share/adduser/adduser.conf", - "etc/hostname", - "etc/networks", - "etc/timezone", - "etc/modules", - "etc/passwd", - "etc/shadow", - "etc/fstab", - "etc/motd", - "etc/hosts", - "etc/group", - "etc/alias", - "etc/crontab", - "etc/crypttab", - "etc/exports", - "etc/mtab", - "etc/hosts.allow", - "etc/hosts.deny", - "etc/os-release", - "etc/password.master", - "etc/profile", - "etc/default/grub", - "etc/resolvconf/update-libc.d/sendmail", - "etc/inittab", - "etc/issue", - "etc/issue.net", - "etc/login.defs", - "etc/sudoers", - "etc/sysconfig/network-scripts/ifcfg-eth0", - "etc/redhat-release", - "etc/scw-release", - "etc/system-release-cpe", - "etc/debian_version", - "etc/fedora-release", - "etc/mandrake-release", - "etc/slackware-release", - "etc/suse-release", - "etc/security/group", - "etc/security/passwd", - "etc/security/user", - "etc/security/environ", - "etc/security/limits", - "etc/security/opasswd", - "boot/grub/grub.cfg", - "boot/grub/menu.lst", - "root/.ksh_history", - "root/.xauthority", - "usr/lib/security/mkuser.default", - "var/lib/squirrelmail/prefs/squirrelmail.log", - "etc/squirrelmail/apache.conf", - "etc/squirrelmail/config_local.php", - "etc/squirrelmail/default_pref", - "etc/squirrelmail/index.php", - "etc/squirrelmail/config_default.php", - "etc/squirrelmail/config.php", - "etc/squirrelmail/filters_setup.php", - "etc/squirrelmail/sqspell_config.php", - "etc/squirrelmail/config/config.php", - "etc/httpd/conf.d/squirrelmail.conf", - "usr/share/squirrelmail/config/config.php", - "private/etc/squirrelmail/config/config.php", - "srv/www/htdos/squirrelmail/config/config.php", - "var/www/squirrelmail/config/config.php", - "var/www/html/squirrelmail/config/config.php", - "var/www/html/squirrelmail-1.2.9/config/config.php", - "usr/share/squirrelmail/plugins/squirrel_logger/setup.php", - "usr/local/squirrelmail/www/readme", - "windows/system32/drivers/etc/hosts", - "windows/system32/drivers/etc/lmhosts.sam", - "windows/system32/drivers/etc/networks", - "windows/system32/drivers/etc/protocol", - "windows/system32/drivers/etc/services", - "/boot.ini", - "windows/debug/netsetup.log", - "windows/comsetup.log", - "windows/repair/setup.log", - "windows/setupact.log", - "windows/setupapi.log", - "windows/setuperr.log", - "windows/updspapi.log", - "windows/wmsetup.log", - "windows/windowsupdate.log", - "windows/odbc.ini", - "usr/local/psa/admin/htdocs/domains/databases/phpmyadmin/libraries/config.default.php", - "etc/apache2/conf.d/phpmyadmin.conf", - "etc/phpmyadmin/config.inc.php", - "etc/openldap/ldap.conf", - "etc/cups/acroread.conf", - "etc/cups/cupsd.conf", - "etc/cups/cupsd.conf.default", - "etc/cups/pdftops.conf", - "etc/cups/printers.conf", - "windows/system32/macromed/flash/flashinstall.log", - "windows/system32/macromed/flash/install.log", - "etc/cvs-cron.conf", - "etc/cvs-pserver.conf", - "etc/subversion/config", - "etc/modprobe.d/vmware-tools.conf", - "etc/updatedb.conf.beforevmwaretoolsinstall", - "etc/vmware-tools/config", - "etc/vmware-tools/tpvmlp.conf", - "etc/vmware-tools/vmware-tools-libraries.conf", - "var/log", - "var/log/sw-cp-server/error_log", - "var/log/sso/sso.log", - "var/log/dpkg.log", - "var/log/btmp", - "var/log/utmp", - "var/log/wtmp", - "var/log/mysql/mysql-bin.log", - "var/log/mysql/mysql-bin.index", - "var/log/mysql/data/mysql-bin.index", - "var/log/mysql.log", - "var/log/mysql.err", - "var/log/mysqlderror.log", - "var/log/mysql/mysql.log", - "var/log/mysql/mysql-slow.log", - "var/log/mysql-bin.index", - "var/log/data/mysql-bin.index", - "var/log/postgresql/postgresql.log", - "var/log/postgres/pg_backup.log", - "var/log/postgres/postgres.log", - "var/log/postgresql.log", - "var/log/pgsql/pgsql.log", - "var/log/postgresql/postgresql-8.1-main.log", - "var/log/postgresql/postgresql-8.3-main.log", - "var/log/postgresql/postgresql-8.4-main.log", - "var/log/postgresql/postgresql-9.0-main.log", - "var/log/postgresql/postgresql-9.1-main.log", - "var/log/pgsql8.log", - "var/log/postgresql/postgres.log", - "var/log/pgsql_log", - "var/log/postgresql/main.log", - "var/log/cron", - "var/log/postgres.log", - "var/log/proftpd", - "var/log/proftpd/xferlog.legacy", - "var/log/proftpd.access_log", - "var/log/proftpd.xferlog", - "var/log/vsftpd.log", - "var/log/xferlog", - "var/log/pure-ftpd/pure-ftpd.log", - "var/log/pureftpd.log", - "var/log/muddleftpd", - "var/log/muddleftpd.conf", - "var/log/ftp-proxy/ftp-proxy.log", - "var/log/ftp-proxy", - "var/log/ftplog", - "var/log/exim_mainlog", - "var/log/exim/mainlog", - "var/log/maillog", - "var/log/exim_paniclog", - "var/log/exim/paniclog", - "var/log/exim/rejectlog", - "var/log/exim_rejectlog", - "var/log/webmin/miniserv.log", - "var/log/httpd/access_log", - "var/log/httpd/error_log", - "var/log/httpd/access.log", - "var/log/httpd/error.log", - "var/log/apache/access_log", - "var/log/apache/access.log", - "var/log/apache/error_log", - "var/log/apache/error.log", - "var/log/apache2/access_log", - "var/log/apache2/access.log", - "var/log/apache2/error_log", - "var/log/apache2/error.log", - "var/log/access_log", - "var/log/access.log", - "var/log/error_log", - "var/log/error.log", - "var/log/tomcat6/catalina.out", - "var/log/lighttpd.error.log", - "var/log/lighttpd.access.log", - "var/logs/access.log", - "var/log/lighttpd/", - "var/log/lighttpd/error.log", - "var/log/lighttpd/access.www.log", - "var/log/lighttpd/error.www.log", - "var/log/lighttpd/access.log", - "var/log/lighttpd/{domain}/access.log", - "var/log/lighttpd/{domain}/error.log", - "var/log/nginx/access_log", - "var/log/nginx/error_log", - "var/log/nginx/access.log", - "var/log/nginx/error.log", - "var/log/nginx.access_log", - "var/log/nginx.error_log", - "var/log/samba/log.smbd", - "var/log/samba/log.nmbd", - "var/log/samba.log", - "var/log/samba.log1", - "var/log/samba.log2", - "var/log/log.smb", - "var/log/ipfw.log", - "var/log/ipfw", - "var/log/ipfw/ipfw.log", - "var/log/ipfw.today", - "var/log/poplog", - "var/log/authlog", - "var/log/news.all", - "var/log/news/news.all", - "var/log/news/news.crit", - "var/log/news/news.err", - "var/log/news/news.notice", - "var/log/news/suck.err", - "var/log/news/suck.notice", - "var/log/messages", - "var/log/messages.1", - "var/log/user.log", - "var/log/user.log.1", - "var/log/auth.log", - "var/log/pm-powersave.log", - "var/log/xorg.0.log", - "var/log/daemon.log", - "var/log/daemon.log.1", - "var/log/kern.log", - "var/log/kern.log.1", - "var/log/mail.err", - "var/log/mail.info", - "var/log/mail.warn", - "var/log/ufw.log", - "var/log/boot.log", - "var/log/syslog", - "var/log/syslog.1", - "var/log/squirrelmail.log", - "var/log/apache2/squirrelmail.log", - "var/log/apache2/squirrelmail.err.log", - "var/log/mail.log", - "var/log/vmware/hostd.log", - "var/log/vmware/hostd-1.log", - "/wp-config.php", - "/wp-config.bak", - "/wp-config.old", - "/wp-config.temp", - "/wp-config.tmp", - "/wp-config.txt", - "/config.yml", - "/config_dev.yml", - "/config_prod.yml", - "/config_test.yml", - "/parameters.yml", - "/routing.yml", - "/security.yml", - "/services.yml", - "sites/default/default.settings.php", - "sites/default/settings.php", - "sites/default/settings.local.php", - "app/etc/local.xml", - "/sftp-config.json", - "/web.config", - "includes/config.php", - "includes/configure.php", - "/config.inc.php", - "/localsettings.php", - "inc/config.php", - "typo3conf/localconf.php", - "config/app.php", - "config/custom.php", - "config/database.php", - "/configuration.php", - "/config.php", - "var/mail/www-data", - "etc/network/", - "etc/init/", - "inetpub/wwwroot/global.asa", - "system32/inetsrv/config/applicationhost.config", - "system32/inetsrv/config/administration.config", - "system32/inetsrv/config/redirection.config", - "system32/config/default", - "system32/config/sam", - "system32/config/system", - "system32/config/software", - "winnt/repair/sam._", - "/package.json", - "/package-lock.json", - "/gruntfile.js", - "/npm-debug.log", - "/ormconfig.json", - "/tsconfig.json", - "/webpack.config.js", - "/yarn.lock", - "proc/0", - "proc/1", - "proc/2", - "proc/3", - "proc/4", - "proc/5", - "proc/6", - "proc/7", - "proc/8", - "proc/9", - "proc/acpi", - "proc/asound", - "proc/bootconfig", - "proc/buddyinfo", - "proc/bus", - "proc/cgroups", - "proc/cmdline", - "proc/config.gz", - "proc/consoles", - "proc/cpuinfo", - "proc/crypto", - "proc/devices", - "proc/diskstats", - "proc/dma", - "proc/docker", - "proc/driver", - "proc/dynamic_debug", - "proc/execdomains", - "proc/fb", - "proc/filesystems", - "proc/fs", - "proc/interrupts", - "proc/iomem", - "proc/ioports", - "proc/ipmi", - "proc/irq", - "proc/kallsyms", - "proc/kcore", - "proc/keys", - "proc/keys", - "proc/key-users", - "proc/kmsg", - "proc/kpagecgroup", - "proc/kpagecount", - "proc/kpageflags", - "proc/latency_stats", - "proc/loadavg", - "proc/locks", - "proc/mdstat", - "proc/meminfo", - "proc/misc", - "proc/modules", - "proc/mounts", - "proc/mpt", - "proc/mtd", - "proc/mtrr", - "proc/net", - "proc/net/tcp", - "proc/net/udp", - "proc/pagetypeinfo", - "proc/partitions", - "proc/pressure", - "proc/sched_debug", - "proc/schedstat", - "proc/scsi", - "proc/self", - "proc/self/cmdline", - "proc/self/environ", - "proc/self/fd/0", - "proc/self/fd/1", - "proc/self/fd/10", - "proc/self/fd/11", - "proc/self/fd/12", - "proc/self/fd/13", - "proc/self/fd/14", - "proc/self/fd/15", - "proc/self/fd/2", - "proc/self/fd/3", - "proc/self/fd/4", - "proc/self/fd/5", - "proc/self/fd/6", - "proc/self/fd/7", - "proc/self/fd/8", - "proc/self/fd/9", - "proc/self/mounts", - "proc/self/stat", - "proc/self/status", - "proc/slabinfo", - "proc/softirqs", - "proc/stat", - "proc/swaps", - "proc/sys", - "proc/sysrq-trigger", - "proc/sysvipc", - "proc/thread-self", - "proc/timer_list", - "proc/timer_stats", - "proc/tty", - "proc/uptime", - "proc/version", - "proc/version_signature", - "proc/vmallocinfo", - "proc/vmstat", - "proc/zoneinfo", - "sys/block", - "sys/bus", - "sys/class", - "sys/dev", - "sys/devices", - "sys/firmware", - "sys/fs", - "sys/hypervisor", - "sys/kernel", - "sys/module", - "sys/power", - "windows\\win.ini", - "default\\ntuser.dat", - "/var/run/secrets/kubernetes.io/serviceaccount" - ], - "options": { - "enforce_word_boundary": true - } - }, - "operator": "phrase_match" - } - ], - "transformers": [ - "lowercase", - "normalizePath" - ] - }, - { - "id": "crs-931-110", - "name": "RFI: Common RFI Vulnerable Parameter Name used w/ URL Payload", - "tags": { - "type": "rfi", - "crs_id": "931110", - "category": "attack_attempt", - "cwe": "98", - "capec": "1000/152/175/253/193", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - } - ], - "regex": "(?:\\binclude\\s*\\([^)]*|mosConfig_absolute_path|_CONF\\[path\\]|_SERVER\\[DOCUMENT_ROOT\\]|GALLERY_BASEDIR|path\\[docroot\\]|appserv_root|config\\[root_dir\\])=(?:file|ftps?|https?)://", - "options": { - "min_length": 15 - } - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "crs-931-120", - "name": "RFI: URL Payload Used w/Trailing Question Mark Character (?)", - "tags": { - "type": "rfi", - "crs_id": "931120", - "category": "attack_attempt", - "cwe": "98", - "capec": "1000/152/175/253/193" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "^(?i:file|ftps?)://.*?\\?+$", - "options": { - "case_sensitive": true, - "min_length": 4 - } - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "crs-932-160", - "name": "Remote Command Execution: Unix Shell Code Found", - "tags": { - "type": "command_injection", - "crs_id": "932160", - "category": "attack_attempt", - "cwe": "77", - "capec": "1000/152/248/88", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "options": { - "enforce_word_boundary": true - }, - "list": [ - "${cdpath}", - "${dirstack}", - "${home}", - "${hostname}", - "${ifs}", - "${oldpwd}", - "${ostype}", - "${path}", - "${pwd}", - "$cdpath", - "$dirstack", - "$home", - "$hostname", - "$ifs", - "$oldpwd", - "$ostype", - "$pwd", - "dev/fd/", - "dev/null", - "dev/stderr", - "dev/stdin", - "dev/stdout", - "dev/tcp/", - "dev/udp/", - "dev/zero", - "etc/master.passwd", - "etc/pwd.db", - "etc/shells", - "etc/spwd.db", - "proc/self/", - "bin/7z", - "bin/7za", - "bin/7zr", - "bin/ab", - "bin/agetty", - "bin/ansible-playbook", - "bin/apt", - "bin/apt-get", - "bin/ar", - "bin/aria2c", - "bin/arj", - "bin/arp", - "bin/as", - "bin/ascii-xfr", - "bin/ascii85", - "bin/ash", - "bin/aspell", - "bin/at", - "bin/atobm", - "bin/awk", - "bin/base32", - "bin/base64", - "bin/basenc", - "bin/bash", - "bin/bpftrace", - "bin/bridge", - "bin/bundler", - "bin/bunzip2", - "bin/busctl", - "bin/busybox", - "bin/byebug", - "bin/bzcat", - "bin/bzcmp", - "bin/bzdiff", - "bin/bzegrep", - "bin/bzexe", - "bin/bzfgrep", - "bin/bzgrep", - "bin/bzip2", - "bin/bzip2recover", - "bin/bzless", - "bin/bzmore", - "bin/bzz", - "bin/c89", - "bin/c99", - "bin/cancel", - "bin/capsh", - "bin/cat", - "bin/cc", - "bin/certbot", - "bin/check_by_ssh", - "bin/check_cups", - "bin/check_log", - "bin/check_memory", - "bin/check_raid", - "bin/check_ssl_cert", - "bin/check_statusfile", - "bin/chmod", - "bin/choom", - "bin/chown", - "bin/chroot", - "bin/clang", - "bin/clang++", - "bin/cmp", - "bin/cobc", - "bin/column", - "bin/comm", - "bin/composer", - "bin/core_perl/zipdetails", - "bin/cowsay", - "bin/cowthink", - "bin/cp", - "bin/cpan", - "bin/cpio", - "bin/cpulimit", - "bin/crash", - "bin/crontab", - "bin/csh", - "bin/csplit", - "bin/csvtool", - "bin/cupsfilter", - "bin/curl", - "bin/cut", - "bin/dash", - "bin/date", - "bin/dd", - "bin/dev/fd/", - "bin/dev/null", - "bin/dev/stderr", - "bin/dev/stdin", - "bin/dev/stdout", - "bin/dev/tcp/", - "bin/dev/udp/", - "bin/dev/zero", - "bin/dialog", - "bin/diff", - "bin/dig", - "bin/dmesg", - "bin/dmidecode", - "bin/dmsetup", - "bin/dnf", - "bin/docker", - "bin/dosbox", - "bin/dpkg", - "bin/du", - "bin/dvips", - "bin/easy_install", - "bin/eb", - "bin/echo", - "bin/ed", - "bin/efax", - "bin/emacs", - "bin/env", - "bin/eqn", - "bin/es", - "bin/esh", - "bin/etc/group", - "bin/etc/master.passwd", - "bin/etc/passwd", - "bin/etc/pwd.db", - "bin/etc/shadow", - "bin/etc/shells", - "bin/etc/spwd.db", - "bin/ex", - "bin/exiftool", - "bin/expand", - "bin/expect", - "bin/expr", - "bin/facter", - "bin/fetch", - "bin/file", - "bin/find", - "bin/finger", - "bin/fish", - "bin/flock", - "bin/fmt", - "bin/fold", - "bin/fping", - "bin/ftp", - "bin/gawk", - "bin/gcc", - "bin/gcore", - "bin/gdb", - "bin/gem", - "bin/genie", - "bin/genisoimage", - "bin/ghc", - "bin/ghci", - "bin/gimp", - "bin/ginsh", - "bin/git", - "bin/grc", - "bin/grep", - "bin/gtester", - "bin/gunzip", - "bin/gzexe", - "bin/gzip", - "bin/hd", - "bin/head", - "bin/hexdump", - "bin/highlight", - "bin/hping3", - "bin/iconv", - "bin/id", - "bin/iftop", - "bin/install", - "bin/ionice", - "bin/ip", - "bin/irb", - "bin/ispell", - "bin/jjs", - "bin/join", - "bin/journalctl", - "bin/jq", - "bin/jrunscript", - "bin/knife", - "bin/ksh", - "bin/ksshell", - "bin/latex", - "bin/ld", - "bin/ldconfig", - "bin/less", - "bin/lftp", - "bin/ln", - "bin/loginctl", - "bin/logsave", - "bin/look", - "bin/lp", - "bin/ls", - "bin/ltrace", - "bin/lua", - "bin/lualatex", - "bin/luatex", - "bin/lwp-download", - "bin/lwp-request", - "bin/lz", - "bin/lz4", - "bin/lz4c", - "bin/lz4cat", - "bin/lzcat", - "bin/lzcmp", - "bin/lzdiff", - "bin/lzegrep", - "bin/lzfgrep", - "bin/lzgrep", - "bin/lzless", - "bin/lzma", - "bin/lzmadec", - "bin/lzmainfo", - "bin/lzmore", - "bin/mail", - "bin/make", - "bin/man", - "bin/mawk", - "bin/mkfifo", - "bin/mknod", - "bin/more", - "bin/mosquitto", - "bin/mount", - "bin/msgattrib", - "bin/msgcat", - "bin/msgconv", - "bin/msgfilter", - "bin/msgmerge", - "bin/msguniq", - "bin/mtr", - "bin/mv", - "bin/mysql", - "bin/nano", - "bin/nasm", - "bin/nawk", - "bin/nc", - "bin/ncat", - "bin/neofetch", - "bin/nice", - "bin/nl", - "bin/nm", - "bin/nmap", - "bin/node", - "bin/nohup", - "bin/npm", - "bin/nroff", - "bin/nsenter", - "bin/octave", - "bin/od", - "bin/openssl", - "bin/openvpn", - "bin/openvt", - "bin/opkg", - "bin/paste", - "bin/pax", - "bin/pdb", - "bin/pdflatex", - "bin/pdftex", - "bin/pdksh", - "bin/perf", - "bin/perl", - "bin/pg", - "bin/php", - "bin/php-cgi", - "bin/php5", - "bin/php7", - "bin/pic", - "bin/pico", - "bin/pidstat", - "bin/pigz", - "bin/pip", - "bin/pkexec", - "bin/pkg", - "bin/pr", - "bin/printf", - "bin/proc/self/", - "bin/pry", - "bin/ps", - "bin/psed", - "bin/psftp", - "bin/psql", - "bin/ptx", - "bin/puppet", - "bin/pxz", - "bin/python", - "bin/python2", - "bin/python3", - "bin/rake", - "bin/rbash", - "bin/rc", - "bin/readelf", - "bin/red", - "bin/redcarpet", - "bin/restic", - "bin/rev", - "bin/rlogin", - "bin/rlwrap", - "bin/rpm", - "bin/rpmquery", - "bin/rsync", - "bin/ruby", - "bin/run-mailcap", - "bin/run-parts", - "bin/rview", - "bin/rvim", - "bin/sash", - "bin/sbin/capsh", - "bin/sbin/logsave", - "bin/sbin/service", - "bin/sbin/start-stop-daemon", - "bin/scp", - "bin/screen", - "bin/script", - "bin/sed", - "bin/service", - "bin/setarch", - "bin/sftp", - "bin/sg", - "bin/sh", - "bin/shuf", - "bin/sleep", - "bin/slsh", - "bin/smbclient", - "bin/snap", - "bin/socat", - "bin/soelim", - "bin/sort", - "bin/split", - "bin/sqlite3", - "bin/ss", - "bin/ssh", - "bin/ssh-keygen", - "bin/ssh-keyscan", - "bin/sshpass", - "bin/start-stop-daemon", - "bin/stdbuf", - "bin/strace", - "bin/strings", - "bin/su", - "bin/sysctl", - "bin/systemctl", - "bin/systemd-resolve", - "bin/tac", - "bin/tail", - "bin/tar", - "bin/task", - "bin/taskset", - "bin/tbl", - "bin/tclsh", - "bin/tcpdump", - "bin/tcsh", - "bin/tee", - "bin/telnet", - "bin/tex", - "bin/tftp", - "bin/tic", - "bin/time", - "bin/timedatectl", - "bin/timeout", - "bin/tmux", - "bin/top", - "bin/troff", - "bin/tshark", - "bin/ul", - "bin/uname", - "bin/uncompress", - "bin/unexpand", - "bin/uniq", - "bin/unlz4", - "bin/unlzma", - "bin/unpigz", - "bin/unrar", - "bin/unshare", - "bin/unxz", - "bin/unzip", - "bin/unzstd", - "bin/update-alternatives", - "bin/uudecode", - "bin/uuencode", - "bin/valgrind", - "bin/vi", - "bin/view", - "bin/vigr", - "bin/vim", - "bin/vimdiff", - "bin/vipw", - "bin/virsh", - "bin/volatility", - "bin/wall", - "bin/watch", - "bin/wc", - "bin/wget", - "bin/whiptail", - "bin/who", - "bin/whoami", - "bin/whois", - "bin/wireshark", - "bin/wish", - "bin/xargs", - "bin/xelatex", - "bin/xetex", - "bin/xmodmap", - "bin/xmore", - "bin/xpad", - "bin/xxd", - "bin/xz", - "bin/xzcat", - "bin/xzcmp", - "bin/xzdec", - "bin/xzdiff", - "bin/xzegrep", - "bin/xzfgrep", - "bin/xzgrep", - "bin/xzless", - "bin/xzmore", - "bin/yarn", - "bin/yelp", - "bin/yes", - "bin/yum", - "bin/zathura", - "bin/zip", - "bin/zipcloak", - "bin/zipcmp", - "bin/zipdetails", - "bin/zipgrep", - "bin/zipinfo", - "bin/zipmerge", - "bin/zipnote", - "bin/zipsplit", - "bin/ziptool", - "bin/zsh", - "bin/zsoelim", - "bin/zstd", - "bin/zstdcat", - "bin/zstdgrep", - "bin/zstdless", - "bin/zstdmt", - "bin/zypper" - ] - }, - "operator": "phrase_match" - } - ], - "transformers": [ - "lowercase", - "cmdLine" - ] - }, - { - "id": "crs-932-171", - "name": "Remote Command Execution: Shellshock (CVE-2014-6271)", - "tags": { - "type": "command_injection", - "crs_id": "932171", - "category": "attack_attempt", - "cwe": "77", - "capec": "1000/152/248/88", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "server.request.headers.no_cookies" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "^\\(\\s*\\)\\s+{", - "options": { - "case_sensitive": true, - "min_length": 4 - } - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "crs-932-180", - "name": "Restricted File Upload Attempt", - "tags": { - "type": "command_injection", - "crs_id": "932180", - "category": "attack_attempt", - "cwe": "706", - "capec": "1000/225/122/17/177", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "x-filename" - ] - }, - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "x_filename" - ] - }, - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "x-file-name" - ] - } - ], - "list": [ - ".htaccess", - ".htdigest", - ".htpasswd", - "wp-config.php", - "config.yml", - "config_dev.yml", - "config_prod.yml", - "config_test.yml", - "parameters.yml", - "routing.yml", - "security.yml", - "services.yml", - "default.settings.php", - "settings.php", - "settings.local.php", - "local.xml", - ".env" - ], - "options": { - "enforce_word_boundary": true - } - }, - "operator": "phrase_match" - } - ], - "transformers": [ - "lowercase" - ] - }, - { - "id": "crs-933-111", - "name": "PHP Injection Attack: PHP Script File Upload Found", - "tags": { - "type": "unrestricted_file_upload", - "crs_id": "933111", - "category": "attack_attempt", - "cwe": "434", - "capec": "1000/225/122/17/650", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "x-filename" - ] - }, - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "x_filename" - ] - }, - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "x.filename" - ] - }, - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "x-file-name" - ] - } - ], - "regex": ".*\\.(?:php\\d*|phtml)\\..*$", - "options": { - "case_sensitive": true, - "min_length": 5 - } - }, - "operator": "match_regex" - } - ], - "transformers": [ - "lowercase" - ] - }, - { - "id": "crs-933-130", - "name": "PHP Injection Attack: Global Variables Found", - "tags": { - "type": "php_code_injection", - "crs_id": "933130", - "category": "attack_attempt", - "cwe": "94", - "capec": "1000/225/122/17/650", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "options": { - "enforce_word_boundary": true - }, - "list": [ - "$globals", - "$_cookie", - "$_env", - "$_files", - "$_get", - "$_post", - "$_request", - "$_server", - "$_session", - "$argc", - "$argv", - "$http_\\u200bresponse_\\u200bheader", - "$php_\\u200berrormsg", - "$http_cookie_vars", - "$http_env_vars", - "$http_get_vars", - "$http_post_files", - "$http_post_vars", - "$http_raw_post_data", - "$http_request_vars", - "$http_server_vars" - ] - }, - "operator": "phrase_match" - } - ], - "transformers": [ - "lowercase" - ] - }, - { - "id": "crs-933-131", - "name": "PHP Injection Attack: HTTP Headers Values Found", - "tags": { - "type": "php_code_injection", - "crs_id": "933131", - "category": "attack_attempt", - "cwe": "94", - "capec": "1000/225/122/17/650" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "(?:HTTP_(?:ACCEPT(?:_(?:ENCODING|LANGUAGE|CHARSET))?|(?:X_FORWARDED_FO|REFERE)R|(?:USER_AGEN|HOS)T|CONNECTION|KEEP_ALIVE)|PATH_(?:TRANSLATED|INFO)|ORIG_PATH_INFO|QUERY_STRING|REQUEST_URI|AUTH_TYPE)", - "options": { - "case_sensitive": true, - "min_length": 9 - } - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "crs-933-140", - "name": "PHP Injection Attack: I/O Stream Found", - "tags": { - "type": "php_code_injection", - "crs_id": "933140", - "category": "attack_attempt", - "cwe": "94", - "capec": "1000/225/122/17/650", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "php://(?:std(?:in|out|err)|(?:in|out)put|fd|memory|temp|filter)", - "options": { - "min_length": 8 - } - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "crs-933-150", - "name": "PHP Injection Attack: High-Risk PHP Function Name Found", - "tags": { - "type": "php_code_injection", - "crs_id": "933150", - "category": "attack_attempt", - "cwe": "94", - "capec": "1000/225/122/17/650", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "list": [ - "__halt_compiler", - "apache_child_terminate", - "base64_decode", - "bzdecompress", - "call_user_func", - "call_user_func_array", - "call_user_method", - "call_user_method_array", - "convert_uudecode", - "file_get_contents", - "file_put_contents", - "fsockopen", - "get_class_methods", - "get_class_vars", - "get_defined_constants", - "get_defined_functions", - "get_defined_vars", - "gzdecode", - "gzinflate", - "gzuncompress", - "include_once", - "invokeargs", - "pcntl_exec", - "pcntl_fork", - "pfsockopen", - "posix_getcwd", - "posix_getpwuid", - "posix_getuid", - "posix_uname", - "reflectionfunction", - "require_once", - "shell_exec", - "str_rot13", - "sys_get_temp_dir", - "wp_remote_fopen", - "wp_remote_get", - "wp_remote_head", - "wp_remote_post", - "wp_remote_request", - "wp_safe_remote_get", - "wp_safe_remote_head", - "wp_safe_remote_post", - "wp_safe_remote_request", - "zlib_decode" - ], - "options": { - "enforce_word_boundary": true - } - }, - "operator": "phrase_match" - } - ], - "transformers": [ - "lowercase" - ] - }, - { - "id": "crs-933-160", - "name": "PHP Injection Attack: High-Risk PHP Function Call Found", - "tags": { - "type": "php_code_injection", - "crs_id": "933160", - "category": "attack_attempt", - "cwe": "94", - "capec": "1000/225/122/17/650" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "\\b(?:s(?:e(?:t(?:_(?:e(?:xception|rror)_handler|magic_quotes_runtime|include_path)|defaultstub)|ssion_s(?:et_save_handler|tart))|qlite_(?:(?:(?:unbuffered|single|array)_)?query|create_(?:aggregate|function)|p?open|exec)|tr(?:eam_(?:context_create|socket_client)|ipc?slashes|rev)|implexml_load_(?:string|file)|ocket_c(?:onnect|reate)|h(?:ow_sourc|a1_fil)e|pl_autoload_register|ystem)|p(?:r(?:eg_(?:replace(?:_callback(?:_array)?)?|match(?:_all)?|split)|oc_(?:(?:terminat|clos|nic)e|get_status|open)|int_r)|o(?:six_(?:get(?:(?:e[gu]|g)id|login|pwnam)|mk(?:fifo|nod)|ttyname|kill)|pen)|hp(?:_(?:strip_whitespac|unam)e|version|info)|g_(?:(?:execut|prepar)e|connect|query)|a(?:rse_(?:ini_file|str)|ssthru)|utenv)|r(?:unkit_(?:function_(?:re(?:defin|nam)e|copy|add)|method_(?:re(?:defin|nam)e|copy|add)|constant_(?:redefine|add))|e(?:(?:gister_(?:shutdown|tick)|name)_function|ad(?:(?:gz)?file|_exif_data|dir))|awurl(?:de|en)code)|i(?:mage(?:createfrom(?:(?:jpe|pn)g|x[bp]m|wbmp|gif)|(?:jpe|pn)g|g(?:d2?|if)|2?wbmp|xbm)|s_(?:(?:(?:execut|write?|read)ab|fi)le|dir)|ni_(?:get(?:_all)?|set)|terator_apply|ptcembed)|g(?:et(?:_(?:c(?:urrent_use|fg_va)r|meta_tags)|my(?:[gpu]id|inode)|(?:lastmo|cw)d|imagesize|env)|z(?:(?:(?:defla|wri)t|encod|fil)e|compress|open|read)|lob)|a(?:rray_(?:u(?:intersect(?:_u?assoc)?|diff(?:_u?assoc)?)|intersect_u(?:assoc|key)|diff_u(?:assoc|key)|filter|reduce|map)|ssert(?:_options)?|tob)|h(?:tml(?:specialchars(?:_decode)?|_entity_decode|entities)|(?:ash(?:_(?:update|hmac))?|ighlight)_file|e(?:ader_register_callback|x2bin))|f(?:i(?:le(?:(?:[acm]tim|inod)e|(?:_exist|perm)s|group)?|nfo_open)|tp_(?:nb_(?:ge|pu)|connec|ge|pu)t|(?:unction_exis|pu)ts|write|open)|o(?:b_(?:get_(?:c(?:ontents|lean)|flush)|end_(?:clean|flush)|clean|flush|start)|dbc_(?:result(?:_all)?|exec(?:ute)?|connect)|pendir)|m(?:b_(?:ereg(?:_(?:replace(?:_callback)?|match)|i(?:_replace)?)?|parse_str)|(?:ove_uploaded|d5)_file|ethod_exists|ysql_query|kdir)|e(?:x(?:if_(?:t(?:humbnail|agname)|imagetype|read_data)|ec)|scapeshell(?:arg|cmd)|rror_reporting|val)|c(?:url_(?:file_create|exec|init)|onvert_uuencode|reate_function|hr)|u(?:n(?:serialize|pack)|rl(?:de|en)code|[ak]?sort)|b(?:(?:son_(?:de|en)|ase64_en)code|zopen|toa)|(?:json_(?:de|en)cod|debug_backtrac|tmpfil)e|var_dump)(?:\\s|/\\*.*\\*/|//.*|#.*|\\\"|')*\\((?:(?:\\s|/\\*.*\\*/|//.*|#.*)*(?:\\$\\w+|[A-Z\\d]\\w*|\\w+\\(.*\\)|\\\\?\"(?:[^\"]|\\\\\"|\"\"|\"\\+\")*\\\\?\"|\\\\?'(?:[^']|''|'\\+')*\\\\?')(?:\\s|/\\*.*\\*/|//.*|#.*)*(?:(?:::|\\.|->)(?:\\s|/\\*.*\\*/|//.*|#.*)*\\w+(?:\\(.*\\))?)?,)*(?:(?:\\s|/\\*.*\\*/|//.*|#.*)*(?:\\$\\w+|[A-Z\\d]\\w*|\\w+\\(.*\\)|\\\\?\"(?:[^\"]|\\\\\"|\"\"|\"\\+\")*\\\\?\"|\\\\?'(?:[^']|''|'\\+')*\\\\?')(?:\\s|/\\*.*\\*/|//.*|#.*)*(?:(?:::|\\.|->)(?:\\s|/\\*.*\\*/|//.*|#.*)*\\w+(?:\\(.*\\))?)?)?\\)", - "options": { - "case_sensitive": true, - "min_length": 5 - } - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "crs-933-170", - "name": "PHP Injection Attack: Serialized Object Injection", - "tags": { - "type": "php_code_injection", - "crs_id": "933170", - "category": "attack_attempt", - "cwe": "502", - "capec": "1000/152/586", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies" - }, - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "[oOcC]:\\d+:\\\".+?\\\":\\d+:{[\\W\\w]*}", - "options": { - "case_sensitive": true, - "min_length": 12 - } - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "crs-933-200", - "name": "PHP Injection Attack: Wrapper scheme detected", - "tags": { - "type": "php_code_injection", - "crs_id": "933200", - "category": "attack_attempt", - "cwe": "502", - "capec": "1000/152/586" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "(?:(?:bzip|ssh)2|z(?:lib|ip)|(?:ph|r)ar|expect|glob|ogg)://", - "options": { - "case_sensitive": true, - "min_length": 6 - } - }, - "operator": "match_regex" - } - ], - "transformers": [ - "removeNulls" - ] - }, - { - "id": "crs-934-100", - "name": "Node.js Injection Attack 1/2", - "tags": { - "type": "js_code_injection", - "crs_id": "934100", - "category": "attack_attempt", - "cwe": "94", - "capec": "1000/152/242" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "\\b(?:(?:l(?:(?:utimes|chmod)(?:Sync)?|(?:stat|ink)Sync)|w(?:rite(?:(?:File|v)(?:Sync)?|Sync)|atchFile)|u(?:n(?:watchFile|linkSync)|times(?:Sync)?)|s(?:(?:ymlink|tat)Sync|pawn(?:File|Sync))|ex(?:ec(?:File(?:Sync)?|Sync)|istsSync)|a(?:ppendFile|ccess)(?:Sync)?|(?:Caveat|Inode)s|open(?:dir)?Sync|new\\s+Function|Availability|\\beval)\\s*\\(|m(?:ain(?:Module\\s*(?:\\W*\\s*(?:constructor|require)|\\[)|\\s*(?:\\W*\\s*(?:constructor|require)|\\[))|kd(?:temp(?:Sync)?|irSync)\\s*\\(|odule\\.exports\\s*=)|c(?:(?:(?:h(?:mod|own)|lose)Sync|reate(?:Write|Read)Stream|p(?:Sync)?)\\s*\\(|o(?:nstructor\\s*(?:\\W*\\s*_load|\\[)|pyFile(?:Sync)?\\s*\\())|f(?:(?:(?:s(?:(?:yncS)?|tatS)|datas(?:yncS)?)ync|ch(?:mod|own)(?:Sync)?)\\s*\\(|u(?:nction\\s*\\(\\s*\\)\\s*{|times(?:Sync)?\\s*\\())|r(?:e(?:(?:ad(?:(?:File|link|dir)?Sync|v(?:Sync)?)|nameSync)\\s*\\(|quire\\s*(?:\\W*\\s*main|\\[))|m(?:Sync)?\\s*\\()|process\\s*(?:\\W*\\s*(?:mainModule|binding)|\\[)|t(?:his\\.constructor|runcateSync\\s*\\()|_(?:\\$\\$ND_FUNC\\$\\$_|_js_function)|global\\s*(?:\\W*\\s*process|\\[)|String\\s*\\.\\s*fromCharCode|binding\\s*\\[)", - "options": { - "case_sensitive": true, - "min_length": 3 - } - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "crs-934-101", - "name": "Node.js Injection Attack 2/2", - "tags": { - "type": "js_code_injection", - "crs_id": "934101", - "category": "attack_attempt", - "confidence": "1", - "cwe": "94", - "capec": "1000/152/242" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "\\b(?:w(?:atch|rite)|(?:spaw|ope)n|exists|close|fork|read)\\s*\\(", - "options": { - "case_sensitive": true, - "min_length": 5 - } - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "crs-941-110", - "name": "XSS Filter - Category 1: Script Tag Vector", - "tags": { - "type": "xss", - "crs_id": "941110", - "category": "attack_attempt", - "cwe": "80", - "capec": "1000/152/242/63/591", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - }, - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "referer" - ] - }, - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "]*>[\\s\\S]*?", - "options": { - "case_sensitive": false, - "min_length": 8 - } - }, - "operator": "match_regex" - } - ], - "transformers": [ - "removeNulls", - "urlDecodeUni" - ] - }, - { - "id": "crs-941-120", - "name": "XSS Filter - Category 2: Event Handler Vector", - "tags": { - "type": "xss", - "crs_id": "941120", - "category": "attack_attempt", - "cwe": "83", - "capec": "1000/152/242/63/591/243", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - }, - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "referer" - ] - }, - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "\\bon(?:d(?:r(?:ag(?:en(?:ter|d)|leave|start|over)?|op)|urationchange|blclick)|s(?:e(?:ek(?:ing|ed)|arch|lect)|u(?:spend|bmit)|talled|croll|how)|m(?:ouse(?:(?:lea|mo)ve|o(?:ver|ut)|enter|down|up)|essage)|p(?:a(?:ge(?:hide|show)|(?:st|us)e)|lay(?:ing)?|rogress|aste|ointer(?:cancel|down|enter|leave|move|out|over|rawupdate|up))|c(?:anplay(?:through)?|o(?:ntextmenu|py)|hange|lick|ut)|a(?:nimation(?:iteration|start|end)|(?:fterprin|bor)t|uxclick|fterscriptexecute)|t(?:o(?:uch(?:cancel|start|move|end)|ggle)|imeupdate)|f(?:ullscreen(?:change|error)|ocus(?:out|in)?|inish)|(?:(?:volume|hash)chang|o(?:ff|n)lin)e|b(?:efore(?:unload|print)|lur)|load(?:ed(?:meta)?data|start|end)?|r(?:es(?:ize|et)|atechange)|key(?:press|down|up)|w(?:aiting|heel)|in(?:valid|put)|e(?:nded|rror)|unload)[\\s\\x0B\\x09\\x0C\\x3B\\x2C\\x28\\x3B]*?=[^=]", - "options": { - "min_length": 8 - } - }, - "operator": "match_regex" - } - ], - "transformers": [ - "removeNulls", - "urlDecodeUni" - ] - }, - { - "id": "crs-941-140", - "name": "XSS Filter - Category 4: Javascript URI Vector", - "tags": { - "type": "xss", - "crs_id": "941140", - "category": "attack_attempt", - "cwe": "84", - "capec": "1000/152/242/63/591/244", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - }, - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "referer" - ] - }, - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "[a-z]+=(?:[^:=]+:.+;)*?[^:=]+:url\\(javascript", - "options": { - "min_length": 18 - } - }, - "operator": "match_regex" - } - ], - "transformers": [ - "removeNulls", - "urlDecodeUni" - ] - }, - { - "id": "crs-941-170", - "name": "NoScript XSS InjectionChecker: Attribute Injection", - "tags": { - "type": "xss", - "crs_id": "941170", - "category": "attack_attempt", - "cwe": "83", - "capec": "1000/152/242/63/591/243", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - }, - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "referer" - ] - }, - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "(?:\\W|^)(?:javascript:(?:[\\s\\S]+[=\\x5c\\(\\[\\.<]|[\\s\\S]*?(?:\\bname\\b|\\x5c[ux]\\d)))|@\\W*?i\\W*?m\\W*?p\\W*?o\\W*?r\\W*?t\\W*?(?:/\\*[\\s\\S]*?)?(?:[\\\"']|\\W*?u\\W*?r\\W*?l[\\s\\S]*?\\()|[^-]*?-\\W*?m\\W*?o\\W*?z\\W*?-\\W*?b\\W*?i\\W*?n\\W*?d\\W*?i\\W*?n\\W*?g[^:]*?:\\W*?u\\W*?r\\W*?l[\\s\\S]*?\\(", - "options": { - "min_length": 6 - } - }, - "operator": "match_regex" - } - ], - "transformers": [ - "removeNulls", - "urlDecodeUni" - ] - }, - { - "id": "crs-941-180", - "name": "Node-Validator Deny List Keywords", - "tags": { - "type": "xss", - "crs_id": "941180", - "category": "attack_attempt", - "cwe": "79", - "capec": "1000/152/242/63/591" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "options": { - "enforce_word_boundary": true - }, - "list": [ - "document.cookie", - "document.write", - ".parentnode", - ".innerhtml", - "window.location", - "-moz-binding" - ] - }, - "operator": "phrase_match" - } - ], - "transformers": [ - "removeNulls", - "lowercase" - ] - }, - { - "id": "crs-941-200", - "name": "IE XSS Filters - Attack Detected via vmlframe tag", - "tags": { - "type": "xss", - "crs_id": "941200", - "category": "attack_attempt", - "cwe": "80", - "capec": "1000/152/242/63/591", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "(?i:<.*[:]?vmlframe.*?[\\s/+]*?src[\\s/+]*=)", - "options": { - "case_sensitive": true, - "min_length": 13 - } - }, - "operator": "match_regex" - } - ], - "transformers": [ - "removeNulls" - ] - }, - { - "id": "crs-941-210", - "name": "IE XSS Filters - Obfuscated Attack Detected via javascript injection", - "tags": { - "type": "xss", - "crs_id": "941210", - "category": "attack_attempt", - "cwe": "80", - "capec": "1000/152/242/63/591", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "(?i:(?:j|&#x?0*(?:74|4A|106|6A);?)(?:\\t|\\n|\\r|&(?:#x?0*(?:9|13|10|A|D);?|tab;|newline;))*(?:a|&#x?0*(?:65|41|97|61);?)(?:\\t|\\n|\\r|&(?:#x?0*(?:9|13|10|A|D);?|tab;|newline;))*(?:v|&#x?0*(?:86|56|118|76);?)(?:\\t|\\n|\\r|&(?:#x?0*(?:9|13|10|A|D);?|tab;|newline;))*(?:a|&#x?0*(?:65|41|97|61);?)(?:\\t|\\n|\\r|&(?:#x?0*(?:9|13|10|A|D);?|tab;|newline;))*(?:s|&#x?0*(?:83|53|115|73);?)(?:\\t|\\n|\\r|&(?:#x?0*(?:9|13|10|A|D);?|tab;|newline;))*(?:c|&#x?0*(?:67|43|99|63);?)(?:\\t|\\n|\\r|&(?:#x?0*(?:9|13|10|A|D);?|tab;|newline;))*(?:r|&#x?0*(?:82|52|114|72);?)(?:\\t|\\n|\\r|&(?:#x?0*(?:9|13|10|A|D);?|tab;|newline;))*(?:i|&#x?0*(?:73|49|105|69);?)(?:\\t|\\n|\\r|&(?:#x?0*(?:9|13|10|A|D);?|tab;|newline;))*(?:p|&#x?0*(?:80|50|112|70);?)(?:\\t|\\n|\\r|&(?:#x?0*(?:9|13|10|A|D);?|tab;|newline;))*(?:t|&#x?0*(?:84|54|116|74);?)(?:\\t|\\n|\\r|&(?:#x?0*(?:9|13|10|A|D);?|tab;|newline;))*(?::|&(?:#x?0*(?:58|3A);?|colon;)).)", - "options": { - "case_sensitive": true, - "min_length": 12 - } - }, - "operator": "match_regex" - } - ], - "transformers": [ - "removeNulls" - ] - }, - { - "id": "crs-941-220", - "name": "IE XSS Filters - Obfuscated Attack Detected via vbscript injection", - "tags": { - "type": "xss", - "crs_id": "941220", - "category": "attack_attempt", - "cwe": "80", - "capec": "1000/152/242/63/591", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "(?i:(?:v|&#x?0*(?:86|56|118|76);?)(?:\\t|&(?:#x?0*(?:9|13|10|A|D);?|tab;|newline;))*(?:b|&#x?0*(?:66|42|98|62);?)(?:\\t|&(?:#x?0*(?:9|13|10|A|D);?|tab;|newline;))*(?:s|&#x?0*(?:83|53|115|73);?)(?:\\t|&(?:#x?0*(?:9|13|10|A|D);?|tab;|newline;))*(?:c|&#x?0*(?:67|43|99|63);?)(?:\\t|&(?:#x?0*(?:9|13|10|A|D);?|tab;|newline;))*(?:r|&#x?0*(?:82|52|114|72);?)(?:\\t|&(?:#x?0*(?:9|13|10|A|D);?|tab;|newline;))*(?:i|&#x?0*(?:73|49|105|69);?)(?:\\t|&(?:#x?0*(?:9|13|10|A|D);?|tab;|newline;))*(?:p|&#x?0*(?:80|50|112|70);?)(?:\\t|&(?:#x?0*(?:9|13|10|A|D);?|tab;|newline;))*(?:t|&#x?0*(?:84|54|116|74);?)(?:\\t|&(?:#x?0*(?:9|13|10|A|D);?|tab;|newline;))*(?::|&(?:#x?0*(?:58|3A);?|colon;)).)", - "options": { - "case_sensitive": true, - "min_length": 10 - } - }, - "operator": "match_regex" - } - ], - "transformers": [ - "removeNulls" - ] - }, - { - "id": "crs-941-230", - "name": "IE XSS Filters - Attack Detected via embed tag", - "tags": { - "type": "xss", - "crs_id": "941230", - "category": "attack_attempt", - "cwe": "83", - "capec": "1000/152/242/63/591/243", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "]", - "options": { - "min_length": 8 - } - }, - "operator": "match_regex" - } - ], - "transformers": [ - "removeNulls" - ] - }, - { - "id": "crs-941-300", - "name": "IE XSS Filters - Attack Detected via object tag", - "tags": { - "type": "xss", - "crs_id": "941300", - "category": "attack_attempt", - "cwe": "83", - "capec": "1000/152/242/63/591/243", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": ")|<.*\\+AD4-", - "options": { - "case_sensitive": true, - "min_length": 6 - } - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "crs-941-360", - "name": "JSFuck / Hieroglyphy obfuscation detected", - "tags": { - "type": "xss", - "crs_id": "941360", - "category": "attack_attempt", - "cwe": "87", - "capec": "1000/152/242/63/591/199" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "![!+ ]\\[\\]", - "options": { - "case_sensitive": true, - "min_length": 4 - } - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "crs-941-390", - "name": "Javascript method detected", - "tags": { - "type": "xss", - "crs_id": "941390", - "category": "attack_attempt", - "confidence": "1", - "cwe": "79", - "capec": "1000/152/242/63/591" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "\\b(?i:eval|settimeout|setinterval|new\\s+Function|alert|prompt)[\\s+]*\\([^\\)]", - "options": { - "case_sensitive": true, - "min_length": 5 - } - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "crs-942-100", - "name": "SQL Injection Attack Detected via libinjection", - "tags": { - "type": "sql_injection", - "crs_id": "942100", - "category": "attack_attempt", - "cwe": "89", - "capec": "1000/152/248/66" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ] - }, - "operator": "is_sqli" - } - ], - "transformers": [ - "removeNulls" - ] - }, - { - "id": "crs-942-160", - "name": "Detects blind sqli tests using sleep() or benchmark()", - "tags": { - "type": "sql_injection", - "crs_id": "942160", - "category": "attack_attempt", - "cwe": "89", - "capec": "1000/152/248/66/7", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "(?i:sleep\\(\\s*?\\d*?\\s*?\\)|benchmark\\(.*?\\,.*?\\))", - "options": { - "case_sensitive": true, - "min_length": 7 - } - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "crs-942-240", - "name": "Detects MySQL charset switch and MSSQL DoS attempts", - "tags": { - "type": "sql_injection", - "crs_id": "942240", - "category": "attack_attempt", - "cwe": "89", - "capec": "1000/152/248/66/7", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "(?:[\\\"'`](?:;*?\\s*?waitfor\\s+(?:delay|time)\\s+[\\\"'`]|;.*?:\\s*?goto)|alter\\s*?\\w+.*?cha(?:racte)?r\\s+set\\s+\\w+)", - "options": { - "min_length": 7 - } - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "crs-942-250", - "name": "Detects MATCH AGAINST, MERGE and EXECUTE IMMEDIATE injections", - "tags": { - "type": "sql_injection", - "crs_id": "942250", - "category": "attack_attempt", - "cwe": "89", - "capec": "1000/152/248/66" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "(?i:merge.*?using\\s*?\\(|execute\\s*?immediate\\s*?[\\\"'`]|match\\s*?[\\w(?:),+-]+\\s*?against\\s*?\\()", - "options": { - "case_sensitive": true, - "min_length": 11 - } - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "crs-942-270", - "name": "Basic SQL injection", - "tags": { - "type": "sql_injection", - "crs_id": "942270", - "category": "attack_attempt", - "cwe": "89", - "capec": "1000/152/248/66" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "union.*?select.*?from", - "options": { - "min_length": 15 - } - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "crs-942-280", - "name": "SQL Injection with delay functions", - "tags": { - "type": "sql_injection", - "crs_id": "942280", - "category": "attack_attempt", - "cwe": "89", - "capec": "1000/152/248/66/7", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "(?:;\\s*?shutdown\\s*?(?:[#;{]|\\/\\*|--)|waitfor\\s*?delay\\s?[\\\"'`]+\\s?\\d|select\\s*?pg_sleep)", - "options": { - "min_length": 10 - } - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "crs-942-290", - "name": "Finds basic MongoDB SQL injection attempts", - "tags": { - "type": "nosql_injection", - "crs_id": "942290", - "category": "attack_attempt", - "cwe": "943", - "capec": "1000/152/248/676" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "(?i:(?:\\[?\\$(?:(?:s(?:lic|iz)|wher)e|e(?:lemMatch|xists|q)|n(?:o[rt]|in?|e)|l(?:ike|te?)|t(?:ext|ype)|a(?:ll|nd)|jsonSchema|between|regex|x?or|div|mod)\\]?)\\b)", - "options": { - "case_sensitive": true, - "min_length": 3 - } - }, - "operator": "match_regex" - } - ], - "transformers": [ - "keys_only" - ] - }, - { - "id": "crs-942-360", - "name": "Detects concatenated basic SQL injection and SQLLFI attempts", - "tags": { - "type": "sql_injection", - "crs_id": "942360", - "category": "attack_attempt", - "cwe": "89", - "capec": "1000/152/248/66/470" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "(?:^[\\W\\d]+\\s*?(?:alter\\s*(?:a(?:(?:pplication\\s*rol|ggregat)e|s(?:ymmetric\\s*ke|sembl)y|u(?:thorization|dit)|vailability\\s*group)|c(?:r(?:yptographic\\s*provider|edential)|o(?:l(?:latio|um)|nversio)n|ertificate|luster)|s(?:e(?:rv(?:ice|er)|curity|quence|ssion|arch)|y(?:mmetric\\s*key|nonym)|togroup|chema)|m(?:a(?:s(?:ter\\s*key|k)|terialized)|e(?:ssage\\s*type|thod)|odule)|l(?:o(?:g(?:file\\s*group|in)|ckdown)|a(?:ngua|r)ge|ibrary)|t(?:(?:abl(?:espac)?|yp)e|r(?:igger|usted)|hreshold|ext)|p(?:a(?:rtition|ckage)|ro(?:cedur|fil)e|ermission)|d(?:i(?:mension|skgroup)|atabase|efault|omain)|r(?:o(?:l(?:lback|e)|ute)|e(?:sourc|mot)e)|f(?:u(?:lltext|nction)|lashback|oreign)|e(?:xte(?:nsion|rnal)|(?:ndpoi|ve)nt)|in(?:dex(?:type)?|memory|stance)|b(?:roker\\s*priority|ufferpool)|x(?:ml\\s*schema|srobject)|w(?:ork(?:load)?|rapper)|hi(?:erarchy|stogram)|o(?:perator|utline)|(?:nicknam|queu)e|us(?:age|er)|group|java|view)|union\\s*(?:(?:distin|sele)ct|all))\\b|\\b(?:(?:(?:trunc|cre|upd)at|renam)e|(?:inser|selec)t|de(?:lete|sc)|alter|load)\\s+(?:group_concat|load_file|char)\\b\\s*\\(?|[\\s(]load_file\\s*?\\(|[\\\"'`]\\s+regexp\\W)", - "options": { - "min_length": 5 - } - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "crs-942-500", - "name": "MySQL in-line comment detected", - "tags": { - "type": "sql_injection", - "crs_id": "942500", - "category": "attack_attempt", - "cwe": "89", - "capec": "1000/152/248/66" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "(?i:/\\*[!+](?:[\\w\\s=_\\-(?:)]+)?\\*/)", - "options": { - "case_sensitive": true, - "min_length": 5 - } - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "crs-943-100", - "name": "Possible Session Fixation Attack: Setting Cookie Values in HTML", - "tags": { - "type": "http_protocol_violation", - "crs_id": "943100", - "category": "attack_attempt", - "cwe": "384", - "capec": "1000/225/21/593/61", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "(?i:\\.cookie\\b.*?;\\W*?(?:expires|domain)\\W*?=|\\bhttp-equiv\\W+set-cookie\\b)", - "options": { - "case_sensitive": true, - "min_length": 15 - } - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "crs-944-100", - "name": "Remote Command Execution: Suspicious Java class detected", - "tags": { - "type": "java_code_injection", - "crs_id": "944100", - "category": "attack_attempt", - "cwe": "94", - "capec": "1000/152/242", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "server.request.headers.no_cookies" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "java\\.lang\\.(?:runtime|processbuilder)", - "options": { - "case_sensitive": true, - "min_length": 17 - } - }, - "operator": "match_regex" - } - ], - "transformers": [ - "lowercase" - ] - }, - { - "id": "crs-944-110", - "name": "Remote Command Execution: Java process spawn (CVE-2017-9805)", - "tags": { - "type": "java_code_injection", - "category": "attack_attempt", - "cwe": "94", - "capec": "1000/152/242" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "server.request.headers.no_cookies" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "(?:unmarshaller|base64data|java\\.).*(?:runtime|processbuilder)", - "options": { - "case_sensitive": false, - "min_length": 13 - } - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "crs-944-130", - "name": "Suspicious Java class detected", - "tags": { - "type": "java_code_injection", - "crs_id": "944130", - "category": "attack_attempt", - "cwe": "94", - "capec": "1000/152/242" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "server.request.headers.no_cookies" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "list": [ - "com.opensymphony.xwork2", - "com.sun.org.apache", - "java.io.bufferedinputstream", - "java.io.bufferedreader", - "java.io.bytearrayinputstream", - "java.io.bytearrayoutputstream", - "java.io.chararrayreader", - "java.io.datainputstream", - "java.io.file", - "java.io.fileoutputstream", - "java.io.filepermission", - "java.io.filewriter", - "java.io.filterinputstream", - "java.io.filteroutputstream", - "java.io.filterreader", - "java.io.inputstream", - "java.io.inputstreamreader", - "java.io.linenumberreader", - "java.io.objectoutputstream", - "java.io.outputstream", - "java.io.pipedoutputstream", - "java.io.pipedreader", - "java.io.printstream", - "java.io.pushbackinputstream", - "java.io.reader", - "java.io.stringreader", - "java.lang.class", - "java.lang.integer", - "java.lang.number", - "java.lang.object", - "java.lang.process", - "java.lang.reflect", - "java.lang.runtime", - "java.lang.string", - "java.lang.stringbuilder", - "java.lang.system", - "javax.script.scriptenginemanager", - "org.apache.commons", - "org.apache.struts", - "org.apache.struts2", - "org.omg.corba", - "java.beans.xmldecode" - ], - "options": { - "enforce_word_boundary": true - } - }, - "operator": "phrase_match" - } - ], - "transformers": [ - "lowercase" - ] - }, - { - "id": "crs-944-260", - "name": "Remote Command Execution: Malicious class-loading payload", - "tags": { - "type": "java_code_injection", - "crs_id": "944260", - "category": "attack_attempt", - "cwe": "94", - "capec": "1000/152/242", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "server.request.headers.no_cookies" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "(?:class\\.module\\.classLoader\\.resources\\.context\\.parent\\.pipeline|springframework\\.context\\.support\\.FileSystemXmlApplicationContext)", - "options": { - "case_sensitive": true, - "min_length": 58 - } - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "dog-000-001", - "name": "Look for Cassandra injections", - "tags": { - "type": "nosql_injection", - "category": "attack_attempt", - "cwe": "943", - "capec": "1000/152/248/676" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - }, - { - "address": "server.request.headers.no_cookies" - } - ], - "regex": "\\ballow\\s+filtering\\b" - }, - "operator": "match_regex" - } - ], - "transformers": [ - "removeComments" - ] - }, - { - "id": "dog-000-002", - "name": "OGNL - Look for formatting injection patterns", - "tags": { - "type": "java_code_injection", - "category": "attack_attempt", - "cwe": "94", - "capec": "1000/152/242" - }, - "conditions": [ - { - "operator": "match_regex", - "parameters": { - "inputs": [ - { - "address": "server.request.uri.raw" - }, - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - }, - { - "address": "server.request.headers.no_cookies" - } - ], - "regex": "[#%$]{(?:[^}]+[^\\w\\s}\\-_][^}]+|\\d+-\\d+)}", - "options": { - "case_sensitive": true - } - } - } - ], - "transformers": [] - }, - { - "id": "dog-000-003", - "name": "OGNL - Detect OGNL exploitation primitives", - "tags": { - "type": "java_code_injection", - "category": "attack_attempt", - "cwe": "94", - "capec": "1000/152/242", - "confidence": "1" - }, - "conditions": [ - { - "operator": "match_regex", - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "server.request.headers.no_cookies" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "[@#]ognl", - "options": { - "case_sensitive": true - } - } - } - ], - "transformers": [] - }, - { - "id": "dog-000-004", - "name": "Spring4Shell - Attempts to exploit the Spring4shell vulnerability", - "tags": { - "type": "exploit_detection", - "category": "attack_attempt", - "cwe": "94", - "capec": "1000/152/242", - "confidence": "1" - }, - "conditions": [ - { - "operator": "match_regex", - "parameters": { - "inputs": [ - { - "address": "server.request.body" - } - ], - "regex": "^class\\.module\\.classLoader\\.", - "options": { - "case_sensitive": false - } - } - } - ], - "transformers": [ - "keys_only" - ] - }, - { - "id": "dog-000-005", - "name": "Node.js: Prototype pollution through __proto__", - "tags": { - "type": "js_code_injection", - "category": "attack_attempt", - "cwe": "1321", - "capec": "1000/152/242", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - } - ], - "regex": "^__proto__$" - }, - "operator": "match_regex" - } - ], - "transformers": [ - "keys_only" - ] - }, - { - "id": "dog-000-006", - "name": "Node.js: Prototype pollution through constructor.prototype", - "tags": { - "type": "js_code_injection", - "category": "attack_attempt", - "cwe": "1321", - "capec": "1000/152/242", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - } - ], - "regex": "^constructor$" - }, - "operator": "match_regex" - }, - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - } - ], - "regex": "^prototype$" - }, - "operator": "match_regex" - } - ], - "transformers": [ - "keys_only" - ] - }, - { - "id": "dog-000-007", - "name": "Server side template injection: Velocity & Freemarker", - "tags": { - "type": "java_code_injection", - "category": "attack_attempt", - "cwe": "1336", - "capec": "1000/152/242/19", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "server.request.headers.no_cookies" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "#(?:set|foreach|macro|parse|if)\\(.*\\)|<#assign.*>" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "dog-913-001", - "name": "BurpCollaborator OOB domain", - "tags": { - "type": "attack_tool", - "category": "attack_attempt", - "tool_name": "BurpCollaborator", - "cwe": "200", - "capec": "1000/118/169", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "server.request.headers.no_cookies" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "\\b(?:burpcollaborator\\.net|oastify\\.com)\\b" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "dog-913-002", - "name": "Qualys OOB domain", - "tags": { - "type": "commercial_scanner", - "category": "attack_attempt", - "tool_name": "Qualys", - "cwe": "200", - "capec": "1000/118/169", - "confidence": "0" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "server.request.headers.no_cookies" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "\\bqualysperiscope\\.com\\b|\\.oscomm\\." - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "dog-913-003", - "name": "Probely OOB domain", - "tags": { - "type": "commercial_scanner", - "category": "attack_attempt", - "tool_name": "Probely", - "cwe": "200", - "capec": "1000/118/169", - "confidence": "0" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "server.request.headers.no_cookies" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "\\bprbly\\.win\\b" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "dog-913-004", - "name": "Known malicious out-of-band interaction domain", - "tags": { - "type": "security_scanner", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "server.request.headers.no_cookies" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "\\b(?:webhook\\.site|\\.canarytokens\\.com|vii\\.one|act1on3\\.ru|gdsburp\\.com|arcticwolf\\.net|oob\\.li|htbiw\\.com|h4\\.vc|mochan\\.cloud|imshopping\\.com|bootstrapnodejs\\.com|mooo-ng\\.com|securitytrails\\.com|canyouhackit\\.io|7bae\\.xyz)\\b" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "dog-913-005", - "name": "Known suspicious out-of-band interaction domain", - "tags": { - "type": "security_scanner", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "confidence": "0" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "server.request.headers.no_cookies" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "\\b(?:\\.ngrok\\.io|requestbin\\.com|requestbin\\.net)\\b" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "dog-913-006", - "name": "Rapid7 OOB domain", - "tags": { - "type": "commercial_scanner", - "category": "attack_attempt", - "tool_name": "Rapid7", - "cwe": "200", - "capec": "1000/118/169", - "confidence": "0" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "server.request.headers.no_cookies" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "\\bappspidered\\.rapid7\\." - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "dog-913-007", - "name": "Interact.sh OOB domain", - "tags": { - "type": "attack_tool", - "category": "attack_attempt", - "tool_name": "interact.sh", - "cwe": "200", - "capec": "1000/118/169", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "server.request.headers.no_cookies" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "\\b(?:interact\\.sh|oast\\.(?:pro|live|site|online|fun|me)|indusfacefinder\\.in|where\\.land|syhunt\\.net|tssrt\\.de|boardofcyber\\.io|assetnote-callback\\.com|praetorianlabs\\.dev|netspi\\.sh)\\b" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "dog-913-008", - "name": "Netsparker OOB domain", - "tags": { - "type": "commercial_scanner", - "category": "attack_attempt", - "tool_name": "Netsparker", - "cwe": "200", - "capec": "1000/118/169", - "confidence": "0" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "server.request.headers.no_cookies" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "\\b(?:\\.|(?:\\\\|&#)(?:0*46|x0*2e);)?r87(?:\\.|(?:\\\\|&#)(?:0*46|x0*2e);)(?:me|com)\\b", - "options": { - "case_sensitive": false, - "min_length": 7 - } - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "dog-913-009", - "name": "WhiteHat Security OOB domain", - "tags": { - "type": "commercial_scanner", - "category": "attack_attempt", - "tool_name": "WhiteHatSecurity", - "cwe": "200", - "capec": "1000/118/169", - "confidence": "0" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "server.request.headers.no_cookies" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "\\bwhsec(?:\\.|(?:\\\\|&#)(?:0*46|x0*2e);)us\\b", - "options": { - "case_sensitive": false, - "min_length": 8 - } - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "dog-913-010", - "name": "Nessus OOB domain", - "tags": { - "type": "commercial_scanner", - "category": "attack_attempt", - "tool_name": "Nessus", - "cwe": "200", - "capec": "1000/118/169", - "confidence": "0" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "server.request.headers.no_cookies" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "\\b\\.nessus\\.org\\b", - "options": { - "case_sensitive": false, - "min_length": 8 - } - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "dog-913-011", - "name": "Watchtowr OOB domain", - "tags": { - "type": "commercial_scanner", - "category": "attack_attempt", - "tool_name": "Watchtowr", - "cwe": "200", - "capec": "1000/118/169", - "confidence": "0" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "server.request.headers.no_cookies" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "\\bwatchtowr\\.com\\b", - "options": { - "case_sensitive": false, - "min_length": 8 - } - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "dog-913-012", - "name": "AppCheck NG OOB domain", - "tags": { - "type": "commercial_scanner", - "category": "attack_attempt", - "tool_name": "AppCheckNG", - "cwe": "200", - "capec": "1000/118/169", - "confidence": "0" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "server.request.headers.no_cookies" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "\\bptst\\.io\\b", - "options": { - "case_sensitive": false, - "min_length": 7 - } - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "dog-920-001", - "name": "JWT authentication bypass", - "tags": { - "type": "http_protocol_violation", - "category": "attack_attempt", - "cwe": "287", - "capec": "1000/225/115", - "confidence": "0" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.cookies" - }, - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "authorization" - ] - } - ], - "regex": "^(?:Bearer )?ey[A-Za-z0-9+_\\-/]*([QY][UW]x[Hn]Ij([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[\\x2b\\x2f-9A-Za-z]ICJ[Ou][Tb][02]5[Fl]|[QY][UW]x[Hn]I([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[048AEIMQUYcgkosw]gOiAi[Tb][km]9[Ou][RZ][Q-Za-f]|[QY][UW]x[Hn]Ij([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[048AEIMQUYcgkosw]gI[km]5[Pv][Tb][km][U-X]|[\\x2b\\x2f-9A-Za-z]{2}[159BFJNRVZdhlptx][Bh][Tb][EG]ci([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[048AEIMQUYcgkosw]gO([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[CSiy]Ai[Tb][km]9[Ou][RZ][Q-Za-f]|[QY][UW]x[Hn]I([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[048AEIMQUYcgkosw]gO([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*ICJ[Ou][Tb][02]5[Fl]|[\\x2b\\x2f-9A-Za-z][02EGUWkm]F[Ms][RZ]y([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[CSiy]A6([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*ICJ[Ou][Tb][02]5[Fl]|[QY][UW]x[Hn]I([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*ID([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*ICJ[Ou][Tb][02]5[Fl]|[\\x2b\\x2f-9A-Za-z]{2}[159BFJNRVZdhlptx][Bh][Tb][EG]ciID([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[\\x2b\\x2f-9A-Za-z]ICJ[Ou][Tb][02]5[Fl]|[QY][UW]x[Hn]I([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[\\x2b\\x2f-9A-Za-z]IDogI[km]5[Pv][Tb][km][U-X]|[QY][UW]x[Hn]I([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[CSiy]A6ICJ[Ou][Tb][02]5[Fl]|[\\x2b\\x2f-9A-Za-z][02EGUWkm]F[Ms][RZ]y([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*ID([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[CSiy]Ai[Tb][km]9[Ou][RZ][Q-Za-f]|[QY][UW]x[Hn]IiA6ICJ[Ou][Tb][02]5[Fl]|[\\x2b\\x2f-9A-Za-z]{2}[159BFJNRVZdhlptx][Bh][Tb][EG]ci([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[048AEIMQUYcgkosw]gO([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[048AEIMQUYcgkosw]gI[km]5[Pv][Tb][km][U-X]|[QY][UW]x[Hn]I([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*ID([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[048AEIMQUYcgkosw]gI[km]5[Pv][Tb][km][U-X]|[QY][UW]x[Hn]I([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[\\x2b\\x2f-9A-Za-z]IDoi[Tb][km]9[Ou][RZ][Q-Za-f]|[\\x2b\\x2f-9A-Za-z]{2}[159BFJNRVZdhlptx][Bh][Tb][EG]ci([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[CSiy]A6([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[CSiy]Ai[Tb][km]9[Ou][RZ][Q-Za-f]|[QY][UW]x[Hn]I([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[CSiy]A6([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[\\x2b\\x2f-9A-Za-z]ICJ[Ou][Tb][02]5[Fl]|[QY][UW]x[Hn]Ij([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*ICJ[Ou][Tb][02]5[Fl]|[\\x2b\\x2f-9A-Za-z][02EGUWkm]F[Ms][RZ]y([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[048AEIMQUYcgkosw]gOiAi[Tb][km]9[Ou][RZ][Q-Za-f]|[QY][UW]x[Hn]I([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[\\x2b\\x2f-9A-Za-z]ID([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[\\x2b\\x2f-9A-Za-z]ICJ[Ou][Tb][02]5[Fl]|[\\x2b\\x2f-9A-Za-z]{2}[159BFJNRVZdhlptx][Bh][Tb][EG]ci([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*ID([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[CSiy]Ai[Tb][km]9[Ou][RZ][Q-Za-f]|[\\x2b\\x2f-9A-Za-z]{2}[159BFJNRVZdhlptx][Bh][Tb][EG]ci([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*ID([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[\\x2b\\x2f-9A-Za-z]ICJ[Ou][Tb][02]5[Fl]|[\\x2b\\x2f-9A-Za-z]{2}[159BFJNRVZdhlptx][Bh][Tb][EG]ciOiAi[Tb][km]9[Ou][RZ][Q-Za-f]|[\\x2b\\x2f-9A-Za-z]{2}[159BFJNRVZdhlptx][Bh][Tb][EG]ci([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*IDogI[km]5[Pv][Tb][km][U-X]|[\\x2b\\x2f-9A-Za-z][02EGUWkm]F[Ms][RZ]y([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[\\x2b\\x2f-9A-Za-z]IDogI[km]5[Pv][Tb][km][U-X]|[\\x2b\\x2f-9A-Za-z][02EGUWkm]F[Ms][RZ]yIgO([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[CSiy]Ai[Tb][km]9[Ou][RZ][Q-Za-f]|[\\x2b\\x2f-9A-Za-z]{2}[159BFJNRVZdhlptx][Bh][Tb][EG]ci([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[CSiy]A6([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*ICJ[Ou][Tb][02]5[Fl]|[\\x2b\\x2f-9A-Za-z][02EGUWkm]F[Ms][RZ]y([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[CSiy]A6([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[048AEIMQUYcgkosw]gI[km]5[Pv][Tb][km][U-X]|[\\x2b\\x2f-9A-Za-z]{2}[159BFJNRVZdhlptx][Bh][Tb][EG]ciIDoi[Tb][km]9[Ou][RZ][Q-Za-f]|[QY][UW]x[Hn]I([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*IDogI[km]5[Pv][Tb][km][U-X]|[\\x2b\\x2f-9A-Za-z][02EGUWkm]F[Ms][RZ]yIgOiJ[Ou][Tb][02]5[Fl]|[QY][UW]x[Hn]I([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[048AEIMQUYcgkosw]gO([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[\\x2b\\x2f-9A-Za-z]ICJ[Ou][Tb][02]5[Fl]|[\\x2b\\x2f-9A-Za-z]{2}[159BFJNRVZdhlptx][Bh][Tb][EG]ciO([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[048AEIMQUYcgkosw]gI[km]5[Pv][Tb][km][U-X]|[QY][UW]x[Hn]I([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[\\x2b\\x2f-9A-Za-z]ID([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[048AEIMQUYcgkosw]gI[km]5[Pv][Tb][km][U-X]|[\\x2b\\x2f-9A-Za-z]{2}[159BFJNRVZdhlptx][Bh][Tb][EG]ci([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[\\x2b\\x2f-9A-Za-z]IDoi[Tb][km]9[Ou][RZ][Q-Za-f]|[\\x2b\\x2f-9A-Za-z]{2}[159BFJNRVZdhlptx][Bh][Tb][EG]ciID([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*ICJ[Ou][Tb][02]5[Fl]|[\\x2b\\x2f-9A-Za-z][02EGUWkm]F[Ms][RZ]y([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[048AEIMQUYcgkosw]gO([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[\\x2b\\x2f-9A-Za-z]ICJ[Ou][Tb][02]5[Fl]|[\\x2b\\x2f-9A-Za-z]{2}[159BFJNRVZdhlptx][Bh][Tb][EG]ci([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*ID([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[048AEIMQUYcgkosw]gI[km]5[Pv][Tb][km][U-X]|[\\x2b\\x2f-9A-Za-z]{2}[159BFJNRVZdhlptx][Bh][Tb][EG]ci([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[\\x2b\\x2f-9A-Za-z]IDogI[km]5[Pv][Tb][km][U-X]|[\\x2b\\x2f-9A-Za-z][02EGUWkm]F[Ms][RZ]yI6([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*ICJ[Ou][Tb][02]5[Fl]|[\\x2b\\x2f-9A-Za-z]{2}[159BFJNRVZdhlptx][Bh][Tb][EG]ci([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[\\x2b\\x2f-9A-Za-z]ID([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[048AEIMQUYcgkosw]gI[km]5[Pv][Tb][km][U-X]|[\\x2b\\x2f-9A-Za-z][02EGUWkm]F[Ms][RZ]yI6([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[\\x2b\\x2f-9A-Za-z]ICJ[Ou][Tb][02]5[Fl]|[\\x2b\\x2f-9A-Za-z]{2}[159BFJNRVZdhlptx][Bh][Tb][EG]ci([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[048AEIMQUYcgkosw]gO([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[\\x2b\\x2f-9A-Za-z]ICJ[Ou][Tb][02]5[Fl]|[\\x2b\\x2f-9A-Za-z][02EGUWkm]F[Ms][RZ]y([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[\\x2b\\x2f-9A-Za-z]ID([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[\\x2b\\x2f-9A-Za-z]ICJ[Ou][Tb][02]5[Fl]|[QY][UW]x[Hn]IiA6([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*ICJ[Ou][Tb][02]5[Fl]|[QY][UW]x[Hn]I([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[048AEIMQUYcgkosw]gO([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[048AEIMQUYcgkosw]gI[km]5[Pv][Tb][km][U-X]|[\\x2b\\x2f-9A-Za-z][02EGUWkm]F[Ms][RZ]y([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[\\x2b\\x2f-9A-Za-z]ID([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[CSiy]Ai[Tb][km]9[Ou][RZ][Q-Za-f]|[\\x2b\\x2f-9A-Za-z][02EGUWkm]F[Ms][RZ]y([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*IDogI[km]5[Pv][Tb][km][U-X]|[\\x2b\\x2f-9A-Za-z][02EGUWkm]F[Ms][RZ]yIgO([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*ICJ[Ou][Tb][02]5[Fl]|[QY][UW]x[Hn]Ij([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[CSiy]Ai[Tb][km]9[Ou][RZ][Q-Za-f]|[QY][UW]x[Hn]I([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[CSiy]A6([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[048AEIMQUYcgkosw]gI[km]5[Pv][Tb][km][U-X]|[\\x2b\\x2f-9A-Za-z][02EGUWkm]F[Ms][RZ]y([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[CSiy]A6ICJ[Ou][Tb][02]5[Fl]|[QY][UW]x[Hn]I([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[\\x2b\\x2f-9A-Za-z]ID([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[CSiy]Ai[Tb][km]9[Ou][RZ][Q-Za-f]|[\\x2b\\x2f-9A-Za-z]{2}[159BFJNRVZdhlptx][Bh][Tb][EG]ciOiJ[Ou][Tb][02]5[Fl]|[\\x2b\\x2f-9A-Za-z]{2}[159BFJNRVZdhlptx][Bh][Tb][EG]ci([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*IDoi[Tb][km]9[Ou][RZ][Q-Za-f]|[QY][UW]x[Hn]I([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[048AEIMQUYcgkosw]gOiJ[Ou][Tb][02]5[Fl]|[\\x2b\\x2f-9A-Za-z]{2}[159BFJNRVZdhlptx][Bh][Tb][EG]ciO([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*ICJ[Ou][Tb][02]5[Fl]|[\\x2b\\x2f-9A-Za-z][02EGUWkm]F[Ms][RZ]yIgOiAi[Tb][km]9[Ou][RZ][Q-Za-f]|[\\x2b\\x2f-9A-Za-z][02EGUWkm]F[Ms][RZ]y([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[\\x2b\\x2f-9A-Za-z]IDoi[Tb][km]9[Ou][RZ][Q-Za-f]|[\\x2b\\x2f-9A-Za-z]{2}[159BFJNRVZdhlptx][Bh][Tb][EG]ciID([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[048AEIMQUYcgkosw]gI[km]5[Pv][Tb][km][U-X]|[\\x2b\\x2f-9A-Za-z]{2}[159BFJNRVZdhlptx][Bh][Tb][EG]ci([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[CSiy]A6ICJ[Ou][Tb][02]5[Fl]|[QY][UW]x[Hn]IjogI[km]5[Pv][Tb][km][U-X]|[QY][UW]x[Hn]I([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[\\x2b\\x2f-9A-Za-z]ID([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*ICJ[Ou][Tb][02]5[Fl]|[QY][UW]x[Hn]I([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[CSiy]A6([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[CSiy]Ai[Tb][km]9[Ou][RZ][Q-Za-f]|[\\x2b\\x2f-9A-Za-z][02EGUWkm]F[Ms][RZ]y([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[048AEIMQUYcgkosw]gO([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[CSiy]Ai[Tb][km]9[Ou][RZ][Q-Za-f]|[\\x2b\\x2f-9A-Za-z][02EGUWkm]F[Ms][RZ]y([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*ID([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[\\x2b\\x2f-9A-Za-z]ICJ[Ou][Tb][02]5[Fl]|[\\x2b\\x2f-9A-Za-z]{2}[159BFJNRVZdhlptx][Bh][Tb][EG]ciO([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[CSiy]Ai[Tb][km]9[Ou][RZ][Q-Za-f]|[QY][UW]x[Hn]IiA6I[km]5[Pv][Tb][km][U-X]|[\\x2b\\x2f-9A-Za-z]{2}[159BFJNRVZdhlptx][Bh][Tb][EG]ci([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[\\x2b\\x2f-9A-Za-z]ID([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*ICJ[Ou][Tb][02]5[Fl]|[\\x2b\\x2f-9A-Za-z]{2}[159BFJNRVZdhlptx][Bh][Tb][EG]ciID([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[CSiy]Ai[Tb][km]9[Ou][RZ][Q-Za-f]|[QY][UW]x[Hn]I([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*ID([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[CSiy]Ai[Tb][km]9[Ou][RZ][Q-Za-f]|[\\x2b\\x2f-9A-Za-z][02EGUWkm]F[Ms][RZ]y([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[CSiy]A6I[km]5[Pv][Tb][km][U-X]|[\\x2b\\x2f-9A-Za-z][02EGUWkm]F[Ms][RZ]yI6I[km]5[Pv][Tb][km][U-X]|[\\x2b\\x2f-9A-Za-z][02EGUWkm]F[Ms][RZ]yI6ICJ[Ou][Tb][02]5[Fl]|[\\x2b\\x2f-9A-Za-z]{2}[159BFJNRVZdhlptx][Bh][Tb][EG]ciIDogI[km]5[Pv][Tb][km][U-X]|[\\x2b\\x2f-9A-Za-z][02EGUWkm]F[Ms][RZ]y([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[\\x2b\\x2f-9A-Za-z]ID([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*ICJ[Ou][Tb][02]5[Fl]|[\\x2b\\x2f-9A-Za-z][02EGUWkm]F[Ms][RZ]y([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[048AEIMQUYcgkosw]gO([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[048AEIMQUYcgkosw]gI[km]5[Pv][Tb][km][U-X]|[\\x2b\\x2f-9A-Za-z]{2}[159BFJNRVZdhlptx][Bh][Tb][EG]ci([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*ID([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*ICJ[Ou][Tb][02]5[Fl]|[\\x2b\\x2f-9A-Za-z][02EGUWkm]F[Ms][RZ]y([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[\\x2b\\x2f-9A-Za-z]ID([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[048AEIMQUYcgkosw]gI[km]5[Pv][Tb][km][U-X]|[QY][UW]x[Hn]IiA6([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[CSiy]Ai[Tb][km]9[Ou][RZ][Q-Za-f]|[QY][UW]x[Hn]I([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[048AEIMQUYcgkosw]gO([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[CSiy]Ai[Tb][km]9[Ou][RZ][Q-Za-f]|[\\x2b\\x2f-9A-Za-z]{2}[159BFJNRVZdhlptx][Bh][Tb][EG]ci([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[048AEIMQUYcgkosw]gO([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*ICJ[Ou][Tb][02]5[Fl]|[\\x2b\\x2f-9A-Za-z]{2}[159BFJNRVZdhlptx][Bh][Tb][EG]ci([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[CSiy]A6([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[\\x2b\\x2f-9A-Za-z]ICJ[Ou][Tb][02]5[Fl]|[QY][UW]x[Hn]IiA6([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[\\x2b\\x2f-9A-Za-z]ICJ[Ou][Tb][02]5[Fl]|[\\x2b\\x2f-9A-Za-z]{2}[159BFJNRVZdhlptx][Bh][Tb][EG]ci([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[\\x2b\\x2f-9A-Za-z]ID([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[\\x2b\\x2f-9A-Za-z]ICJ[Ou][Tb][02]5[Fl]|[\\x2b\\x2f-9A-Za-z][02EGUWkm]F[Ms][RZ]y([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*IDoi[Tb][km]9[Ou][RZ][Q-Za-f]|[\\x2b\\x2f-9A-Za-z]{2}[159BFJNRVZdhlptx][Bh][Tb][EG]ciO([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[\\x2b\\x2f-9A-Za-z]ICJ[Ou][Tb][02]5[Fl]|[QY][UW]x[Hn]I([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[CSiy]A6I[km]5[Pv][Tb][km][U-X]|[QY][UW]x[Hn]IiA6([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[048AEIMQUYcgkosw]gI[km]5[Pv][Tb][km][U-X]|[\\x2b\\x2f-9A-Za-z][02EGUWkm]F[Ms][RZ]y([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[CSiy]A6([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[\\x2b\\x2f-9A-Za-z]ICJ[Ou][Tb][02]5[Fl]|[\\x2b\\x2f-9A-Za-z]{2}[159BFJNRVZdhlptx][Bh][Tb][EG]ci([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[CSiy]A6([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[048AEIMQUYcgkosw]gI[km]5[Pv][Tb][km][U-X]|[\\x2b\\x2f-9A-Za-z][02EGUWkm]F[Ms][RZ]y([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[048AEIMQUYcgkosw]gO([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*ICJ[Ou][Tb][02]5[Fl]|[\\x2b\\x2f-9A-Za-z][02EGUWkm]F[Ms][RZ]yI6([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[048AEIMQUYcgkosw]gI[km]5[Pv][Tb][km][U-X]|[\\x2b\\x2f-9A-Za-z][02EGUWkm]F[Ms][RZ]yIgO([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[048AEIMQUYcgkosw]gI[km]5[Pv][Tb][km][U-X]|[\\x2b\\x2f-9A-Za-z]{2}[159BFJNRVZdhlptx][Bh][Tb][EG]ci([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[048AEIMQUYcgkosw]gOiJ[Ou][Tb][02]5[Fl]|[\\x2b\\x2f-9A-Za-z][02EGUWkm]F[Ms][RZ]y([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*ID([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*ICJ[Ou][Tb][02]5[Fl]|[\\x2b\\x2f-9A-Za-z][02EGUWkm]F[Ms][RZ]y([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[CSiy]A6([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[CSiy]Ai[Tb][km]9[Ou][RZ][Q-Za-f]|[QY][UW]x[Hn]I([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*ID([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[\\x2b\\x2f-9A-Za-z]ICJ[Ou][Tb][02]5[Fl]|[\\x2b\\x2f-9A-Za-z]{2}[159BFJNRVZdhlptx][Bh][Tb][EG]ci([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[\\x2b\\x2f-9A-Za-z]ID([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[CSiy]Ai[Tb][km]9[Ou][RZ][Q-Za-f]|[\\x2b\\x2f-9A-Za-z][02EGUWkm]F[Ms][RZ]y([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*ID([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[048AEIMQUYcgkosw]gI[km]5[Pv][Tb][km][U-X]|[\\x2b\\x2f-9A-Za-z][02EGUWkm]F[Ms][RZ]yIgO([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[\\x2b\\x2f-9A-Za-z]ICJ[Ou][Tb][02]5[Fl]|[QY][UW]x[Hn]I([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[CSiy]A6([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*ICJ[Ou][Tb][02]5[Fl]|[QY][UW]x[Hn]I([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*IDoi[Tb][km]9[Ou][RZ][Q-Za-f]|[\\x2b\\x2f-9A-Za-z]{2}[159BFJNRVZdhlptx][Bh][Tb][EG]ci([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[CSiy]A6I[km]5[Pv][Tb][km][U-X]|[\\x2b\\x2f-9A-Za-z][02EGUWkm]F[Ms][RZ]y([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[048AEIMQUYcgkosw]gOiJ[Ou][Tb][02]5[Fl]|[QY][UW]x[Hn]Ijoi[Tb][km]9[Ou][RZ][Q-Za-f]|[\\x2b\\x2f-9A-Za-z]{2}[159BFJNRVZdhlptx][Bh][Tb][EG]ci([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[048AEIMQUYcgkosw]gOiAi[Tb][km]9[Ou][RZ][Q-Za-f]|[\\x2b\\x2f-9A-Za-z][02EGUWkm]F[Ms][RZ]yI6([048ACEIMQSUYcgikoswy]|[\\x2b\\x2f-9A-Za-z]I)*[CSiy]Ai[Tb][km]9[Ou][RZ][Q-Za-f])[A-Za-z0-9+-/]*\\.[A-Za-z0-9+_\\-/]+\\.(?:[A-Za-z0-9+_\\-/]+)?$", - "options": { - "case_sensitive": true - } - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "dog-931-001", - "name": "RFI: URL Payload to well known RFI target", - "tags": { - "type": "rfi", - "category": "attack_attempt", - "cwe": "98", - "capec": "1000/152/175/253/193", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "^(?i:file|ftps?|https?).*/rfiinc\\.txt\\?+$", - "options": { - "case_sensitive": true, - "min_length": 17 - } - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "dog-932-100", - "name": "Shell spawn executing network command", - "tags": { - "type": "command_injection", - "category": "attack_attempt", - "cwe": "77", - "capec": "1000/152/248/88", - "confidence": "0" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "server.request.headers.no_cookies" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "(?:(?:['\"\\x60({|;&]|(?:^|['\"\\x60({|;&])(?:cmd(?:\\.exe)?\\s+(?:/\\w(?::\\w+)?\\s+)*))(?:ping|curl|wget|telnet)|\\bnslookup)[\\s,]", - "options": { - "case_sensitive": true, - "min_length": 5 - } - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "dog-934-001", - "name": "XXE - XML file loads external entity", - "tags": { - "type": "xxe", - "category": "attack_attempt", - "cwe": "91", - "capec": "1000/152/248/250", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.body" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "(?:<\\?xml[^>]*>.*)]+SYSTEM\\s+[^>]+>", - "options": { - "case_sensitive": false, - "min_length": 24 - } - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "dog-941-001", - "name": "XSS in source property", - "tags": { - "type": "xss", - "category": "attack_attempt", - "cwe": "83", - "capec": "1000/152/242/63/591/243", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - }, - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "referer" - ] - }, - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "<(?:iframe|esi:include)(?:(?:\\s|/)*\\w+=[\"'\\w]+)*(?:\\s|/)*src(?:doc)?=[\"']?(?:data:|javascript:|http:|dns:|//)[^\\s'\"]+['\"]?", - "options": { - "min_length": 14 - } - }, - "operator": "match_regex" - } - ], - "transformers": [ - "removeNulls", - "urlDecodeUni" - ] - }, - { - "id": "dog-942-001", - "name": "Blind XSS callback domains", - "tags": { - "type": "xss", - "category": "attack_attempt", - "cwe": "83", - "capec": "1000/152/242/63/591/243", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "server.request.headers.no_cookies" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "https?:\\/\\/(?:.*\\.)?(?:bxss\\.(?:in|me)|xss\\.ht|js\\.rip)", - "options": { - "case_sensitive": false - } - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "nfd-000-001", - "name": "Detect common directory discovery scans", - "tags": { - "type": "security_scanner", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "confidence": "1" - }, - "conditions": [ - { - "operator": "match_regex", - "parameters": { - "inputs": [ - { - "address": "server.response.status" - } - ], - "regex": "^404$", - "options": { - "case_sensitive": true - } - } - }, - { - "operator": "phrase_match", - "parameters": { - "options": { - "enforce_word_boundary": true - }, - "inputs": [ - { - "address": "server.request.uri.raw" - } - ], - "list": [ - "/wordpress/", - "/etc/", - "/login.php", - "/install.php", - "/administrator", - "/admin.php", - "/wp-config", - "/phpmyadmin", - "/fckeditor", - "/mysql", - "/manager/html", - ".htaccess", - "/config.php", - "/configuration", - "/cgi-bin/php", - "/search.php", - "/tinymce", - "/tiny_mce", - "/settings.php", - "../../..", - "/install/", - "/download.php", - "/webdav", - "/forum.php", - "/user.php", - "/style.php", - "/jmx-console", - "/modules.php", - "/include.php", - "/default.asp", - "/help.php", - "/database.yml", - "/database.yml.pgsql", - "/database.yml.sqlite3", - "/database.yml.sqlite", - "/database.yml.mysql", - ".%2e/", - "/view.php", - "/header.php", - "/search.asp", - "%5c%5c", - "/server/php/", - "/invoker/jmxinvokerservlet", - "/phpmyadmin/index.php", - "/data/admin/allowurl.txt", - "/verify.php", - "/misc/ajax.js", - "/.idea", - "/module.php", - "/backup.rar", - "/backup.tar", - "/backup.zip", - "/backup.7z", - "/backup.gz", - "/backup.tgz", - "/backup.tar.gz", - "waitfor%20delay", - "/calendar.php", - "/news.php", - "/dompdf.php", - "))))))))))))))))", - "/web.config", - "tree.php", - "/cgi-bin-sdb/printenv", - "/comments.php", - "/detail.asp", - "/license.txt", - "/admin.asp", - "/auth.php", - "/list.php", - "/content.php", - "/mod.php", - "/mini.php", - "/install.pgsql", - "/install.mysql", - "/install.sqlite", - "/install.sqlite3", - "/install.txt", - "/install.md", - "/doku.php", - "/main.asp", - "/myadmin", - "/force-download.php", - "/iisprotect/admin", - "/.gitignore", - "/print.php", - "/common.php", - "/mainfile.php", - "/functions.php", - "/scripts/setup.php", - "/faq.php", - "/op/op.login.php", - "/home.php", - "/includes/hnmain.inc.php3", - "/preview.php", - "/dump.rar", - "/dump.tar", - "/dump.zip", - "/dump.7z", - "/dump.gz", - "/dump.tgz", - "/dump.tar.gz", - "/thumbnail.php", - "/sendcard.php", - "/global.asax", - "/directory.php", - "/footer.php", - "/error.asp", - "/forum.asp", - "/save.php", - "/htmlsax3.php", - "/adm/krgourl.php", - "/includes/converter.inc.php", - "/nucleus/libs/pluginadmin.php", - "/base_qry_common.php", - "/fileadmin", - "/bitrix/admin/", - "/adm.php", - "/util/barcode.php", - "/action.php", - "/rss.asp", - "/downloads.php", - "/page.php", - "/snarf_ajax.php", - "/fck/editor", - "/sendmail.php", - "/detail.php", - "/iframe.php", - "/swfupload.swf", - "/jenkins/login", - "/phpmyadmin/main.php", - "/phpmyadmin/scripts/setup.php", - "/user/index.php", - "/checkout.php", - "/process.php", - "/ks_inc/ajax.js", - "/export.php", - "/register.php", - "/cart.php", - "/console.php", - "/friend.php", - "/readmsg.php", - "/install.asp", - "/dagent/downloadreport.asp", - "/system/index.php", - "/core/changelog.txt", - "/js/util.js", - "/interna.php", - "/gallery.php", - "/links.php", - "/data/admin/ver.txt", - "/language/zh-cn.xml", - "/productdetails.asp", - "/admin/template/article_more/config.htm", - "/components/com_moofaq/includes/file_includer.php", - "/licence.txt", - "/rss.xsl", - "/vtigerservice.php", - "/mysql/main.php", - "/passwiki.php", - "/scr/soustab.php", - "/global.php", - "/email.php", - "/user.asp", - "/msd", - "/products.php", - "/cultbooking.php", - "/cron.php", - "/static/js/admincp.js", - "/comment.php", - "/maintainers", - "/modules/plain/adminpart/addplain.php", - "/wp-content/plugins/ungallery/source_vuln.php", - "/upgrade.txt", - "/category.php", - "/index_logged.php", - "/members.asp", - "/script/html.js", - "/images/ad.js", - "/awstats/awstats.pl", - "/includes/esqueletos/skel_null.php", - "/modules/profile/user.php", - "/window_top.php", - "/openbrowser.php", - "/thread.php", - "tinfoil_xss", - "/includes/include.php", - "/urheber.php", - "/header.inc.php", - "/mysqldumper", - "/display.php", - "/website.php", - "/stats.php", - "/assets/plugins/mp3_id/mp3_id.php", - "/siteminderagent/forms/smpwservices.fcc", - "/eval-stdin.php" - ] - } - } - ], - "transformers": [ - "lowercase" - ] - }, - { - "id": "nfd-000-002", - "name": "Detect failed attempt to fetch readme files", - "tags": { - "type": "security_scanner", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "confidence": "1" - }, - "conditions": [ - { - "operator": "match_regex", - "parameters": { - "inputs": [ - { - "address": "server.response.status" - } - ], - "regex": "^404$", - "options": { - "case_sensitive": true - } - } - }, - { - "operator": "match_regex", - "parameters": { - "inputs": [ - { - "address": "server.request.uri.raw" - } - ], - "regex": "readme\\.[\\.a-z0-9]+$", - "options": { - "case_sensitive": false - } - } - } - ], - "transformers": [] - }, - { - "id": "nfd-000-003", - "name": "Detect failed attempt to fetch Java EE resource files", - "tags": { - "type": "security_scanner", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "confidence": "1" - }, - "conditions": [ - { - "operator": "match_regex", - "parameters": { - "inputs": [ - { - "address": "server.response.status" - } - ], - "regex": "^404$", - "options": { - "case_sensitive": true - } - } - }, - { - "operator": "match_regex", - "parameters": { - "inputs": [ - { - "address": "server.request.uri.raw" - } - ], - "regex": "^(?:.*web\\-inf)(?:.*web\\.xml).*$", - "options": { - "case_sensitive": false - } - } - } - ], - "transformers": [] - }, - { - "id": "nfd-000-004", - "name": "Detect failed attempt to fetch code files", - "tags": { - "type": "security_scanner", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "confidence": "1" - }, - "conditions": [ - { - "operator": "match_regex", - "parameters": { - "inputs": [ - { - "address": "server.response.status" - } - ], - "regex": "^404$", - "options": { - "case_sensitive": true - } - } - }, - { - "operator": "match_regex", - "parameters": { - "inputs": [ - { - "address": "server.request.uri.raw" - } - ], - "regex": "\\.(java|pyc?|rb|class)\\b", - "options": { - "case_sensitive": false - } - } - } - ], - "transformers": [] - }, - { - "id": "nfd-000-005", - "name": "Detect failed attempt to fetch source code archives", - "tags": { - "type": "security_scanner", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "confidence": "1" - }, - "conditions": [ - { - "operator": "match_regex", - "parameters": { - "inputs": [ - { - "address": "server.response.status" - } - ], - "regex": "^404$", - "options": { - "case_sensitive": true - } - } - }, - { - "operator": "match_regex", - "parameters": { - "inputs": [ - { - "address": "server.request.uri.raw" - } - ], - "regex": "\\.(sql|log|ndb|gz|zip|tar\\.gz|tar|regVV|reg|conf|bz2|ini|db|war|bat|inc|btr|server|ds|conf|config|admin|master|sln|bak)\\b(?:[^.]|$)", - "options": { - "case_sensitive": false - } - } - } - ], - "transformers": [] - }, - { - "id": "nfd-000-006", - "name": "Detect failed attempt to fetch sensitive files", - "tags": { - "type": "security_scanner", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "confidence": "1" - }, - "conditions": [ - { - "operator": "match_regex", - "parameters": { - "inputs": [ - { - "address": "server.response.status" - } - ], - "regex": "^404$", - "options": { - "case_sensitive": true - } - } - }, - { - "operator": "match_regex", - "parameters": { - "inputs": [ - { - "address": "server.request.uri.raw" - } - ], - "regex": "\\.(cgi|bat|dll|exe|key|cert|crt|pem|der|pkcs|pkcs|pkcs[0-9]*|nsf|jsa|war|java|class|vb|vba|so|git|svn|hg|cvs)([^a-zA-Z0-9_]|$)", - "options": { - "case_sensitive": false - } - } - } - ], - "transformers": [] - }, - { - "id": "nfd-000-007", - "name": "Detect failed attempt to fetch archives", - "tags": { - "type": "security_scanner", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "confidence": "1" - }, - "conditions": [ - { - "operator": "match_regex", - "parameters": { - "inputs": [ - { - "address": "server.response.status" - } - ], - "regex": "^404$", - "options": { - "case_sensitive": true - } - } - }, - { - "operator": "match_regex", - "parameters": { - "inputs": [ - { - "address": "server.request.uri.raw" - } - ], - "regex": "/[\\d\\-_]*\\.(rar|tar|zip|7z|gz|tgz|tar.gz)", - "options": { - "case_sensitive": false - } - } - } - ], - "transformers": [] - }, - { - "id": "nfd-000-008", - "name": "Detect failed attempt to trigger incorrect application behavior", - "tags": { - "type": "security_scanner", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "confidence": "1" - }, - "conditions": [ - { - "operator": "match_regex", - "parameters": { - "inputs": [ - { - "address": "server.response.status" - } - ], - "regex": "^404$", - "options": { - "case_sensitive": true - } - } - }, - { - "operator": "match_regex", - "parameters": { - "inputs": [ - { - "address": "server.request.uri.raw" - } - ], - "regex": "(/(administrator/components/com.*\\.php|response\\.write\\(.+\\))|select\\(.+\\)from|\\(.*sleep\\(.+\\)|(%[a-zA-Z0-9]{2}[a-zA-Z]{0,1})+\\))", - "options": { - "case_sensitive": false - } - } - } - ], - "transformers": [] - }, - { - "id": "nfd-000-009", - "name": "Detect failed attempt to leak the structure of the application", - "tags": { - "type": "security_scanner", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "confidence": "1" - }, - "conditions": [ - { - "operator": "match_regex", - "parameters": { - "inputs": [ - { - "address": "server.response.status" - } - ], - "regex": "^404$", - "options": { - "case_sensitive": true - } - } - }, - { - "operator": "match_regex", - "parameters": { - "inputs": [ - { - "address": "server.request.uri.raw" - } - ], - "regex": "/(login\\.rol|LICENSE|[\\w-]+\\.(plx|pwd))$", - "options": { - "case_sensitive": false - } - } - } - ], - "transformers": [] - }, - { - "id": "nfd-000-010", - "name": "Detect failed attempts to find API documentation", - "tags": { - "type": "security_scanner", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "confidence": "0" - }, - "conditions": [ - { - "operator": "match_regex", - "parameters": { - "inputs": [ - { - "address": "server.response.status" - } - ], - "regex": "^404$", - "options": { - "case_sensitive": true - } - } - }, - { - "operator": "match_regex", - "parameters": { - "inputs": [ - { - "address": "server.request.uri.raw" - } - ], - "regex": "(?:/swagger\\b|/api[-/]docs?\\b)", - "options": { - "case_sensitive": false - } - } - } - ], - "transformers": [] - }, - { - "id": "rasp-930-100", - "name": "Local file inclusion exploit", - "tags": { - "type": "lfi", - "category": "vulnerability_trigger", - "cwe": "22", - "capec": "1000/255/153/126", - "confidence": "0", - "module": "rasp" - }, - "conditions": [ - { - "parameters": { - "resource": [ - { - "address": "server.io.fs.file" - } - ], - "params": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ] - }, - "operator": "lfi_detector" - } - ], - "transformers": [], - "on_match": [ - "stack_trace" - ] - }, - { - "id": "rasp-932-100", - "name": "Command injection exploit", - "tags": { - "type": "command_injection", - "category": "vulnerability_trigger", - "cwe": "77", - "capec": "1000/152/248/88", - "confidence": "0", - "module": "rasp" - }, - "conditions": [ - { - "parameters": { - "resource": [ - { - "address": "server.sys.shell.cmd" - } - ], - "params": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ] - }, - "operator": "shi_detector" - } - ], - "transformers": [], - "on_match": [ - "stack_trace" - ] - }, - { - "id": "rasp-934-100", - "name": "Server-side request forgery exploit", - "tags": { - "type": "ssrf", - "category": "vulnerability_trigger", - "cwe": "918", - "capec": "1000/225/115/664", - "confidence": "0", - "module": "rasp" - }, - "conditions": [ - { - "parameters": { - "resource": [ - { - "address": "server.io.net.url" - } - ], - "params": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ] - }, - "operator": "ssrf_detector" - } - ], - "transformers": [], - "on_match": [ - "stack_trace" - ] - }, - { - "id": "rasp-942-100", - "name": "SQL injection exploit", - "tags": { - "type": "sql_injection", - "category": "vulnerability_trigger", - "cwe": "89", - "capec": "1000/152/248/66", - "confidence": "0", - "module": "rasp" - }, - "conditions": [ - { - "parameters": { - "resource": [ - { - "address": "server.db.statement" - } - ], - "params": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "db_type": [ - { - "address": "server.db.system" - } - ] - }, - "operator": "sqli_detector@v2" - } - ], - "transformers": [], - "on_match": [ - "stack_trace" - ] - }, - { - "id": "sqr-000-001", - "name": "SSRF: Try to access the credential manager of the main cloud services", - "tags": { - "type": "ssrf", - "category": "attack_attempt", - "cwe": "918", - "capec": "1000/225/115/664", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "(?i)^\\W*((http|ftp)s?://)?\\W*((::f{4}:)?(169|(0x)?0*a9|0+251)\\.?(254|(0x)?0*fe|0+376)[0-9a-fx\\.:]+|metadata\\.google\\.internal|metadata\\.goog)\\W*/", - "options": { - "min_length": 4 - } - }, - "operator": "match_regex" - } - ], - "transformers": [ - "removeNulls" - ] - }, - { - "id": "sqr-000-002", - "name": "Server-side Javascript injection: Try to detect obvious JS injection", - "tags": { - "type": "js_code_injection", - "category": "attack_attempt", - "cwe": "94", - "capec": "1000/152/242" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "require\\(['\"][\\w\\.]+['\"]\\)|process\\.\\w+\\([\\w\\.]*\\)|\\.toString\\(\\)", - "options": { - "min_length": 4 - } - }, - "operator": "match_regex" - } - ], - "transformers": [ - "removeNulls" - ] - }, - { - "id": "sqr-000-008", - "name": "Windows: Detect attempts to exfiltrate .ini files", - "tags": { - "type": "command_injection", - "category": "attack_attempt", - "cwe": "78", - "capec": "1000/152/248/88", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "server.request.headers.no_cookies" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "(?i)[&|]\\s*type\\s+%\\w+%\\\\+\\w+\\.ini\\s*[&|]" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "sqr-000-009", - "name": "Linux: Detect attempts to exfiltrate passwd files", - "tags": { - "type": "command_injection", - "category": "attack_attempt", - "cwe": "78", - "capec": "1000/152/248/88", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "server.request.headers.no_cookies" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "(?i)[&|]\\s*cat\\s*\\/etc\\/[\\w\\.\\/]*passwd\\s*[&|]" - }, - "operator": "match_regex" - } - ], - "transformers": [ - "cmdLine" - ] - }, - { - "id": "sqr-000-010", - "name": "Windows: Detect attempts to timeout a shell", - "tags": { - "type": "command_injection", - "category": "attack_attempt", - "cwe": "78", - "capec": "1000/152/248/88", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "server.request.headers.no_cookies" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "(?i)[&|]\\s*timeout\\s+/t\\s+\\d+\\s*[&|]" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "sqr-000-011", - "name": "SSRF: Try to access internal OMI service (CVE-2021-38647)", - "tags": { - "type": "ssrf", - "category": "attack_attempt", - "cwe": "918", - "capec": "1000/225/115/664", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "http(s?):\\/\\/([A-Za-z0-9\\.\\-\\_]+|\\[[A-Fa-f0-9\\:]+\\]|):5986\\/wsman", - "options": { - "min_length": 4 - } - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "sqr-000-012", - "name": "SSRF: Detect SSRF attempt on internal service", - "tags": { - "type": "ssrf", - "category": "attack_attempt", - "cwe": "918", - "capec": "1000/225/115/664", - "confidence": "0" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "^(jar:)?(http|https):\\/\\/([0-9oq]{1,5}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}|[0-9]{1,10})(:[0-9]{1,5})?(\\/[^:@]*)?$" - }, - "operator": "match_regex" - } - ], - "transformers": [ - "lowercase" - ] - }, - { - "id": "sqr-000-013", - "name": "SSRF: Detect SSRF attempts using IPv6 or octal/hexdecimal obfuscation", - "tags": { - "type": "ssrf", - "category": "attack_attempt", - "cwe": "918", - "capec": "1000/225/115/664", - "confidence": "0" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "^(jar:)?(http|https):\\/\\/((\\[)?[:0-9a-f\\.x]{2,}(\\])?)(:[0-9]{1,5})?(\\/[^:@]*)?$" - }, - "operator": "match_regex" - } - ], - "transformers": [ - "lowercase" - ] - }, - { - "id": "sqr-000-014", - "name": "SSRF: Detect SSRF domain redirection bypass", - "tags": { - "type": "ssrf", - "category": "attack_attempt", - "cwe": "918", - "capec": "1000/225/115/664", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "server.request.headers.no_cookies" - }, - { - "address": "grpc.server.request.message" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "(http|https):\\/\\/(?:.*\\.)?(?:burpcollaborator\\.net|localtest\\.me|mail\\.ebc\\.apple\\.com|bugbounty\\.dod\\.network|.*\\.[nx]ip\\.io|oastify\\.com|oast\\.(?:pro|live|site|online|fun|me)|sslip\\.io|requestbin\\.com|requestbin\\.net|hookbin\\.com|webhook\\.site|canarytokens\\.com|interact\\.sh|ngrok\\.io|bugbounty\\.click|prbly\\.win|qualysperiscope\\.com|vii\\.one|act1on3\\.ru)" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "sqr-000-015", - "name": "SSRF: Detect SSRF attempt using non HTTP protocol", - "tags": { - "type": "ssrf", - "category": "attack_attempt", - "cwe": "918", - "capec": "1000/225/115/664", - "confidence": "0" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "server.request.headers.no_cookies" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "^(jar:)?((file|netdoc):\\/\\/[\\\\\\/]+|(dict|gopher|ldap|sftp|tftp):\\/\\/.*:[0-9]{1,5})" - }, - "operator": "match_regex" - } - ], - "transformers": [ - "lowercase" - ] - }, - { - "id": "sqr-000-017", - "name": "Log4shell: Attempt to exploit log4j CVE-2021-44228", - "tags": { - "type": "exploit_detection", - "category": "attack_attempt", - "cwe": "94", - "capec": "1000/152/242", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.uri.raw" - }, - { - "address": "server.request.query" - }, - { - "address": "server.request.body" - }, - { - "address": "server.request.path_params" - }, - { - "address": "server.request.headers.no_cookies" - }, - { - "address": "graphql.server.all_resolvers" - }, - { - "address": "graphql.server.resolver" - } - ], - "regex": "\\${[^j]*j[^n]*n[^d]*d[^i]*i[^:]*:[^}]*}" - }, - "operator": "match_regex" - } - ], - "transformers": [ - "unicode_normalize" - ] - }, - { - "id": "ua0-600-0xx", - "name": "Joomla exploitation tool", - "tags": { - "type": "attack_tool", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "Joomla exploitation tool", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "JDatabaseDriverMysqli" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-10x", - "name": "Nessus", - "tags": { - "type": "attack_tool", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "Nessus", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "(?i)^Nessus(/|([ :]+SOAP))" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-12x", - "name": "Arachni", - "tags": { - "type": "attack_tool", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "Arachni", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "^Arachni\\/v" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-13x", - "name": "Jorgee", - "tags": { - "type": "attack_tool", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "Jorgee", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "(?i)\\bJorgee\\b" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-14x", - "name": "Probely", - "tags": { - "type": "commercial_scanner", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "Probely", - "confidence": "0" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "(?i)\\bProbely\\b" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-15x", - "name": "Metis", - "tags": { - "type": "attack_tool", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "Metis", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "(?i)\\bmetis\\b" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-16x", - "name": "SQL power injector", - "tags": { - "type": "attack_tool", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "SQLPowerInjector", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "sql power injector" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-18x", - "name": "N-Stealth", - "tags": { - "type": "attack_tool", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "N-Stealth", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "(?i)\\bn-stealth\\b" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-19x", - "name": "Brutus", - "tags": { - "type": "attack_tool", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "Brutus", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "(?i)\\bbrutus\\b" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-1xx", - "name": "Shellshock exploitation tool", - "tags": { - "type": "security_scanner", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "\\(\\) \\{ :; *\\}" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-20x", - "name": "Netsparker", - "tags": { - "type": "commercial_scanner", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "Netsparker", - "confidence": "0" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "\\bnetsparker\\b" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-22x", - "name": "JAASCois", - "tags": { - "type": "attack_tool", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "JAASCois", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "(?i)\\bjaascois\\b" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-26x", - "name": "Nsauditor", - "tags": { - "type": "attack_tool", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "Nsauditor", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "(?i)\\bnsauditor\\b" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-27x", - "name": "Paros", - "tags": { - "type": "attack_tool", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "Paros", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "(?i)Mozilla/.* Paros/" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-28x", - "name": "DirBuster", - "tags": { - "type": "attack_tool", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "DirBuster", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "(?i)\\bdirbuster\\b" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-29x", - "name": "Pangolin", - "tags": { - "type": "attack_tool", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "Pangolin", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "(?i)\\bpangolin\\b" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-2xx", - "name": "Qualys", - "tags": { - "type": "commercial_scanner", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "Qualys", - "confidence": "0" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "(?i)\\bqualys\\b" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-30x", - "name": "SQLNinja", - "tags": { - "type": "attack_tool", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "SQLNinja", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "(?i)\\bsqlninja\\b" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-31x", - "name": "Nikto", - "tags": { - "type": "attack_tool", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "Nikto", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "\\(Nikto/[\\d\\.]+\\)" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-33x", - "name": "BlackWidow", - "tags": { - "type": "attack_tool", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "BlackWidow", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "(?i)\\bblack\\s?widow\\b" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-34x", - "name": "Grendel-Scan", - "tags": { - "type": "attack_tool", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "Grendel-Scan", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "(?i)\\bgrendel-scan\\b" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-35x", - "name": "Havij", - "tags": { - "type": "attack_tool", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "Havij", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "(?i)\\bhavij\\b" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-36x", - "name": "w3af", - "tags": { - "type": "attack_tool", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "w3af", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "(?i)\\bw3af\\b" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-37x", - "name": "Nmap", - "tags": { - "type": "attack_tool", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "Nmap", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "nmap (nse|scripting engine)" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-39x", - "name": "Nessus Scripted", - "tags": { - "type": "attack_tool", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "Nessus", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "(?i)^'?[a-z0-9_]+\\.nasl'?$" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-3xx", - "name": "Evil Scanner", - "tags": { - "type": "attack_tool", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "EvilScanner", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "(?i)\\bevilScanner\\b" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-40x", - "name": "WebFuck", - "tags": { - "type": "attack_tool", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "WebFuck", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "(?i)\\bWebFuck\\b" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-42x", - "name": "OpenVAS", - "tags": { - "type": "attack_tool", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "OpenVAS", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "(?i)OpenVAS\\b" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-43x", - "name": "Spider-Pig", - "tags": { - "type": "attack_tool", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "Spider-Pig", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "Powered by Spider-Pig by tinfoilsecurity\\.com" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-44x", - "name": "Zgrab", - "tags": { - "type": "attack_tool", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "Zgrab", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "Mozilla/\\d+.\\d+ zgrab" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-45x", - "name": "Zmeu", - "tags": { - "type": "attack_tool", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "Zmeu", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "(?i)\\bZmEu\\b" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-47x", - "name": "GoogleSecurityScanner", - "tags": { - "type": "commercial_scanner", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "GoogleSecurityScanner", - "confidence": "0" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "(?i)\\bGoogleSecurityScanner\\b" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-48x", - "name": "Commix", - "tags": { - "type": "attack_tool", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "Commix", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "^commix\\/" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-49x", - "name": "Gobuster", - "tags": { - "type": "attack_tool", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "Gobuster", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "^gobuster\\/" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-4xx", - "name": "CGIchk", - "tags": { - "type": "attack_tool", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "CGIchk", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "(?i)\\bcgichk\\b" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-51x", - "name": "FFUF", - "tags": { - "type": "attack_tool", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "FFUF", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "(?i)^Fuzz Faster U Fool\\b" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-52x", - "name": "Nuclei", - "tags": { - "type": "attack_tool", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "Nuclei", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "(?i)^Nuclei\\b" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-53x", - "name": "Tsunami", - "tags": { - "type": "attack_tool", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "Tsunami", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "(?i)\\bTsunamiSecurityScanner\\b" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-54x", - "name": "Nimbostratus", - "tags": { - "type": "attack_tool", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "Nimbostratus", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "(?i)\\bnimbostratus-bot\\b" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-55x", - "name": "Datadog test scanner: user-agent", - "tags": { - "type": "security_scanner", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "Datadog Canary Test", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - }, - { - "address": "grpc.server.request.metadata", - "key_path": [ - "dd-canary" - ] - } - ], - "regex": "^dd-test-scanner-log(?:$|/|\\s)" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-56x", - "name": "Datadog test scanner - blocking version: user-agent", - "tags": { - "type": "attack_tool", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "Datadog Canary Test", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - }, - { - "address": "grpc.server.request.metadata", - "key_path": [ - "dd-canary" - ] - } - ], - "regex": "^dd-test-scanner-log-block(?:$|/|\\s)" - }, - "operator": "match_regex" - } - ], - "transformers": [], - "on_match": [ - "block" - ] - }, - { - "id": "ua0-600-57x", - "name": "AlertLogic", - "tags": { - "type": "commercial_scanner", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "AlertLogic", - "confidence": "0" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "\\bAlertLogic-MDR-" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-58x", - "name": "wfuzz", - "tags": { - "type": "attack_tool", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "wfuzz", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "\\bwfuzz\\b" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-59x", - "name": "Detectify", - "tags": { - "type": "commercial_scanner", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "Detectify", - "confidence": "0" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "\\bdetectify\\b" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-5xx", - "name": "Blind SQL Injection Brute Forcer", - "tags": { - "type": "attack_tool", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "BSQLBF", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "(?i)\\bbsqlbf\\b" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-60x", - "name": "masscan", - "tags": { - "type": "attack_tool", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "masscan", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "^masscan/" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-61x", - "name": "WPScan", - "tags": { - "type": "attack_tool", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "WPScan", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "^wpscan\\b" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-62x", - "name": "Aon pentesting services", - "tags": { - "type": "commercial_scanner", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "Aon", - "confidence": "0" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "^Aon/" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-63x", - "name": "FeroxBuster", - "tags": { - "type": "attack_tool", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "feroxbuster", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "^feroxbuster/" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-6xx", - "name": "Stealthy scanner", - "tags": { - "type": "security_scanner", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "mozilla/4\\.0 \\(compatible(; msie (?:6\\.0; (?:win32|Windows NT 5\\.0)|4\\.0; Windows NT))?\\)", - "options": { - "case_sensitive": false - } - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-7xx", - "name": "SQLmap", - "tags": { - "type": "attack_tool", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "SQLmap", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "^sqlmap/" - }, - "operator": "match_regex" - } - ], - "transformers": [] - }, - { - "id": "ua0-600-9xx", - "name": "Skipfish", - "tags": { - "type": "attack_tool", - "category": "attack_attempt", - "cwe": "200", - "capec": "1000/118/169", - "tool_name": "Skipfish", - "confidence": "1" - }, - "conditions": [ - { - "parameters": { - "inputs": [ - { - "address": "server.request.headers.no_cookies", - "key_path": [ - "user-agent" - ] - } - ], - "regex": "(?i)mozilla/5\\.0 sf/" - }, - "operator": "match_regex" - } - ], - "transformers": [] - } - ], - "processors": [ - { - "id": "http-endpoint-fingerprint", - "generator": "http_endpoint_fingerprint", - "conditions": [ - { - "operator": "exists", - "parameters": { - "inputs": [ - { - "address": "waf.context.event" - }, - { - "address": "server.business_logic.users.login.failure" - }, - { - "address": "server.business_logic.users.login.success" - } - ] - } - } - ], - "parameters": { - "mappings": [ - { - "method": [ - { - "address": "server.request.method" - } - ], - "uri_raw": [ - { - "address": "server.request.uri.raw" - } - ], - "body": [ - { - "address": "server.request.body" - } - ], - "query": [ - { - "address": "server.request.query" - } - ], - "output": "_dd.appsec.fp.http.endpoint" - } - ] - }, - "evaluate": false, - "output": true - }, - { - "id": "extract-content", - "generator": "extract_schema", - "conditions": [ - { - "operator": "equals", - "parameters": { - "inputs": [ - { - "address": "waf.context.processor", - "key_path": [ - "extract-schema" - ] - } - ], - "type": "boolean", - "value": true - } - } - ], - "parameters": { - "mappings": [ - { - "inputs": [ - { - "address": "server.request.body" - } - ], - "output": "_dd.appsec.s.req.body" - }, - { - "inputs": [ - { - "address": "server.request.cookies" - } - ], - "output": "_dd.appsec.s.req.cookies" - }, - { - "inputs": [ - { - "address": "server.request.query" - } - ], - "output": "_dd.appsec.s.req.query" - }, - { - "inputs": [ - { - "address": "server.request.path_params" - } - ], - "output": "_dd.appsec.s.req.params" - }, - { - "inputs": [ - { - "address": "server.response.body" - } - ], - "output": "_dd.appsec.s.res.body" - }, - { - "inputs": [ - { - "address": "graphql.server.all_resolvers" - } - ], - "output": "_dd.appsec.s.graphql.all_resolvers" - }, - { - "inputs": [ - { - "address": "graphql.server.resolver" - } - ], - "output": "_dd.appsec.s.graphql.resolver" - } - ], - "scanners": [ - { - "tags": { - "category": "payment" - } - }, - { - "tags": { - "category": "pii" - } - } - ] - }, - "evaluate": false, - "output": true - }, - { - "id": "extract-headers", - "generator": "extract_schema", - "conditions": [ - { - "operator": "equals", - "parameters": { - "inputs": [ - { - "address": "waf.context.processor", - "key_path": [ - "extract-schema" - ] - } - ], - "type": "boolean", - "value": true - } - } - ], - "parameters": { - "mappings": [ - { - "inputs": [ - { - "address": "server.request.headers.no_cookies" - } - ], - "output": "_dd.appsec.s.req.headers" - }, - { - "inputs": [ - { - "address": "server.response.headers.no_cookies" - } - ], - "output": "_dd.appsec.s.res.headers" - } - ], - "scanners": [ - { - "tags": { - "category": "credentials" - } - }, - { - "tags": { - "category": "pii" - } - } - ] - }, - "evaluate": false, - "output": true - }, - { - "id": "http-header-fingerprint", - "generator": "http_header_fingerprint", - "conditions": [ - { - "operator": "exists", - "parameters": { - "inputs": [ - { - "address": "waf.context.event" - }, - { - "address": "server.business_logic.users.login.failure" - }, - { - "address": "server.business_logic.users.login.success" - } - ] - } - } - ], - "parameters": { - "mappings": [ - { - "headers": [ - { - "address": "server.request.headers.no_cookies" - } - ], - "output": "_dd.appsec.fp.http.header" - } - ] - }, - "evaluate": false, - "output": true - }, - { - "id": "http-network-fingerprint", - "generator": "http_network_fingerprint", - "conditions": [ - { - "operator": "exists", - "parameters": { - "inputs": [ - { - "address": "waf.context.event" - }, - { - "address": "server.business_logic.users.login.failure" - }, - { - "address": "server.business_logic.users.login.success" - } - ] - } - } - ], - "parameters": { - "mappings": [ - { - "headers": [ - { - "address": "server.request.headers.no_cookies" - } - ], - "output": "_dd.appsec.fp.http.network" - } - ] - }, - "evaluate": false, - "output": true - }, - { - "id": "session-fingerprint", - "generator": "session_fingerprint", - "conditions": [ - { - "operator": "exists", - "parameters": { - "inputs": [ - { - "address": "waf.context.event" - }, - { - "address": "server.business_logic.users.login.failure" - }, - { - "address": "server.business_logic.users.login.success" - } - ] - } - } - ], - "parameters": { - "mappings": [ - { - "cookies": [ - { - "address": "server.request.cookies" - } - ], - "session_id": [ - { - "address": "usr.session_id" - } - ], - "user_id": [ - { - "address": "usr.id" - } - ], - "output": "_dd.appsec.fp.session" - } - ] - }, - "evaluate": false, - "output": true - } - ], - "scanners": [ - { - "id": "406f8606-52c4-4663-8db9-df70f9e8766c", - "name": "ZIP Code", - "key": { - "operator": "match_regex", - "parameters": { - "regex": "\\b(?:zip|postal)\\b", - "options": { - "case_sensitive": false, - "min_length": 3 - } - } - }, - "value": { - "operator": "match_regex", - "parameters": { - "regex": "^[0-9]{5}(?:-[0-9]{4})?$", - "options": { - "case_sensitive": true, - "min_length": 5 - } - } - }, - "tags": { - "type": "zipcode", - "category": "address" - } - }, - { - "id": "JU1sRk3mSzqSUJn6GrVn7g", - "name": "American Express Card Scanner (4+4+4+3 digits)", - "key": { - "operator": "match_regex", - "parameters": { - "regex": "\\b(?:card|cc|credit|debit|payment|amex|visa|mastercard|maestro|discover|jcb|diner|amex|visa|mastercard|maestro|discover|jcb|diner)\\b", - "options": { - "case_sensitive": false, - "min_length": 3 - } - } - }, - "value": { - "operator": "match_regex", - "parameters": { - "regex": "\\b3[47]\\d{2}(?:(?:\\s\\d{4}\\s\\d{4}\\s\\d{3})|(?:\\,\\d{4}\\,\\d{4}\\,\\d{3})|(?:-\\d{4}-\\d{4}-\\d{3})|(?:\\.\\d{4}\\.\\d{4}\\.\\d{3}))\\b", - "options": { - "case_sensitive": false, - "min_length": 16 - } - } - }, - "tags": { - "type": "card", - "card_type": "amex", - "category": "payment" - } - }, - { - "id": "edmH513UTQWcRiQ9UnzHlw-mod", - "name": "American Express Card Scanner (4+6|5+5|6 digits)", - "key": { - "operator": "match_regex", - "parameters": { - "regex": "\\b(?:card|cc|credit|debit|payment|amex|visa|mastercard|maestro|discover|jcb|diner)\\b", - "options": { - "case_sensitive": false, - "min_length": 3 - } - } - }, - "value": { - "operator": "match_regex", - "parameters": { - "regex": "\\b3[47]\\d{2}(?:(?:\\s\\d{5,6}\\s\\d{5,6})|(?:\\.\\d{5,6}\\.\\d{5,6})|(?:-\\d{5,6}-\\d{5,6})|(?:,\\d{5,6},\\d{5,6}))\\b", - "options": { - "case_sensitive": false, - "min_length": 17 - } - } - }, - "tags": { - "type": "card", - "card_type": "amex", - "category": "payment" - } - }, - { - "id": "e6K4h_7qTLaMiAbaNXoSZA", - "name": "American Express Card Scanner (8+7 digits)", - "key": { - "operator": "match_regex", - "parameters": { - "regex": "\\b(?:card|cc|credit|debit|payment|amex|visa|mastercard|maestro|discover|jcb|diner)\\b", - "options": { - "case_sensitive": false, - "min_length": 3 - } - } - }, - "value": { - "operator": "match_regex", - "parameters": { - "regex": "\\b3[47]\\d{6}(?:(?:\\s\\d{7})|(?:\\,\\d{7})|(?:-\\d{7})|(?:\\.\\d{7}))\\b", - "options": { - "case_sensitive": false, - "min_length": 16 - } - } - }, - "tags": { - "type": "card", - "card_type": "amex", - "category": "payment" - } - }, - { - "id": "K2rZflWzRhGM9HiTc6whyQ", - "name": "American Express Card Scanner (1x15 digits)", - "key": { - "operator": "match_regex", - "parameters": { - "regex": "\\b(?:card|cc|credit|debit|payment|amex|visa|mastercard|maestro|discover|jcb|diner)\\b", - "options": { - "case_sensitive": false, - "min_length": 3 - } - } - }, - "value": { - "operator": "match_regex", - "parameters": { - "regex": "\\b3[47]\\d{13}\\b", - "options": { - "case_sensitive": false, - "min_length": 15 - } - } - }, - "tags": { - "type": "card", - "card_type": "amex", - "category": "payment" - } - }, - { - "id": "9d7756e343cefa22a5c098e1092590f806eb5446", - "name": "Basic Authentication Scanner", - "key": { - "operator": "match_regex", - "parameters": { - "regex": "\\bauthorization\\b", - "options": { - "case_sensitive": false, - "min_length": 13 - } - } - }, - "value": { - "operator": "match_regex", - "parameters": { - "regex": "^basic\\s+[A-Za-z0-9+/=]+", - "options": { - "case_sensitive": false, - "min_length": 7 - } - } - }, - "tags": { - "type": "basic_auth", - "category": "credentials" - } - }, - { - "id": "mZy8XjZLReC9smpERXWnnw", - "name": "Bearer Authentication Scanner", - "key": { - "operator": "match_regex", - "parameters": { - "regex": "\\bauthorization\\b", - "options": { - "case_sensitive": false, - "min_length": 13 - } - } - }, - "value": { - "operator": "match_regex", - "parameters": { - "regex": "^bearer\\s+[-a-z0-9._~+/]{4,}", - "options": { - "case_sensitive": false, - "min_length": 11 - } - } - }, - "tags": { - "type": "bearer_token", - "category": "credentials" - } - }, - { - "id": "450239afc250a19799b6c03dc0e16fd6a4b2a1af", - "name": "Canadian Social Insurance Number Scanner", - "key": { - "operator": "match_regex", - "parameters": { - "regex": "\\b(?:social[\\s_]?(?:insurance(?:\\s+number)?)?|SIN|Canadian[\\s_]?(?:social[\\s_]?(?:insurance)?|insurance[\\s_]?number)?)\\b", - "options": { - "case_sensitive": false, - "min_length": 3 - } - } - }, - "value": { - "operator": "match_regex", - "parameters": { - "regex": "\\b\\d{3}-\\d{3}-\\d{3}\\b", - "options": { - "case_sensitive": false, - "min_length": 11 - } - } - }, - "tags": { - "type": "canadian_sin", - "category": "pii" - } - }, - { - "id": "87a879ff33693b46c8a614d8211f5a2c289beca0", - "name": "Digest Authentication Scanner", - "key": { - "operator": "match_regex", - "parameters": { - "regex": "\\bauthorization\\b", - "options": { - "case_sensitive": false, - "min_length": 13 - } - } - }, - "value": { - "operator": "match_regex", - "parameters": { - "regex": "^digest\\s+", - "options": { - "case_sensitive": false, - "min_length": 7 - } - } - }, - "tags": { - "type": "digest_auth", - "category": "credentials" - } - }, - { - "id": "qWumeP1GQUa_E4ffAnT-Yg", - "name": "American Express Card Scanner (1x14 digits)", - "key": { - "operator": "match_regex", - "parameters": { - "regex": "\\b(?:card|cc|credit|debit|payment|amex|visa|mastercard|maestro|discover|jcb|diner)\\b", - "options": { - "case_sensitive": false, - "min_length": 3 - } - } - }, - "value": { - "operator": "match_regex", - "parameters": { - "regex": "(?:30[0-59]\\d|3[689]\\d{2})(?:\\d{10})", - "options": { - "case_sensitive": false, - "min_length": 14 - } - } - }, - "tags": { - "type": "card", - "card_type": "diners", - "category": "payment" - } - }, - { - "id": "NlTWWM5LS6W0GSqBLuvtRw", - "name": "Diners Card Scanner (4+4+4+2 digits)", - "key": { - "operator": "match_regex", - "parameters": { - "regex": "\\b(?:card|cc|credit|debit|payment|amex|visa|mastercard|maestro|discover|jcb|diner)\\b", - "options": { - "case_sensitive": false, - "min_length": 3 - } - } - }, - "value": { - "operator": "match_regex", - "parameters": { - "regex": "\\b(?:30[0-59]\\d|3[689]\\d{2})(?:(?:\\s\\d{4}\\s\\d{4}\\s\\d{2})|(?:\\,\\d{4}\\,\\d{4}\\,\\d{2})|(?:-\\d{4}-\\d{4}-\\d{2})|(?:\\.\\d{4}\\.\\d{4}\\.\\d{2}))\\b", - "options": { - "case_sensitive": false, - "min_length": 17 - } - } - }, - "tags": { - "type": "card", - "card_type": "diners", - "category": "payment" - } - }, - { - "id": "Xr5VdbQSTXitYGGiTfxBpw", - "name": "Diners Card Scanner (4+6+4 digits)", - "key": { - "operator": "match_regex", - "parameters": { - "regex": "\\b(?:card|cc|credit|debit|payment|amex|visa|mastercard|maestro|discover|jcb|diner)\\b", - "options": { - "case_sensitive": false, - "min_length": 3 - } - } - }, - "value": { - "operator": "match_regex", - "parameters": { - "regex": "\\b(?:30[0-59]\\d|3[689]\\d{2})(?:(?:\\s\\d{6}\\s\\d{4})|(?:\\.\\d{6}\\.\\d{4})|(?:-\\d{6}-\\d{4})|(?:,\\d{6},\\d{4}))\\b", - "options": { - "case_sensitive": false, - "min_length": 16 - } - } - }, - "tags": { - "type": "card", - "card_type": "diners", - "category": "payment" - } - }, - { - "id": "gAbunN_WQNytxu54DjcbAA-mod", - "name": "Diners Card Scanner (8+6 digits)", - "key": { - "operator": "match_regex", - "parameters": { - "regex": "\\b(?:card|cc|credit|debit|payment|amex|visa|mastercard|maestro|discover|jcb|diner)\\b", - "options": { - "case_sensitive": false, - "min_length": 3 - } - } - }, - "value": { - "operator": "match_regex", - "parameters": { - "regex": "\\b(?:30[0-59]\\d{5}|3[689]\\d{6})\\s?(?:(?:\\s\\d{6})|(?:\\,\\d{6})|(?:-\\d{6})|(?:\\.\\d{6}))\\b", - "options": { - "case_sensitive": false, - "min_length": 14 - } - } - }, - "tags": { - "type": "card", - "card_type": "diners", - "category": "payment" - } - }, - { - "id": "9cs4qCfEQBeX17U7AepOvQ", - "name": "MasterCard Scanner (2x8 digits)", - "key": { - "operator": "match_regex", - "parameters": { - "regex": "\\b(?:card|cc|credit|debit|payment|amex|visa|mastercard|maestro|discover|jcb|diner)\\b", - "options": { - "case_sensitive": false, - "min_length": 3 - } - } - }, - "value": { - "operator": "match_regex", - "parameters": { - "regex": "\\b(?:6221(?:2[6-9]|[3-9][0-9])\\d{2}(?:,\\d{8}|\\s\\d{8}|-\\d{8}|\\.\\d{8})|6229(?:[01][0-9]|2[0-5])\\d{2}(?:,\\d{8}|\\s\\d{8}|-\\d{8}|\\.\\d{8})|(?:6011|65\\d{2}|64[4-9]\\d|622[2-8])\\d{4}(?:,\\d{8}|\\s\\d{8}|-\\d{8}|\\.\\d{8}))\\b", - "options": { - "case_sensitive": false, - "min_length": 16 - } - } - }, - "tags": { - "type": "card", - "card_type": "discover", - "category": "payment" - } - }, - { - "id": "YBIDWJIvQWW_TFOyU0CGJg", - "name": "Discover Card Scanner (4x4 digits)", - "key": { - "operator": "match_regex", - "parameters": { - "regex": "\\b(?:card|cc|credit|debit|payment|amex|visa|mastercard|maestro|discover|jcb|diner)\\b", - "options": { - "case_sensitive": false, - "min_length": 3 - } - } - }, - "value": { - "operator": "match_regex", - "parameters": { - "regex": "\\b(?:(?:(?:6221(?:2[6-9]|[3-9][0-9])\\d{2}(?:,\\d{4}){2})|(?:6221\\s(?:2[6-9]|[3-9][0-9])\\d{2}(?:\\s\\d{4}){2})|(?:6221\\.(?:2[6-9]|[3-9][0-9])\\d{2}(?:\\.\\d{4}){2})|(?:6221-(?:2[6-9]|[3-9][0-9])\\d{2}(?:-\\d{4}){2}))|(?:(?:6229(?:[01][0-9]|2[0-5])\\d{2}(?:,\\d{4}){2})|(?:6229\\s(?:[01][0-9]|2[0-5])\\d{2}(?:\\s\\d{4}){2})|(?:6229\\.(?:[01][0-9]|2[0-5])\\d{2}(?:\\.\\d{4}){2})|(?:6229-(?:[01][0-9]|2[0-5])\\d{2}(?:-\\d{4}){2}))|(?:(?:6011|65\\d{2}|64[4-9]\\d|622[2-8])(?:(?:\\s\\d{4}){3}|(?:\\.\\d{4}){3}|(?:-\\d{4}){3}|(?:,\\d{4}){3})))\\b", - "options": { - "case_sensitive": false, - "min_length": 16 - } - } - }, - "tags": { - "type": "card", - "card_type": "discover", - "category": "payment" - } - }, - { - "id": "12cpbjtVTMaMutFhh9sojQ", - "name": "Discover Card Scanner (1x16 digits)", - "key": { - "operator": "match_regex", - "parameters": { - "regex": "\\b(?:card|cc|credit|debit|payment|amex|visa|mastercard|maestro|discover|jcb|diner)\\b", - "options": { - "case_sensitive": false, - "min_length": 3 - } - } - }, - "value": { - "operator": "match_regex", - "parameters": { - "regex": "\\b(?:6221(?:2[6-9]|[3-9][0-9])\\d{10}|6229(?:[01][0-9]|2[0-5])\\d{10}|(?:6011|65\\d{2}|64[4-9]\\d|622[2-8])\\d{12})\\b", - "options": { - "case_sensitive": false, - "min_length": 16 - } - } - }, - "tags": { - "type": "card", - "card_type": "discover", - "category": "payment" - } - }, - { - "id": "PuXiVTCkTHOtj0Yad1ppsw", - "name": "Standard E-mail Address", - "key": { - "operator": "match_regex", - "parameters": { - "regex": "\\b(?:(?:e[-\\s]?)?mail|address|sender|\\bto\\b|from|recipient)\\b", - "options": { - "case_sensitive": false, - "min_length": 2 - } - } - }, - "value": { - "operator": "match_regex", - "parameters": { - "regex": "\\b[\\w!#$%&'*+/=?`{|}~^-]+(?:\\.[\\w!#$%&'*+/=?`{|}~^-]+)*(%40|@)(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,6}\\b", - "options": { - "case_sensitive": false, - "min_length": 5 - } - } - }, - "tags": { - "type": "email", - "category": "pii" - } - }, - { - "id": "8VS2RKxzR8a_95L5fuwaXQ", - "name": "IBAN", - "key": { - "operator": "match_regex", - "parameters": { - "regex": "\\b(?:iban|account|sender|receiver)\\b", - "options": { - "case_sensitive": false, - "min_length": 3 - } - } - }, - "value": { - "operator": "match_regex", - "parameters": { - "regex": "\\b(?:NO\\d{2}(?:[ \\-]?\\d{4}){2}[ \\-]?\\d{3}|BE\\d{2}(?:[ \\-]?\\d{4}){3}|(?:DK|FO|FI|GL|SD)\\d{2}(?:[ \\-]?\\d{4}){3}[ \\-]?\\d{2}|NL\\d{2}[ \\-]?[A-Z]{4}(?:[ \\-]?\\d{4}){2}[ \\-]?\\d{2}|MK\\d{2}[ \\-]?\\d{3}[A-Z0-9](?:[ \\-]?[A-Z0-9]{4}){2}[ \\-]?[A-Z0-9]\\d{2}|SI\\d{17}|(?:AT|BA|EE|LT|XK)\\d{18}|(?:LU|KZ|EE|LT)\\d{5}[A-Z0-9]{13}|LV\\d{2}[A-Z]{4}[A-Z0-9]{13}|(?:LI|CH)\\d{2}[ \\-]?\\d{4}[ \\-]?\\d[A-Z0-9]{3}(?:[ \\-]?[A-Z0-9]{4}){2}[ \\-]?[A-Z0-9]|HR\\d{2}(?:[ \\-]?\\d{4}){4}[ \\-]?\\d|GE\\d{2}[ \\-]?[A-Z0-9]{2}\\d{2}\\d{14}|VA\\d{20}|BG\\d{2}[A-Z]{4}\\d{6}[A-Z0-9]{8}|BH\\d{2}[A-Z]{4}[A-Z0-9]{14}|GB\\d{2}[A-Z]{4}(?:[ \\-]?\\d{4}){3}[ \\-]?\\d{2}|IE\\d{2}[ \\-]?[A-Z0-9]{4}(?:[ \\-]?\\d{4}){3}[ \\-]?\\d{2}|(?:CR|DE|ME|RS)\\d{2}(?:[ \\-]?\\d{4}){4}[ \\-]?\\d{2}|(?:AE|TL|IL)\\d{2}(?:[ \\-]?\\d{4}){4}[ \\-]?\\d{3}|GI\\d{2}[ \\-]?[A-Z]{4}(?:[ \\-]?[A-Z0-9]{4}){3}[ \\-]?[A-Z0-9]{3}|IQ\\d{2}[ \\-]?[A-Z]{4}(?:[ \\-]?\\d{4}){3}[ \\-]?\\d{3}|MD\\d{2}(?:[ \\-]?[A-Z0-9]{4}){5}|SA\\d{2}[ \\-]?\\d{2}[A-Z0-9]{2}(?:[ \\-]?[A-Z0-9]{4}){4}|RO\\d{2}[ \\-]?[A-Z]{4}(?:[ \\-]?[A-Z0-9]{4}){4}|(?:PK|VG)\\d{2}[ \\-]?[A-Z0-9]{4}(?:[ \\-]?\\d{4}){4}|AD\\d{2}(?:[ \\-]?\\d{4}){2}(?:[ \\-]?[A-Z0-9]{4}){3}|(?:CZ|SK|ES|SE|TN)\\d{2}(?:[ \\-]?\\d{4}){5}|(?:LY|PT|ST)\\d{2}(?:[ \\-]?\\d{4}){5}[ \\-]?\\d|TR\\d{2}[ \\-]?\\d{4}[ \\-]?\\d[A-Z0-9]{3}(?:[ \\-]?[A-Z0-9]{4}){3}[ \\-]?[A-Z0-9]{2}|IS\\d{2}(?:[ \\-]?\\d{4}){5}[ \\-]?\\d{2}|(?:IT|SM)\\d{2}[ \\-]?[A-Z]\\d{3}[ \\-]?\\d{4}[ \\-]?\\d{3}[A-Z0-9](?:[ \\-]?[A-Z0-9]{4}){2}[ \\-]?[A-Z0-9]{3}|GR\\d{2}[ \\-]?\\d{4}[ \\-]?\\d{3}[A-Z0-9](?:[ \\-]?[A-Z0-9]{4}){3}[A-Z0-9]{3}|(?:FR|MC)\\d{2}(?:[ \\-]?\\d{4}){2}[ \\-]?\\d{2}[A-Z0-9]{2}(?:[ \\-]?[A-Z0-9]{4}){2}[ \\-]?[A-Z0-9]\\d{2}|MR\\d{2}(?:[ \\-]?\\d{4}){5}[ \\-]?\\d{3}|(?:SV|DO)\\d{2}[ \\-]?[A-Z]{4}(?:[ \\-]?\\d{4}){5}|BY\\d{2}[ \\-]?[A-Z]{4}[ \\-]?\\d{4}(?:[ \\-]?[A-Z0-9]{4}){4}|GT\\d{2}(?:[ \\-]?[A-Z0-9]{4}){6}|AZ\\d{2}[ \\-]?[A-Z0-9]{4}(?:[ \\-]?\\d{5}){4}|LB\\d{2}[ \\-]?\\d{4}(?:[ \\-]?[A-Z0-9]{5}){4}|(?:AL|CY)\\d{2}(?:[ \\-]?\\d{4}){2}(?:[ \\-]?[A-Z0-9]{4}){4}|(?:HU|PL)\\d{2}(?:[ \\-]?\\d{4}){6}|QA\\d{2}[ \\-]?[A-Z]{4}(?:[ \\-]?[A-Z0-9]{4}){5}[ \\-]?[A-Z0-9]|PS\\d{2}[ \\-]?[A-Z0-9]{4}(?:[ \\-]?\\d{4}){5}[ \\-]?\\d|UA\\d{2}[ \\-]?\\d{4}[ \\-]?\\d{2}[A-Z0-9]{2}(?:[ \\-]?[A-Z0-9]{4}){4}[ \\-]?[A-Z0-9]|BR\\d{2}(?:[ \\-]?\\d{4}){5}[ \\-]?\\d{3}[A-Z0-9][ \\-]?[A-Z0-9]|EG\\d{2}(?:[ \\-]?\\d{4}){6}\\d|MU\\d{2}[ \\-]?[A-Z]{4}(?:[ \\-]?\\d{4}){4}\\d{3}[A-Z][ \\-]?[A-Z]{2}|(?:KW|JO)\\d{2}[ \\-]?[A-Z]{4}(?:[ \\-]?[A-Z0-9]{4}){5}[ \\-]?[A-Z0-9]{2}|MT\\d{2}[ \\-]?[A-Z]{4}[ \\-]?\\d{4}[ \\-]?\\d[A-Z0-9]{3}(?:[ \\-]?[A-Z0-9]{3}){4}[ \\-]?[A-Z0-9]{3}|SC\\d{2}[ \\-]?[A-Z]{4}(?:[ \\-]?\\d{4}){5}[ \\-]?[A-Z]{3}|LC\\d{2}[ \\-]?[A-Z]{4}(?:[ \\-]?[A-Z0-9]{4}){6})\\b", - "options": { - "case_sensitive": false, - "min_length": 15 - } - } - }, - "tags": { - "type": "iban", - "category": "payment" - } - }, - { - "id": "h6WJcecQTwqvN9KeEtwDvg", - "name": "JCB Card Scanner (1x16 digits)", - "key": { - "operator": "match_regex", - "parameters": { - "regex": "\\b(?:card|cc|credit|debit|payment|amex|visa|mastercard|maestro|discover|jcb|diner)\\b", - "options": { - "case_sensitive": false, - "min_length": 3 - } - } - }, - "value": { - "operator": "match_regex", - "parameters": { - "regex": "\\b35(?:2[89]|[3-9][0-9])(?:\\d{12})\\b", - "options": { - "case_sensitive": false, - "min_length": 16 - } - } - }, - "tags": { - "type": "card", - "card_type": "jcb", - "category": "payment" - } - }, - { - "id": "gcEaMu_VSJ2-bGCEkgyC0w", - "name": "JCB Card Scanner (2x8 digits)", - "key": { - "operator": "match_regex", - "parameters": { - "regex": "\\b(?:card|cc|credit|debit|payment|amex|visa|mastercard|maestro|discover|jcb|diner)\\b", - "options": { - "case_sensitive": false, - "min_length": 3 - } - } - }, - "value": { - "operator": "match_regex", - "parameters": { - "regex": "\\b35(?:2[89]|[3-9][0-9])\\d{4}(?:(?:,\\d{8})|(?:-\\d{8})|(?:\\s\\d{8})|(?:\\.\\d{8}))\\b", - "options": { - "case_sensitive": false, - "min_length": 17 - } - } - }, - "tags": { - "type": "card", - "card_type": "jcb", - "category": "payment" - } - }, - { - "id": "imTliuhXT5GAeRNhqChXQQ", - "name": "JCB Card Scanner (4x4 digits)", - "key": { - "operator": "match_regex", - "parameters": { - "regex": "\\b(?:card|cc|credit|debit|payment|amex|visa|mastercard|maestro|discover|jcb|diner)\\b", - "options": { - "case_sensitive": false, - "min_length": 3 - } - } - }, - "value": { - "operator": "match_regex", - "parameters": { - "regex": "\\b35(?:2[89]|[3-9][0-9])(?:(?:\\s\\d{4}){3}|(?:\\.\\d{4}){3}|(?:-\\d{4}){3}|(?:,\\d{4}){3})\\b", - "options": { - "case_sensitive": false, - "min_length": 16 - } - } - }, - "tags": { - "type": "card", - "card_type": "jcb", - "category": "payment" - } - }, - { - "id": "9osY3xc9Q7ONAV0zw9Uz4A", - "name": "JSON Web Token", - "value": { - "operator": "match_regex", - "parameters": { - "regex": "\\bey[I-L][\\w=-]+\\.ey[I-L][\\w=-]+(\\.[\\w.+\\/=-]+)?\\b", - "options": { - "case_sensitive": false, - "min_length": 20 - } - } - }, - "tags": { - "type": "json_web_token", - "category": "credentials" - } - }, - { - "id": "d1Q9D3YMRxuVKf6CZInJPw", - "name": "Maestro Card Scanner (1x16 digits)", - "key": { - "operator": "match_regex", - "parameters": { - "regex": "\\b(?:card|cc|credit|debit|payment|amex|visa|mastercard|maestro|discover|jcb|diner)\\b", - "options": { - "case_sensitive": false, - "min_length": 3 - } - } - }, - "value": { - "operator": "match_regex", - "parameters": { - "regex": "\\b(?:5[06-9]\\d{2}|6\\d{3})(?:\\d{12})\\b", - "options": { - "case_sensitive": false, - "min_length": 16 - } - } - }, - "tags": { - "type": "card", - "card_type": "maestro", - "category": "payment" - } - }, - { - "id": "M3YIQKKjRVmoeQuM3pjzrw", - "name": "Maestro Card Scanner (2x8 digits)", - "key": { - "operator": "match_regex", - "parameters": { - "regex": "\\b(?:card|cc|credit|debit|payment|amex|visa|mastercard|maestro|discover|jcb|diner)\\b", - "options": { - "case_sensitive": false, - "min_length": 3 - } - } - }, - "value": { - "operator": "match_regex", - "parameters": { - "regex": "\\b(?:5[06-9]\\d{6}|6\\d{7})(?:\\s\\d{8}|\\.\\d{8}|-\\d{8}|,\\d{8})\\b", - "options": { - "case_sensitive": false, - "min_length": 17 - } - } - }, - "tags": { - "type": "card", - "card_type": "maestro", - "category": "payment" - } - }, - { - "id": "hRxiQBlSSVKcjh5U7LZYLA", - "name": "Maestro Card Scanner (4x4 digits)", - "key": { - "operator": "match_regex", - "parameters": { - "regex": "\\b(?:card|cc|credit|debit|payment|amex|visa|mastercard|maestro|discover|jcb|diner)\\b", - "options": { - "case_sensitive": false, - "min_length": 3 - } - } - }, - "value": { - "operator": "match_regex", - "parameters": { - "regex": "\\b(?:5[06-9]\\d{2}|6\\d{3})(?:(?:\\s\\d{4}){3}|(?:\\.\\d{4}){3}|(?:-\\d{4}){3}|(?:,\\d{4}){3})\\b", - "options": { - "case_sensitive": false, - "min_length": 16 - } - } - }, - "tags": { - "type": "card", - "card_type": "maestro", - "category": "payment" - } - }, - { - "id": "NwhIYNS4STqZys37WlaIKA", - "name": "MasterCard Scanner (2x8 digits)", - "key": { - "operator": "match_regex", - "parameters": { - "regex": "\\b(?:card|cc|credit|debit|payment|amex|visa|mastercard|maestro|discover|jcb|diner)\\b", - "options": { - "case_sensitive": false, - "min_length": 3 - } - } - }, - "value": { - "operator": "match_regex", - "parameters": { - "regex": "\\b(?:(?:5[1-5]\\d{2})|(?:222[1-9])|(?:22[3-9]\\d)|(?:2[3-6]\\d{2})|(?:27[0-1]\\d)|(?:2720))(?:(?:\\d{4}(?:(?:,\\d{8})|(?:-\\d{8})|(?:\\s\\d{8})|(?:\\.\\d{8}))))\\b", - "options": { - "case_sensitive": false, - "min_length": 16 - } - } - }, - "tags": { - "type": "card", - "card_type": "mastercard", - "category": "payment" - } - }, - { - "id": "axxJkyjhRTOuhjwlsA35Vw", - "name": "MasterCard Scanner (4x4 digits)", - "key": { - "operator": "match_regex", - "parameters": { - "regex": "\\b(?:card|cc|credit|debit|payment|amex|visa|mastercard|maestro|discover|jcb|diner)\\b", - "options": { - "case_sensitive": false, - "min_length": 3 - } - } - }, - "value": { - "operator": "match_regex", - "parameters": { - "regex": "\\b(?:(?:5[1-5]\\d{2})|(?:222[1-9])|(?:22[3-9]\\d)|(?:2[3-6]\\d{2})|(?:27[0-1]\\d)|(?:2720))(?:(?:\\s\\d{4}){3}|(?:\\.\\d{4}){3}|(?:-\\d{4}){3}|(?:,\\d{4}){3})\\b", - "options": { - "case_sensitive": false, - "min_length": 16 - } - } - }, - "tags": { - "type": "card", - "card_type": "mastercard", - "category": "payment" - } - }, - { - "id": "76EhmoK3TPqJcpM-fK0pLw", - "name": "MasterCard Scanner (1x16 digits)", - "key": { - "operator": "match_regex", - "parameters": { - "regex": "\\b(?:card|cc|credit|debit|payment|amex|visa|mastercard|maestro|discover|jcb|diner)\\b", - "options": { - "case_sensitive": false, - "min_length": 3 - } - } - }, - "value": { - "operator": "match_regex", - "parameters": { - "regex": "\\b(?:(?:5[1-5]\\d{2})|(?:222[1-9])|(?:22[3-9]\\d)|(?:2[3-6]\\d{2})|(?:27[0-1]\\d)|(?:2720))(?:\\d{12})\\b", - "options": { - "case_sensitive": false, - "min_length": 16 - } - } - }, - "tags": { - "type": "card", - "card_type": "mastercard", - "category": "payment" - } - }, - { - "id": "18b608bd7a764bff5b2344c0", - "name": "Phone number", - "key": { - "operator": "match_regex", - "parameters": { - "regex": "\\bphone|number|mobile\\b", - "options": { - "case_sensitive": false, - "min_length": 3 - } - } - }, - "value": { - "operator": "match_regex", - "parameters": { - "regex": "^(?:\\(\\+\\d{1,3}\\)|\\+\\d{1,3}|00\\d{1,3})?[-\\s\\.]?(?:\\(\\d{3}\\)[-\\s\\.]?)?(?:\\d[-\\s\\.]?){6,10}$", - "options": { - "case_sensitive": false, - "min_length": 6 - } - } - }, - "tags": { - "type": "phone", - "category": "pii" - } - }, - { - "id": "de0899e0cbaaa812bb624cf04c912071012f616d-mod", - "name": "UK National Insurance Number Scanner", - "key": { - "operator": "match_regex", - "parameters": { - "regex": "^nin$|\\binsurance\\b", - "options": { - "case_sensitive": false, - "min_length": 3 - } - } - }, - "value": { - "operator": "match_regex", - "parameters": { - "regex": "\\b[A-Z]{2}[\\s-]?\\d{6}[\\s-]?[A-Z]?\\b", - "options": { - "case_sensitive": false, - "min_length": 8 - } - } - }, - "tags": { - "type": "uk_nin", - "category": "pii" - } - }, - { - "id": "d962f7ddb3f55041e39195a60ff79d4814a7c331", - "name": "US Passport Scanner", - "key": { - "operator": "match_regex", - "parameters": { - "regex": "\\bpassport\\b", - "options": { - "case_sensitive": false, - "min_length": 8 - } - } - }, - "value": { - "operator": "match_regex", - "parameters": { - "regex": "\\b[0-9A-Z]{9}\\b|\\b[0-9]{6}[A-Z][0-9]{2}\\b", - "options": { - "case_sensitive": false, - "min_length": 8 - } - } - }, - "tags": { - "type": "passport_number", - "category": "pii" - } - }, - { - "id": "7771fc3b-b205-4b93-bcef-28608c5c1b54", - "name": "United States Social Security Number Scanner", - "key": { - "operator": "match_regex", - "parameters": { - "regex": "\\b(?:SSN|(?:(?:social)?[\\s_]?(?:security)?[\\s_]?(?:number)?)?)\\b", - "options": { - "case_sensitive": false, - "min_length": 3 - } - } - }, - "value": { - "operator": "match_regex", - "parameters": { - "regex": "\\b\\d{3}[-\\s\\.]{1}\\d{2}[-\\s\\.]{1}\\d{4}\\b", - "options": { - "case_sensitive": false, - "min_length": 11 - } - } - }, - "tags": { - "type": "us_ssn", - "category": "pii" - } - }, - { - "id": "ac6d683cbac77f6e399a14990793dd8fd0fca333", - "name": "US Vehicle Identification Number Scanner", - "key": { - "operator": "match_regex", - "parameters": { - "regex": "\\b(?:vehicle[_\\s-]*identification[_\\s-]*number|vin)\\b", - "options": { - "case_sensitive": false, - "min_length": 3 - } - } - }, - "value": { - "operator": "match_regex", - "parameters": { - "regex": "\\b[A-HJ-NPR-Z0-9]{17}\\b", - "options": { - "case_sensitive": false, - "min_length": 17 - } - } - }, - "tags": { - "type": "vin", - "category": "pii" - } - }, - { - "id": "wJIgOygRQhKkR69b_9XbRQ", - "name": "Visa Card Scanner (2x8 digits)", - "key": { - "operator": "match_regex", - "parameters": { - "regex": "\\b(?:card|cc|credit|debit|payment|amex|visa|mastercard|maestro|discover|jcb|diner)\\b", - "options": { - "case_sensitive": false, - "min_length": 3 - } - } - }, - "value": { - "operator": "match_regex", - "parameters": { - "regex": "\\b4\\d{3}(?:(?:\\d{4}(?:(?:,\\d{8})|(?:-\\d{8})|(?:\\s\\d{8})|(?:\\.\\d{8}))))\\b", - "options": { - "case_sensitive": false, - "min_length": 16 - } - } - }, - "tags": { - "type": "card", - "card_type": "visa", - "category": "payment" - } - }, - { - "id": "0o71SJxXQNK7Q6gMbBesFQ", - "name": "Visa Card Scanner (4x4 digits)", - "key": { - "operator": "match_regex", - "parameters": { - "regex": "\\b(?:card|cc|credit|debit|payment|amex|visa|mastercard|maestro|discover|jcb|diner)\\b", - "options": { - "case_sensitive": false, - "min_length": 3 - } - } - }, - "value": { - "operator": "match_regex", - "parameters": { - "regex": "\\b4\\d{3}(?:(?:,\\d{4}){3}|(?:\\s\\d{4}){3}|(?:\\.\\d{4}){3}|(?:-\\d{4}){3})\\b", - "options": { - "case_sensitive": false, - "min_length": 16 - } - } - }, - "tags": { - "type": "card", - "card_type": "visa", - "category": "payment" - } - }, - { - "id": "QrHD6AfgQm6z-j0wStxTvA", - "name": "Visa Card Scanner (1x15 & 1x16 & 1x19 digits)", - "key": { - "operator": "match_regex", - "parameters": { - "regex": "\\b(?:card|cc|credit|debit|payment|amex|visa|mastercard|maestro|discover|jcb|diner)\\b", - "options": { - "case_sensitive": false, - "min_length": 3 - } - } - }, - "value": { - "operator": "match_regex", - "parameters": { - "regex": "4[0-9]{12}(?:[0-9]{3})?", - "options": { - "case_sensitive": false, - "min_length": 13 - } - } - }, - "tags": { - "type": "card", - "card_type": "visa", - "category": "payment" - } - } - ] -} \ No newline at end of file diff --git a/vendor/github.com/DataDog/appsec-internal-go/httpsec/client_ip.go b/vendor/github.com/DataDog/appsec-internal-go/httpsec/client_ip.go deleted file mode 100644 index 3761a773..00000000 --- a/vendor/github.com/DataDog/appsec-internal-go/httpsec/client_ip.go +++ /dev/null @@ -1,126 +0,0 @@ -package httpsec - -import ( - "net" - "net/textproto" - "strings" - - "github.com/DataDog/appsec-internal-go/netip" -) - -const ( - // RemoteIPTag is the tag name used for the remote HTTP request IP address. - RemoteIPTag = "network.client.ip" - // ClientIPTag is the tag name used for the client IP deduced from the HTTP - // request headers with ClientIP(). - ClientIPTag = "http.client_ip" -) - -// ClientIPTags returns the resulting Datadog span tags `http.client_ip` -// containing the client IP and `network.client.ip` containing the remote IP. -// The tags are present only if a valid ip address has been returned by -// ClientIP(). -func ClientIPTags(remoteIP, clientIP netip.Addr) (tags map[string]string) { - remoteIPValid := remoteIP.IsValid() - clientIPValid := clientIP.IsValid() - if !remoteIPValid && !clientIPValid { - return nil - } - - tags = make(map[string]string, 2) - if remoteIPValid { - tags[RemoteIPTag] = remoteIP.String() - } - if clientIPValid { - tags[ClientIPTag] = clientIP.String() - } - return tags -} - -// ClientIP returns the first public IP address found in the given headers. If -// none is present, it returns the first valid IP address present, possibly -// being a local IP address. The remote address, when valid, is used as fallback -// when no IP address has been found at all. -func ClientIP(hdrs map[string][]string, hasCanonicalHeaders bool, remoteAddr string, monitoredHeaders []string) (remoteIP, clientIP netip.Addr) { - // Walk IP-related headers - var foundIP netip.Addr -headersLoop: - for _, headerName := range monitoredHeaders { - if hasCanonicalHeaders { - headerName = textproto.CanonicalMIMEHeaderKey(headerName) - } - - headerValues, exists := hdrs[headerName] - if !exists { - continue // this monitored header is not present - } - - // Assuming a list of comma-separated IP addresses, split them and build - // the list of values to try to parse as IP addresses - var ips []string - for _, ip := range headerValues { - ips = append(ips, strings.Split(ip, ",")...) - } - - // Look for the first valid or global IP address in the comma-separated list - for _, ipstr := range ips { - ip := parseIP(strings.TrimSpace(ipstr)) - if !ip.IsValid() { - continue - } - // Replace foundIP if still not valid in order to keep the oldest - if !foundIP.IsValid() { - foundIP = ip - } - if isGlobal(ip) { - foundIP = ip - break headersLoop - } - } - } - - // Decide which IP address is the client one by starting with the remote IP - if ip := parseIP(remoteAddr); ip.IsValid() { - remoteIP = ip - clientIP = ip - } - - // The IP address found in the headers supersedes a private remote IP address. - if foundIP.IsValid() && !isGlobal(remoteIP) || isGlobal(foundIP) { - clientIP = foundIP - } - - return remoteIP, clientIP -} - -func parseIP(s string) netip.Addr { - if ip, err := netip.ParseAddr(s); err == nil { - return ip - } - if h, _, err := net.SplitHostPort(s); err == nil { - if ip, err := netip.ParseAddr(h); err == nil { - return ip - } - } - return netip.Addr{} -} - -var ipv6SpecialNetworks = [...]netip.Prefix{ - netip.MustParsePrefix("fec0::/10"), // site local -} - -func isGlobal(ip netip.Addr) bool { - // IsPrivate also checks for ipv6 ULA. - // We care to check for these addresses are not considered public, hence not global. - // See https://www.rfc-editor.org/rfc/rfc4193.txt for more details. - isGlobal := ip.IsValid() && !ip.IsPrivate() && !ip.IsLoopback() && !ip.IsLinkLocalUnicast() - if !isGlobal || !ip.Is6() { - return isGlobal - } - for _, n := range ipv6SpecialNetworks { - if n.Contains(ip) { - return false - } - } - return isGlobal -} diff --git a/vendor/github.com/DataDog/appsec-internal-go/limiter/limiter.go b/vendor/github.com/DataDog/appsec-internal-go/limiter/limiter.go deleted file mode 100644 index f1f16d36..00000000 --- a/vendor/github.com/DataDog/appsec-internal-go/limiter/limiter.go +++ /dev/null @@ -1,147 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2022-present Datadog, Inc. - -// Package limiter provides simple rate limiting primitives, and an implementation of a token bucket rate limiter. -package limiter - -import ( - "time" - - "sync/atomic" -) - -// Limiter is used to abstract the rate limiter implementation to only expose the needed function for rate limiting. -// This is for example useful for testing, allowing us to use a modified rate limiter tuned for testing through the same -// interface. -type Limiter interface { - Allow() bool -} - -// TokenTicker is a thread-safe and lock-free rate limiter based on a token bucket. -// The idea is to have a goroutine that will update the bucket with fresh tokens at regular intervals using a time.Ticker. -// The advantage of using a goroutine here is that the implementation becomes easily thread-safe using a few -// atomic operations with little overhead overall. TokenTicker.Start() *should* be called before the first call to -// TokenTicker.Allow() and TokenTicker.Stop() *must* be called once done using. Note that calling TokenTicker.Allow() -// before TokenTicker.Start() is valid, but it means the bucket won't be refilling until the call to TokenTicker.Start() is made -type TokenTicker struct { - tokens atomic.Int64 // The amount of tokens currently available - maxTokens int64 // The maximum amount of tokens the bucket can hold - ticker *time.Ticker // The ticker used to update the bucket (nil if not started yet) - stopChan chan struct{} // The channel to stop the ticker updater (nil if not started yet) -} - -// NewTokenTicker is a utility function that allocates a token ticker, initializes necessary fields and returns it -func NewTokenTicker(tokens, maxTokens int64) *TokenTicker { - t := &TokenTicker{ - maxTokens: maxTokens, - } - t.tokens.Store(tokens) - return t -} - -// updateBucket performs a select loop to update the token amount in the bucket. -// Used in a goroutine by the rate limiter. -func (t *TokenTicker) updateBucket(startTime time.Time, ticksChan <-chan time.Time, stopChan <-chan struct{}, syncChan chan<- struct{}) { - nsPerToken := time.Second.Nanoseconds() / t.maxTokens - elapsedNs := int64(0) - prevStamp := startTime - - for { - select { - case <-stopChan: - if syncChan != nil { - close(syncChan) - } - return - case stamp, ok := <-ticksChan: - if !ok { - // The ticker has been closed, stamp is a zero-value, we ignore that. We nil-out the - // ticksChan so we don't get stuck endlessly reading from this closed channel again. - ticksChan = nil - continue - } - - // Compute the time in nanoseconds that passed between the previous timestamp and this one - // This will be used to know how many tokens can be added into the bucket depending on the limiter rate - elapsedNs += stamp.Sub(prevStamp).Nanoseconds() - if elapsedNs > t.maxTokens*nsPerToken { - elapsedNs = t.maxTokens * nsPerToken - } - prevStamp = stamp - // Update the number of tokens in the bucket if enough nanoseconds have passed - if elapsedNs >= nsPerToken { - // Atomic spin lock to make sure we don't race for `t.tokens` - for { - tokens := t.tokens.Load() - if tokens == t.maxTokens { - break // Bucket is already full, nothing to do - } - inc := elapsedNs / nsPerToken - // Make sure not to add more tokens than we are allowed to into the bucket - if tokens+inc > t.maxTokens { - inc -= (tokens + inc) % t.maxTokens - } - if t.tokens.CompareAndSwap(tokens, tokens+inc) { - // Keep track of remaining elapsed ns that were not taken into account for this computation, - // so that increment computation remains precise over time - elapsedNs = elapsedNs % nsPerToken - break - } - } - } - // Sync channel used to signify that the goroutine is done updating the bucket. Used for tests to guarantee - // that the goroutine ticked at least once. - if syncChan != nil { - syncChan <- struct{}{} - } - } - } -} - -// Start starts the ticker and launches the goroutine responsible for updating the token bucket. -// The ticker is set to tick at a fixed rate of 500us. -func (t *TokenTicker) Start() { - timeNow := time.Now() - t.ticker = time.NewTicker(500 * time.Microsecond) - t.start(timeNow, t.ticker.C, nil) -} - -// start is used for internal testing. Controlling the ticker means being able to test per-tick -// rather than per-duration, which is more reliable if the app is under a lot of stress. The -// syncChan, if non-nil, will receive one message after each tick from the ticksChan has been -// processed, providing a strong synchronization primitive. The limiter will close the syncChan when -// it is stopped, signaling that no further ticks will be processed. -func (t *TokenTicker) start(startTime time.Time, ticksChan <-chan time.Time, syncChan chan<- struct{}) { - t.stopChan = make(chan struct{}) - go t.updateBucket(startTime, ticksChan, t.stopChan, syncChan) -} - -// Stop shuts down the rate limiter, taking care stopping the ticker and closing all channels -func (t *TokenTicker) Stop() { - // Stop the ticker only if it has been instantiated (not the case when testing by calling start() directly) - if t.ticker != nil { - t.ticker.Stop() - t.ticker = nil // Ensure stop can be called multiple times idempotently. - } - // Close the stop channel only if it has been created. This covers the case where Stop() is called without any prior - // call to Start() - if t.stopChan != nil { - close(t.stopChan) - t.stopChan = nil // Ensure stop can be called multiple times idempotently. - } -} - -// Allow checks and returns whether a token can be retrieved from the bucket and consumed. -// Thread-safe. -func (t *TokenTicker) Allow() bool { - for { - tokens := t.tokens.Load() - if tokens == 0 { - return false - } else if t.tokens.CompareAndSwap(tokens, tokens-1) { - return true - } - } -} diff --git a/vendor/github.com/DataDog/appsec-internal-go/log/backend.go b/vendor/github.com/DataDog/appsec-internal-go/log/backend.go deleted file mode 100644 index b9d94f5c..00000000 --- a/vendor/github.com/DataDog/appsec-internal-go/log/backend.go +++ /dev/null @@ -1,138 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2022-present Datadog, Inc. - -package log - -import ( - "fmt" - "log" - "os" - "strings" -) - -var ( - backend = Backend{ - Trace: defaultWithLevel(logLevelTrace), - Debug: defaultWithLevel(logLevelDebug), - Info: defaultWithLevel(logLevelInfo), - Warn: defaultWithLevel(logLevelWarn), - Errorf: defaultErrorfWithLevel(logLevelError), - Criticalf: defaultErrorfWithLevel(logLevelCritical), - } - defaultBackendLogLevel = logLevelError -) - -type Backend struct { - Trace func(string, ...any) - Debug func(string, ...any) - Info func(string, ...any) - Warn func(string, ...any) - Errorf func(string, ...any) error - Criticalf func(string, ...any) error -} - -// SetBackend replaces the active log backend with the provided one. Any nil -// function in the new backend will silently ignore any message logged at that -// level. -func SetBackend(newBackend Backend) { - if newBackend.Trace == nil { - newBackend.Trace = noopLogger - } - if newBackend.Debug == nil { - newBackend.Debug = noopLogger - } - if newBackend.Info == nil { - newBackend.Info = noopLogger - } - if newBackend.Warn == nil { - newBackend.Warn = noopLogger - } - if newBackend.Errorf == nil { - newBackend.Errorf = fmt.Errorf - } - if newBackend.Criticalf == nil { - newBackend.Criticalf = fmt.Errorf - } - - backend = newBackend -} - -// defaultWithLevel returns the default log backend function for the provided -// logLevel. This returns a no-op function if the default backend logLevel does -// not enable logging at that level. -func defaultWithLevel(level logLevel) func(string, ...any) { - if defaultBackendLogLevel < level { - return noopLogger - } - return func(format string, args ...any) { - log.Printf(fmt.Sprintf("[%s] %s\n", level, format), args...) - } -} - -// defaultErrorfWithLevel returns the default log backend function for the -// provided error logLevel. -func defaultErrorfWithLevel(level logLevel) func(string, ...any) error { - if defaultBackendLogLevel < level { - return fmt.Errorf - } - return func(format string, args ...any) error { - err := fmt.Errorf(format, args...) - log.Printf("[%s] %v", level, err) - return err - } -} - -// noopLogger does nothing. -func noopLogger(string, ...any) { /* noop */ } - -type logLevel uint8 - -const ( - logLevelTrace logLevel = 1 << iota - logLevelDebug - logLevelInfo - logLevelWarn - logLevelError - logLevelCritical -) - -func (l logLevel) String() string { - switch l { - case logLevelTrace: - return "TRACE" - case logLevelDebug: - return "DEBUG" - case logLevelInfo: - return "INFO" - case logLevelWarn: - return "WARN" - case logLevelError: - return "ERROR" - case logLevelCritical: - return "CRITICAL" - default: - return "UNKNOWN" - } -} - -func init() { - ddLogLevel := os.Getenv("DD_LOG_LEVEL") - switch strings.ToUpper(ddLogLevel) { - case "TRACE": - defaultBackendLogLevel = logLevelTrace - case "DEBUG": - defaultBackendLogLevel = logLevelDebug - case "INFO": - defaultBackendLogLevel = logLevelInfo - case "WARN": - defaultBackendLogLevel = logLevelWarn - case "ERROR": - defaultBackendLogLevel = logLevelError - case "CRITICAL": - defaultBackendLogLevel = logLevelCritical - default: - // Ignore invalid/unexpected values - } -} diff --git a/vendor/github.com/DataDog/appsec-internal-go/log/log.go b/vendor/github.com/DataDog/appsec-internal-go/log/log.go deleted file mode 100644 index a34f578d..00000000 --- a/vendor/github.com/DataDog/appsec-internal-go/log/log.go +++ /dev/null @@ -1,45 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2022-present Datadog, Inc. - -// Package log provides a logging facility that is used by this library, and -// which can be configured to piggyback on another logging facility where -// available. If not explicitly configured, this will log messages using the Go -// standar library log package, filtered according to the log level set in the -// `DD_LOG_LEVEL` environment variable (or `ERROR` if none is set). -// -// Custom logger intergrations are configured by calling the SetBackend function. -package log - -// Trace logs a message with format using the TRACE log level. -func Trace(format string, args ...any) { - backend.Trace(format, args...) -} - -// Debug logs a message with format using the DEBUG log level. -func Debug(format string, args ...any) { - backend.Debug(format, args...) -} - -// Info logs a message with format using the INFO log level. -func Info(format string, args ...any) { - backend.Info(format, args...) -} - -// Warn logs a message with format using the WARN log level. -func Warn(format string, args ...any) { - backend.Warn(format, args...) -} - -// Errorf logs a message with format using the ERROR log level and returns an -// error containing the formatted log message. -func Errorf(format string, args ...any) error { - return backend.Errorf(format, args...) -} - -// Errorf logs a message with format using the CRITICAL log level and returns an -// error containing the formatted log message. -func Criticalf(format string, args ...any) error { - return backend.Criticalf(format, args...) -} diff --git a/vendor/github.com/DataDog/appsec-internal-go/netip/ip.go b/vendor/github.com/DataDog/appsec-internal-go/netip/ip.go deleted file mode 100644 index 99e1e627..00000000 --- a/vendor/github.com/DataDog/appsec-internal-go/netip/ip.go +++ /dev/null @@ -1,31 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2022 Datadog, Inc. - -package netip - -import "net/netip" - -// Addr wraps a netip.Addr value -type Addr = netip.Addr - -// Prefix wraps a netip.Prefix value -type Prefix = netip.Prefix - -var ( - // ParseAddr wraps the netip.ParseAddr function - ParseAddr = netip.ParseAddr - // MustParsePrefix wraps the netip.MustParsePrefix function - MustParsePrefix = netip.MustParsePrefix - // MustParseAddr wraps the netip.MustParseAddr function - MustParseAddr = netip.MustParseAddr - // AddrFrom16 wraps the netIP.AddrFrom16 function - AddrFrom16 = netip.AddrFrom16 -) - -// IPv4 wraps the netip.AddrFrom4 function -func IPv4(a, b, c, d byte) Addr { - e := [4]byte{a, b, c, d} - return netip.AddrFrom4(e) -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/LICENSE b/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/LICENSE deleted file mode 100644 index b370545b..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/LICENSE +++ /dev/null @@ -1,200 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2016-present Datadog, Inc. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/cache.go b/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/cache.go deleted file mode 100644 index 837b2b15..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/cache.go +++ /dev/null @@ -1,90 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package obfuscate - -import ( - "fmt" - "time" - - "github.com/outcaste-io/ristretto" -) - -// measuredCache is a wrapper on top of *ristretto.Cache which additionally -// sends metrics (hits and misses) every 10 seconds. -type measuredCache struct { - *ristretto.Cache - - // close allows sending shutdown notification. - close chan struct{} - statsd StatsClient -} - -// Close gracefully closes the cache when active. -func (c *measuredCache) Close() { - if c.Cache == nil { - return - } - c.close <- struct{}{} - <-c.close -} - -func (c *measuredCache) statsLoop() { - defer func() { - c.close <- struct{}{} - }() - tick := time.NewTicker(10 * time.Second) - defer tick.Stop() - mx := c.Cache.Metrics - for { - select { - case <-tick.C: - _ = c.statsd.Gauge("datadog.trace_agent.obfuscation.sql_cache.hits", float64(mx.Hits()), nil, 1) //nolint:errcheck - _ = c.statsd.Gauge("datadog.trace_agent.obfuscation.sql_cache.misses", float64(mx.Misses()), nil, 1) //nolint:errcheck - case <-c.close: - c.Cache.Close() - return - } - } -} - -type cacheOptions struct { - On bool - Statsd StatsClient -} - -// newMeasuredCache returns a new measuredCache. -func newMeasuredCache(opts cacheOptions) *measuredCache { - if !opts.On { - // a nil *ristretto.Cache is a no-op cache - return &measuredCache{} - } - cfg := &ristretto.Config{ - // We know that the maximum allowed resource length is 5K. This means that - // in 5MB we can store a minimum of 1000 queries. - MaxCost: 5000000, - - // An appromixated worst-case scenario when the cache is filled with small - // queries averaged as being of length 11 ("LOCK TABLES"), we would be able - // to fit 476K of them into 5MB of cost. - // - // We average it to 500K and multiply 10x as the documentation recommends. - NumCounters: 500000 * 10, - - BufferItems: 64, // default recommended value - Metrics: true, // enable hit/miss counters - } - cache, err := ristretto.NewCache(cfg) - if err != nil { - panic(fmt.Errorf("Error starting obfuscator query cache: %v", err)) - } - c := measuredCache{ - close: make(chan struct{}), - statsd: opts.Statsd, - Cache: cache, - } - go c.statsLoop() - return &c -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/credit_cards.go b/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/credit_cards.go deleted file mode 100644 index b172b2c1..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/credit_cards.go +++ /dev/null @@ -1,269 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package obfuscate - -import ( - "strings" -) - -// creditCard maintains credit card obfuscation state and processing. -type creditCard struct { - luhn bool -} - -func newCCObfuscator(config *CreditCardsConfig) *creditCard { - return &creditCard{ - luhn: config.Luhn, - } -} - -// ObfuscateCreditCardNumber obfuscates any "credit card like" numbers in value for keys not in the allow-list -func (o *Obfuscator) ObfuscateCreditCardNumber(key, val string) string { - switch key { - case "_sample_rate", - "_sampling_priority_v1", - "account_id", - "aws_account", - "error", - "error.msg", - "error.type", - "error.stack", - "env", - "graphql.field", - "graphql.query", - "graphql.type", - "graphql.operation.name", - "grpc.code", - "grpc.method", - "grpc.request", - "http.status_code", - "http.method", - "runtime-id", - "out.host", - "out.port", - "sampling.priority", - "span.type", - "span.name", - "service.name", - "service", - "sql.query", - "version": - // these tags are known to not be credit card numbers - return val - } - if strings.HasPrefix(key, "_") { - return val - } - if o.ccObfuscator.IsCardNumber(val) { - return "?" - } - return val -} - -// IsCardNumber checks if b could be a credit card number by checking the digit count and IIN prefix. -// If validateLuhn is true, the Luhn checksum is also applied to potential candidates. -func (cc *creditCard) IsCardNumber(b string) (ok bool) { - // - // Just credit card numbers for now, based on: - // • https://baymard.com/checkout-usability/credit-card-patterns - // • https://www.regular-expressions.info/creditcard.html - // - if len(b) == 0 { - return false - } - if len(b) < 12 { - // fast path: can not be a credit card - return false - } - if b[0] != ' ' && b[0] != '-' && (b[0] < '0' || b[0] > '9') { - // fast path: only valid characters are 0-9, space (" ") and dash("-") - return false - } - prefix := 0 // holds up to b[:6] digits as a numeric value (for example []byte{"523"} becomes int(523)) for checking prefixes - count := 0 // counts digits encountered - foundPrefix := false // reports whether we've detected a valid prefix - recdigit := func(_ byte) {} // callback on each found digit; no-op by default (we only need this for Luhn) - if cc.luhn { - // we need Luhn checksum validation, so we have to take additional action - // and record all digits found - buf := make([]byte, 0, len(b)) - recdigit = func(b byte) { buf = append(buf, b) } - defer func() { - if !ok { - // if isCardNumber returned false, it means that b can not be - // a credit card number - return - } - // potentially a credit card number, run the Luhn checksum - ok = luhnValid(buf) - }() - } -loop: - for i := range b { - // We traverse and search b for a valid IIN credit card prefix based - // on the digits found, ignoring spaces and dashes. - // Source: https://www.regular-expressions.info/creditcard.html - switch b[i] { - case ' ', '-': - // ignore space (' ') and dash ('-') - continue loop - } - if b[i] < '0' || b[i] > '9' { - // not a 0 to 9 digit; can not be a credit card number; abort - return false - } - count++ - recdigit(b[i]) - if !foundPrefix { - // we have not yet found a valid prefix so we convert the digits - // that we have so far into a numeric value: - prefix = prefix*10 + (int(b[i]) - '0') - maybe, yes := validCardPrefix(prefix) - if yes { - // we've found a valid prefix; continue counting - foundPrefix = true - } else if !maybe { - // this is not a valid prefix and we should not continue looking - return false - } - } - if count > 16 { - // too many digits - return false - } - } - if count < 12 { - // too few digits - return false - } - return foundPrefix -} - -// luhnValid checks that the number represented in the given string validates the Luhn Checksum algorithm. -// str is expected to contain exclusively digits at all positions. -// -// See: -// • https://en.wikipedia.org/wiki/Luhn_algorithm -// • https://dev.to/shiraazm/goluhn-a-simple-library-for-generating-calculating-and-verifying-luhn-numbers-588j -func luhnValid(str []byte) bool { - var ( - sum int - alt bool - ) - n := len(str) - for i := n - 1; i > -1; i-- { - if str[i] < '0' || str[i] > '9' { - return false // not a number! - } - mod := int(str[i] - 0x30) // convert byte to int - if alt { - mod *= 2 - if mod > 9 { - mod = (mod % 10) + 1 - } - } - alt = !alt - sum += mod - } - return sum%10 == 0 -} - -// validCardPrefix validates whether b is a valid card prefix. Maybe returns true if -// the prefix could be an IIN once more digits are revealed and yes reports whether -// b is a fully valid IIN. -// -// If yes is false and maybe is false, there is no reason to continue searching. The -// prefix is invalid. -// -// IMPORTANT: If adding new prefixes to this algorithm, make sure that you update -// the "maybe" clauses above, in the shorter prefixes than the one you are adding. -// This refers to the cases which return true, false. -// -// TODO(x): this whole code could be code generated from a prettier data structure. -// Ultimately, it could even be user-configurable. -func validCardPrefix(n int) (maybe, yes bool) { - // Validates IIN prefix possibilities - // Source: https://www.regular-expressions.info/creditcard.html - if n > 699999 { - // too long for any known prefix; stop looking - return false, false - } - if n < 10 { - switch n { - case 1, 4: - // 1 & 4 are valid IIN - return false, true - case 2, 3, 5, 6: - // 2, 3, 5, 6 could be the start of valid IIN - return true, false - default: - // invalid IIN - return false, false - } - } - if n < 100 { - if (n >= 34 && n <= 39) || - (n >= 51 && n <= 55) || - n == 62 || - n == 65 { - // 34-39, 51-55, 62, 65 are valid IIN - return false, true - } - if n == 30 || n == 63 || n == 64 || n == 50 || n == 60 || - (n >= 22 && n <= 27) || (n >= 56 && n <= 58) || (n >= 60 && n <= 69) { - // 30, 63, 64, 50, 60, 22-27, 56-58, 60-69 may end up as valid IIN - return true, false - } - } - if n < 1000 { - if (n >= 300 && n <= 305) || - (n >= 644 && n <= 649) || - n == 309 || - n == 636 { - // 300‑305, 309, 636, 644‑649 are valid IIN - return false, true - } - if (n >= 352 && n <= 358) || n == 501 || n == 601 || - (n >= 222 && n <= 272) || (n >= 500 && n <= 509) || - (n >= 560 && n <= 589) || (n >= 600 && n <= 699) { - // 352-358, 501, 601, 222-272, 500-509, 560-589, 600-699 may be a 4 or 6 digit IIN prefix - return true, false - } - } - if n < 10000 { - if (n >= 3528 && n <= 3589) || - n == 5019 || - n == 6011 { - // 3528‑3589, 5019, 6011 are valid IINs - return false, true - } - if (n >= 2221 && n <= 2720) || (n >= 5000 && n <= 5099) || - (n >= 5600 && n <= 5899) || (n >= 6000 && n <= 6999) { - // maybe a 6-digit IIN - return true, false - } - } - if n < 100000 { - if (n >= 22210 && n <= 27209) || - (n >= 50000 && n <= 50999) || - (n >= 56000 && n <= 58999) || - (n >= 60000 && n <= 69999) { - // maybe a 6-digit IIN - return true, false - } - } - if n < 1000000 { - if (n >= 222100 && n <= 272099) || - (n >= 500000 && n <= 509999) || - (n >= 560000 && n <= 589999) || - (n >= 600000 && n <= 699999) { - // 222100‑272099, 500000‑509999, 560000‑589999, 600000‑699999 are valid IIN - return false, true - } - } - // unknown IIN - return false, false -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/http.go b/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/http.go deleted file mode 100644 index d9a00084..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/http.go +++ /dev/null @@ -1,60 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package obfuscate - -import ( - "net/url" - "strings" -) - -// obfuscateUserInfo returns a URL string that obfuscates any userinfo by setting url.User to nil. -func obfuscateUserInfo(val string) string { - u, err := url.Parse(val) - if err != nil { - return val - } - u.User = nil - return u.String() -} - -// ObfuscateURLString obfuscates the given URL. It must be a valid URL. -func (o *Obfuscator) ObfuscateURLString(val string) string { - if !o.opts.HTTP.RemoveQueryString && !o.opts.HTTP.RemovePathDigits { - // nothing to do - return obfuscateUserInfo(val) - } - u, err := url.Parse(val) - if err != nil { - // should not happen for valid URLs, but better obfuscate everything - // rather than expose sensitive information when this option is on. - return "?" - } - u.User = nil - if o.opts.HTTP.RemoveQueryString && u.RawQuery != "" { - u.ForceQuery = true // add the '?' - u.RawQuery = "" - } - if o.opts.HTTP.RemovePathDigits { - segs := strings.Split(u.Path, "/") - var changed bool - for i, seg := range segs { - for _, ch := range []byte(seg) { - if ch >= '0' && ch <= '9' { - // we can not set the question mark directly here because the url - // package will escape it into %3F, so we use this placeholder and - // replace it further down. - segs[i] = "/REDACTED/" - changed = true - break - } - } - } - if changed { - u.Path = strings.Join(segs, "/") - } - } - return strings.Replace(u.String(), "/REDACTED/", "?", -1) -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/ip_address.go b/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/ip_address.go deleted file mode 100644 index 7639453b..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/ip_address.go +++ /dev/null @@ -1,168 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package obfuscate - -import ( - "net" - "net/netip" - "regexp" - "strings" -) - -// QuantizePeerIPAddresses quantizes a comma separated list of hosts. Each entry which is an IP address is replaced using quantizeIP. -// Duplicate entries post-quantization or collapsed into a single unique value. -// Entries which are not IP addresses are left unchanged. -// Comma-separated host lists are common for peer tags like peer.cassandra.contact.points, peer.couchbase.seed.nodes, peer.kafka.bootstrap.servers -func QuantizePeerIPAddresses(raw string) string { - values := strings.Split(raw, ",") - uniq := values[:0] - uniqSet := make(map[string]bool) - for _, v := range values { - q := quantizeIP(v) - if !uniqSet[q] { - uniqSet[q] = true - uniq = append(uniq, q) - } - } - return strings.Join(uniq, ",") -} - -var protocolRegex = regexp.MustCompile(`((?:dnspoll|ftp|file|http|https):/{2,3}).*`) - -var allowedIPAddresses = map[string]bool{ - // localhost - "127.0.0.1": true, - "::1": true, - // link-local cloud provider metadata server addresses - "169.254.169.254": true, - "fd00:ec2::254": true, - // ECS task metadata - "169.254.170.2": true, -} - -func splitPrefix(raw string) (prefix, after string) { - if after, ok := strings.CutPrefix(raw, "ip-"); ok { // AWS EC2 hostnames e.g. ip-10-123-4-567.ec2.internal - return "ip-", after - } - subMatches := protocolRegex.FindStringSubmatch(raw) - if len(subMatches) >= 2 { - prefix = subMatches[1] - } - return prefix, raw[len(prefix):] -} - -// quantizeIP quantizes the ip address in the provided string, only if it exactly matches an ip with an optional port -// if the string is not an ip then empty string is returned -func quantizeIP(raw string) string { - prefix, rawNoPrefix := splitPrefix(raw) - host, port, suffix := parseIPAndPort(rawNoPrefix) - if host == "" { - // not an ip address - return raw - } - if allowedIPAddresses[host] { - return raw - } - replacement := prefix + "blocked-ip-address" - if port != "" { - // we're keeping the original port as part of the key because ports are much lower cardinality - // than ip addresses, and they also tend to correspond more closely to a protocol (i.e. 443 is HTTPS) - // so it's likely safe and probably also useful to leave them in - replacement = replacement + ":" + port - } - return replacement + suffix -} - -// parseIPAndPort returns (host, port) if the host is a valid ip address with an optional port, else returns empty strings. -func parseIPAndPort(input string) (host, port, suffix string) { - host, port, err := net.SplitHostPort(input) - if err != nil { - host = input - } - if ok, i := isParseableIP(host); ok { - return host[:i], port, host[i:] - } - return "", "", "" -} - -func isParseableIP(s string) (parsed bool, lastIndex int) { - if len(s) == 0 { - return false, -1 - } - // Must start with a hex digit, or IPv6 can have a preceding ':' - switch s[0] { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'a', 'b', 'c', 'd', 'e', 'f', - 'A', 'B', 'C', 'D', 'E', 'F', - ':': - default: - return false, -1 - } - for i := 0; i < len(s); i++ { - switch s[i] { - case '.', '_', '-': - return parseIPv4(s, s[i]) - case ':': - // IPv6 - if _, err := netip.ParseAddr(s); err == nil { - return true, len(s) - } - return false, -1 - case '%': - // Assume that this was trying to be an IPv6 address with - // a zone specifier, but the address is missing. - return false, -1 - } - } - return false, -1 -} - -// parseIsIPv4 parses s as an IPv4 address and returns whether it is an IP address -// modified from netip to accept alternate separators besides '.' -// also modified to return true if s is an IPv4 address with trailing characters -func parseIPv4(s string, sep byte) (parsed bool, lastIndex int) { - var fields [4]uint8 - var val, pos int - var digLen int // number of digits in current octet - for i := 0; i < len(s); i++ { - if s[i] >= '0' && s[i] <= '9' { - if digLen == 1 && val == 0 { - return false, -1 - } - val = val*10 + int(s[i]) - '0' - digLen++ - if val > 255 { - return false, -1 - } - } else if s[i] == sep { - // .1.2.3 - // 1.2.3. - // 1..2.3 - if i == 0 || i == len(s)-1 || s[i-1] == sep { - return false, -1 - } - // 1.2.3.4.5 - if pos == 3 { - return true, i - } - fields[pos] = uint8(val) - pos++ - val = 0 - digLen = 0 - } else { - if pos == 3 && digLen > 0 { - fields[3] = uint8(val) - return true, i - } - return false, -1 - } - } - if pos < 3 { - return false, -1 - } - fields[3] = uint8(val) - return true, len(s) -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/json.go b/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/json.go deleted file mode 100644 index d2a60ec6..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/json.go +++ /dev/null @@ -1,234 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package obfuscate - -import ( - "bytes" - "strconv" - "strings" - "sync" -) - -// ObfuscateMongoDBString obfuscates the given MongoDB JSON query. -func (o *Obfuscator) ObfuscateMongoDBString(cmd string) string { - return obfuscateJSONString(cmd, o.mongo) -} - -// ObfuscateElasticSearchString obfuscates the given ElasticSearch JSON query. -func (o *Obfuscator) ObfuscateElasticSearchString(cmd string) string { - return obfuscateJSONString(cmd, o.es) -} - -// ObfuscateOpenSearchString obfuscates the given OpenSearch JSON query. -func (o *Obfuscator) ObfuscateOpenSearchString(cmd string) string { - return obfuscateJSONString(cmd, o.openSearch) -} - -// obfuscateJSONString obfuscates the given span's tag using the given obfuscator. If the obfuscator is -// nil it is considered disabled. -func obfuscateJSONString(cmd string, obfuscator *jsonObfuscator) string { - if obfuscator == nil || cmd == "" { - // obfuscator is disabled or string is empty - return cmd - } - out, _ := obfuscator.obfuscate([]byte(cmd)) - // we should accept whatever the obfuscator returns, even if it's an error: a parsing - // error simply means that the JSON was invalid, meaning that we've only obfuscated - // as much of it as we could. It is safe to accept the output, even if partial. - return out -} - -type jsonObfuscator struct { - buffPool sync.Pool // pool for fixed-length buffers (50 showed to be the optimal running benchmarks with different length) - statePool sync.Pool // pool for jsonObfuscatorState values - keepKeys map[string]bool // the values for these keys will not be obfuscated - transformKeys map[string]bool // the values for these keys pass through the transformer - transformer func(string) string -} - -func newJSONObfuscator(cfg *JSONConfig, o *Obfuscator) *jsonObfuscator { - keepValue := make(map[string]bool, len(cfg.KeepValues)) - for _, v := range cfg.KeepValues { - keepValue[v] = true - } - var ( - transformKeys map[string]bool - transformer func(string) string - ) - if len(cfg.ObfuscateSQLValues) > 0 { - transformer = sqlObfuscationTransformer(o) - transformKeys = make(map[string]bool, len(cfg.ObfuscateSQLValues)) - for _, v := range cfg.ObfuscateSQLValues { - transformKeys[v] = true - } - } - return &jsonObfuscator{ - keepKeys: keepValue, - transformKeys: transformKeys, - transformer: transformer, - buffPool: sync.Pool{ - New: func() any { - return new(bytes.Buffer) - }, - }, - statePool: sync.Pool{ - New: func() any { - return &jsonObfuscatorState{ - closures: []bool{}, - } - }, - }, - } -} - -func sqlObfuscationTransformer(o *Obfuscator) func(string) string { - return func(s string) string { - result, err := o.ObfuscateSQLString(s) - if err != nil { - o.log.Debugf("Failed to obfuscate SQL string '%s': %s", s, err.Error()) - // instead of returning an empty string we explicitly return an error string here within the result in order - // to surface the problem clearly to the user - return "Datadog-agent failed to obfuscate SQL string. Enable agent debug logs for more info." - } - return result.Query - } -} - -type jsonObfuscatorState struct { - scan scanner // scanner - closures []bool // closure stack, true if object (e.g. {[{ => []bool{true, false, true}) - keepDepth int // the depth at which we've stopped obfuscating - key bool // true if scanning a key - wiped bool // true if obfuscation string (`"?"`) was already written for current value - keeping bool // true if not obfuscating - transformingValue bool // true if collecting the next literal for transformation -} - -func (st *jsonObfuscatorState) reset() { - st.scan.reset() - st.closures = st.closures[0:0] - st.keepDepth = 0 - st.key = false - st.wiped = false - st.keeping = false - st.transformingValue = false -} - -// setKey verifies if we are currently scanning a key based on the current state -// and updates the state accordingly. It must be called only after a closure or a -// value scan has ended. -func (st *jsonObfuscatorState) setKey() { - n := len(st.closures) - st.key = n == 0 || st.closures[n-1] // true if we are at top level or in an object - st.wiped = false -} - -func (p *jsonObfuscator) obfuscate(data []byte) (string, error) { - if len(data) == 0 { - return "", nil - } - - var out strings.Builder - st := p.statePool.Get().(*jsonObfuscatorState) - st.reset() - - buf := p.buffPool.Get().(*bytes.Buffer) // recording current token - buf.Reset() - defer func() { - p.statePool.Put(st) - p.buffPool.Put(buf) - }() - - out.Grow(len(data)) - buf.Grow(len(data) / 10) // Benchmarks show that the optimal point is a tenth of the data length. - for _, c := range data { - st.scan.bytes++ - op := st.scan.step(&st.scan, c) - depth := len(st.closures) - switch op { - case scanBeginObject: - // object begins: { - st.closures = append(st.closures, true) - st.setKey() - st.transformingValue = false - case scanBeginArray: - // array begins: [ - st.closures = append(st.closures, false) - st.setKey() - st.transformingValue = false - case scanEndArray, scanEndObject: - // array or object closing - if n := len(st.closures) - 1; n > 0 { - st.closures = st.closures[:n] - } - fallthrough - case scanObjectValue, scanArrayValue: - // done scanning value - st.setKey() - if st.transformingValue && p.transformer != nil { - v, err := strconv.Unquote(buf.String()) - if err != nil { - v = buf.String() - } - result := p.transformer(v) - out.WriteByte('"') - out.WriteString(result) - out.WriteByte('"') - st.transformingValue = false - buf.Reset() - } else if st.keeping && depth < st.keepDepth { - st.keeping = false - } - case scanBeginLiteral, scanContinue: - // starting or continuing a literal - if st.transformingValue { - buf.WriteByte(c) - continue - } else if st.key { - // it's a key - buf.WriteByte(c) - } else if !st.keeping { - // it's a value we're not keeping - if !st.wiped { - out.WriteString(`"?"`) - st.wiped = true - } - continue - } - case scanObjectKey: - // done scanning key - k := string(bytes.Trim(buf.Bytes(), `"`)) - if !st.keeping && p.keepKeys[k] { - // we should not obfuscate values of this key - st.keeping = true - st.keepDepth = depth + 1 - } else if !st.transformingValue && p.transformer != nil && p.transformKeys[k] { - // the string value immediately following this key will be passed through the value transformer - // if anything other than a literal is found then sql obfuscation is stopped and json obfuscation - // proceeds as usual - st.transformingValue = true - } - buf.Reset() - st.key = false - case scanSkipSpace: - continue - case scanError: - // we've encountered an error, mark that there might be more JSON - // using the ellipsis and return whatever we've managed to obfuscate - // thus far. - out.WriteString("...") - return out.String(), st.scan.err - } - out.WriteByte(c) - } - if st.scan.eof() == scanError { - // if an error occurred it's fine, simply add the ellipsis to indicate - // that the input has been truncated. - out.Write([]byte("...")) - return out.String(), st.scan.err - } - return out.String(), nil -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/json_scanner.go b/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/json_scanner.go deleted file mode 100644 index 6c490bbc..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/json_scanner.go +++ /dev/null @@ -1,560 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// -// The code that follows is copied from go/src/encoding/json/scanner.go -// It may contain minor edits, such as allowing multiple JSON objects within -// the same input string (see stateEndTop) -// - -package obfuscate - -import "strconv" - -// A SyntaxError is a description of a JSON syntax error. -type SyntaxError struct { - msg string // description of error - Offset int64 // error occurred after reading Offset bytes -} - -func (e *SyntaxError) Error() string { return e.msg } - -// A scanner is a JSON scanning state machine. -// Callers call scan.reset() and then pass bytes in one at a time -// by calling scan.step(&scan, c) for each byte. -// The return value, referred to as an opcode, tells the -// caller about significant parsing events like beginning -// and ending literals, objects, and arrays, so that the -// caller can follow along if it wishes. -// The return value scanEnd indicates that a single top-level -// JSON value has been completed, *before* the byte that -// just got passed in. (The indication must be delayed in order -// to recognize the end of numbers: is 123 a whole value or -// the beginning of 12345e+6?). -type scanner struct { - // The step is a func to be called to execute the next transition. - // Also tried using an integer constant and a single func - // with a switch, but using the func directly was 10% faster - // on a 64-bit Mac Mini, and it's nicer to read. - step func(*scanner, byte) int - - // Reached end of top-level value. - endTop bool - - // Stack of what we're in the middle of - array values, object keys, object values. - parseState []int - - // Error that happened, if any. - err error - - // total bytes consumed, updated by decoder.Decode - bytes int64 -} - -// These values are returned by the state transition functions -// assigned to scanner.state and the method scanner.eof. -// They give details about the current state of the scan that -// callers might be interested to know about. -// It is okay to ignore the return value of any particular -// call to scanner.state: if one call returns scanError, -// every subsequent call will return scanError too. -const ( - // Continue. - scanContinue = iota // uninteresting byte - scanBeginLiteral // end implied by next result != scanContinue - scanBeginObject // begin object - scanObjectKey // just finished object key (string) - scanObjectValue // just finished non-last object value - scanEndObject // end object (implies scanObjectValue if possible) - scanBeginArray // begin array - scanArrayValue // just finished array value - scanEndArray // end array (implies scanArrayValue if possible) - scanSkipSpace // space byte; can skip; known to be last "continue" result - - // Stop. - scanEnd // top-level value ended *before* this byte; known to be first "stop" result - scanError // hit an error, scanner.err. -) - -// These values are stored in the parseState stack. -// They give the current state of a composite value -// being scanned. If the parser is inside a nested value -// the parseState describes the nested state, outermost at entry 0. -const ( - parseObjectKey = iota // parsing object key (before colon) - parseObjectValue // parsing object value (after colon) - parseArrayValue // parsing array value -) - -// reset prepares the scanner for use. -// It must be called before calling s.step. -func (s *scanner) reset() { - s.step = stateBeginValue - s.parseState = s.parseState[0:0] - s.err = nil - s.endTop = false -} - -// eof tells the scanner that the end of input has been reached. -// It returns a scan status just as s.step does. -func (s *scanner) eof() int { - if s.err != nil { - return scanError - } - if s.endTop { - return scanEnd - } - s.step(s, ' ') - if s.endTop { - return scanEnd - } - if s.err == nil { - s.err = &SyntaxError{"unexpected end of JSON input", s.bytes} - } - return scanError -} - -// pushParseState pushes a new parse state p onto the parse stack. -func (s *scanner) pushParseState(p int) { - s.parseState = append(s.parseState, p) -} - -// popParseState pops a parse state (already obtained) off the stack -// and updates s.step accordingly. -func (s *scanner) popParseState() { - n := len(s.parseState) - 1 - if n == 0 { - s.step = stateEndTop - s.endTop = true - return - } - s.parseState = s.parseState[0:n] - s.step = stateEndValue -} - -func isSpace(c byte) bool { - return c == ' ' || c == '\t' || c == '\r' || c == '\n' -} - -// stateBeginValueOrEmpty is the state after reading `[`. -func stateBeginValueOrEmpty(s *scanner, c byte) int { - if c <= ' ' && isSpace(c) { - return scanSkipSpace - } - if c == ']' { - return stateEndValue(s, c) - } - return stateBeginValue(s, c) -} - -// stateBeginValue is the state at the beginning of the input. -func stateBeginValue(s *scanner, c byte) int { - if c <= ' ' && isSpace(c) { - return scanSkipSpace - } - switch c { - case '{': - s.step = stateBeginStringOrEmpty - s.pushParseState(parseObjectKey) - return scanBeginObject - case '[': - s.step = stateBeginValueOrEmpty - s.pushParseState(parseArrayValue) - return scanBeginArray - case '"': - s.step = stateInString - return scanBeginLiteral - case '-': - s.step = stateNeg - return scanBeginLiteral - case '0': // beginning of 0.123 - s.step = state0 - return scanBeginLiteral - case 't': // beginning of true - s.step = stateT - return scanBeginLiteral - case 'f': // beginning of false - s.step = stateF - return scanBeginLiteral - case 'n': // beginning of null - s.step = stateN - return scanBeginLiteral - } - if '1' <= c && c <= '9' { // beginning of 1234.5 - s.step = state1 - return scanBeginLiteral - } - return s.error(c, "looking for beginning of value") -} - -// stateBeginStringOrEmpty is the state after reading `{`. -func stateBeginStringOrEmpty(s *scanner, c byte) int { - if c <= ' ' && isSpace(c) { - return scanSkipSpace - } - n := len(s.parseState) - if c == '}' && n > 0 { - s.parseState[n-1] = parseObjectValue - return stateEndValue(s, c) - } - return stateBeginString(s, c) -} - -// stateBeginString is the state after reading `{"key": value,`. -func stateBeginString(s *scanner, c byte) int { - if c <= ' ' && isSpace(c) { - return scanSkipSpace - } - if c == '"' { - s.step = stateInString - return scanBeginLiteral - } - return s.error(c, "looking for beginning of object key string") -} - -// stateEndValue is the state after completing a value, -// such as after reading `{}` or `true` or `["x"`. -func stateEndValue(s *scanner, c byte) int { - n := len(s.parseState) - if n == 0 { - // Completed top-level before the current byte. - s.step = stateEndTop - s.endTop = true - return stateEndTop(s, c) - } - if c <= ' ' && isSpace(c) { - s.step = stateEndValue - return scanSkipSpace - } - ps := s.parseState[n-1] - switch ps { - case parseObjectKey: - if c == ':' { - s.parseState[n-1] = parseObjectValue - s.step = stateBeginValue - return scanObjectKey - } - return s.error(c, "after object key") - case parseObjectValue: - if c == ',' { - s.parseState[n-1] = parseObjectKey - s.step = stateBeginString - return scanObjectValue - } - if c == '}' { - s.popParseState() - return scanEndObject - } - return s.error(c, "after object key:value pair") - case parseArrayValue: - if c == ',' { - s.step = stateBeginValue - return scanArrayValue - } - if c == ']' { - s.popParseState() - return scanEndArray - } - return s.error(c, "after array element") - } - return s.error(c, "") -} - -// stateEndTop is the state after finishing the top-level value, -// such as after reading `{}` or `[1,2,3]`. -// Only space characters should be seen now. -func stateEndTop(s *scanner, c byte) int { - if c != ' ' && c != '\t' && c != '\r' && c != '\n' { - // The former behaviour has been removed. Now, if anything - // other than whitespace follows, we assume a new JSON string - // might be starting. This allows us to continue obfuscating - // further strings in cases where there are multiple JSON - // objects enumerated sequentially within the same input. - // This is a common case for ElasticSearch response bodies. - s.reset() - return s.step(s, c) - } - return scanEnd -} - -// stateInString is the state after reading `"`. -func stateInString(s *scanner, c byte) int { - if c == '"' { - s.step = stateEndValue - return scanContinue - } - if c == '\\' { - s.step = stateInStringEsc - return scanContinue - } - if c < 0x20 { - return s.error(c, "in string literal") - } - return scanContinue -} - -// stateInStringEsc is the state after reading `"\` during a quoted string. -func stateInStringEsc(s *scanner, c byte) int { - switch c { - case 'b', 'f', 'n', 'r', 't', '\\', '/', '"': - s.step = stateInString - return scanContinue - case 'u': - s.step = stateInStringEscU - return scanContinue - } - return s.error(c, "in string escape code") -} - -// stateInStringEscU is the state after reading `"\u` during a quoted string. -func stateInStringEscU(s *scanner, c byte) int { - if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' { - s.step = stateInStringEscU1 - return scanContinue - } - // numbers - return s.error(c, "in \\u hexadecimal character escape") -} - -// stateInStringEscU1 is the state after reading `"\u1` during a quoted string. -func stateInStringEscU1(s *scanner, c byte) int { - if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' { - s.step = stateInStringEscU12 - return scanContinue - } - // numbers - return s.error(c, "in \\u hexadecimal character escape") -} - -// stateInStringEscU12 is the state after reading `"\u12` during a quoted string. -func stateInStringEscU12(s *scanner, c byte) int { - if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' { - s.step = stateInStringEscU123 - return scanContinue - } - // numbers - return s.error(c, "in \\u hexadecimal character escape") -} - -// stateInStringEscU123 is the state after reading `"\u123` during a quoted string. -func stateInStringEscU123(s *scanner, c byte) int { - if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' { - s.step = stateInString - return scanContinue - } - // numbers - return s.error(c, "in \\u hexadecimal character escape") -} - -// stateNeg is the state after reading `-` during a number. -func stateNeg(s *scanner, c byte) int { - if c == '0' { - s.step = state0 - return scanContinue - } - if '1' <= c && c <= '9' { - s.step = state1 - return scanContinue - } - return s.error(c, "in numeric literal") -} - -// state1 is the state after reading a non-zero integer during a number, -// such as after reading `1` or `100` but not `0`. -func state1(s *scanner, c byte) int { - if '0' <= c && c <= '9' { - s.step = state1 - return scanContinue - } - return state0(s, c) -} - -// state0 is the state after reading `0` during a number. -func state0(s *scanner, c byte) int { - if c == '.' { - s.step = stateDot - return scanContinue - } - if c == 'e' || c == 'E' { - s.step = stateE - return scanContinue - } - return stateEndValue(s, c) -} - -// stateDot is the state after reading the integer and decimal point in a number, -// such as after reading `1.`. -func stateDot(s *scanner, c byte) int { - if '0' <= c && c <= '9' { - s.step = stateDot0 - return scanContinue - } - return s.error(c, "after decimal point in numeric literal") -} - -// stateDot0 is the state after reading the integer, decimal point, and subsequent -// digits of a number, such as after reading `3.14`. -func stateDot0(s *scanner, c byte) int { - if '0' <= c && c <= '9' { - return scanContinue - } - if c == 'e' || c == 'E' { - s.step = stateE - return scanContinue - } - return stateEndValue(s, c) -} - -// stateE is the state after reading the mantissa and e in a number, -// such as after reading `314e` or `0.314e`. -func stateE(s *scanner, c byte) int { - if c == '+' || c == '-' { - s.step = stateESign - return scanContinue - } - return stateESign(s, c) -} - -// stateESign is the state after reading the mantissa, e, and sign in a number, -// such as after reading `314e-` or `0.314e+`. -func stateESign(s *scanner, c byte) int { - if '0' <= c && c <= '9' { - s.step = stateE0 - return scanContinue - } - return s.error(c, "in exponent of numeric literal") -} - -// stateE0 is the state after reading the mantissa, e, optional sign, -// and at least one digit of the exponent in a number, -// such as after reading `314e-2` or `0.314e+1` or `3.14e0`. -func stateE0(s *scanner, c byte) int { - if '0' <= c && c <= '9' { - return scanContinue - } - return stateEndValue(s, c) -} - -// stateT is the state after reading `t`. -func stateT(s *scanner, c byte) int { - if c == 'r' { - s.step = stateTr - return scanContinue - } - return s.error(c, "in literal true (expecting 'r')") -} - -// stateTr is the state after reading `tr`. -func stateTr(s *scanner, c byte) int { - if c == 'u' { - s.step = stateTru - return scanContinue - } - return s.error(c, "in literal true (expecting 'u')") -} - -// stateTru is the state after reading `tru`. -func stateTru(s *scanner, c byte) int { - if c == 'e' { - s.step = stateEndValue - return scanContinue - } - return s.error(c, "in literal true (expecting 'e')") -} - -// stateF is the state after reading `f`. -func stateF(s *scanner, c byte) int { - if c == 'a' { - s.step = stateFa - return scanContinue - } - return s.error(c, "in literal false (expecting 'a')") -} - -// stateFa is the state after reading `fa`. -func stateFa(s *scanner, c byte) int { - if c == 'l' { - s.step = stateFal - return scanContinue - } - return s.error(c, "in literal false (expecting 'l')") -} - -// stateFal is the state after reading `fal`. -func stateFal(s *scanner, c byte) int { - if c == 's' { - s.step = stateFals - return scanContinue - } - return s.error(c, "in literal false (expecting 's')") -} - -// stateFals is the state after reading `fals`. -func stateFals(s *scanner, c byte) int { - if c == 'e' { - s.step = stateEndValue - return scanContinue - } - return s.error(c, "in literal false (expecting 'e')") -} - -// stateN is the state after reading `n`. -func stateN(s *scanner, c byte) int { - if c == 'u' { - s.step = stateNu - return scanContinue - } - return s.error(c, "in literal null (expecting 'u')") -} - -// stateNu is the state after reading `nu`. -func stateNu(s *scanner, c byte) int { - if c == 'l' { - s.step = stateNul - return scanContinue - } - return s.error(c, "in literal null (expecting 'l')") -} - -// stateNul is the state after reading `nul`. -func stateNul(s *scanner, c byte) int { - if c == 'l' { - s.step = stateEndValue - return scanContinue - } - return s.error(c, "in literal null (expecting 'l')") -} - -// stateError is the state after reaching a syntax error, -// such as after reading `[1}` or `5.1.2`. -func stateError(_ *scanner, _ byte) int { - return scanError -} - -// error records an error and switches to the error state. -func (s *scanner) error(c byte, context string) int { - s.step = stateError - s.err = &SyntaxError{"invalid character " + quoteChar(c) + " " + context, s.bytes} - return scanError -} - -// quoteChar formats c as a quoted character literal -func quoteChar(c byte) string { - // special cases - different from quoted strings - if c == '\'' { - return `'\''` - } - if c == '"' { - return `'"'` - } - - // use quoted string with different quotation marks - s := strconv.Quote(string(c)) - return "'" + s[1:len(s)-1] + "'" -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/memcached.go b/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/memcached.go deleted file mode 100644 index 5fd821fd..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/memcached.go +++ /dev/null @@ -1,26 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package obfuscate - -import ( - "strings" -) - -// ObfuscateMemcachedString obfuscates the Memcached command cmd. -func (o *Obfuscator) ObfuscateMemcachedString(cmd string) string { - if !o.opts.Memcached.KeepCommand { - // If the command shouldn't be kept, then the entire tag will - // be dropped. - return "" - } - // All memcached commands end with new lines [1]. In the case of storage - // commands, key values follow after. Knowing this, all we have to do - // to obfuscate the values is to remove everything that follows - // a new line. For non-storage commands, this will have no effect. - // [1]: https://github.com/memcached/memcached/blob/master/doc/protocol.txt - truncated := strings.SplitN(cmd, "\r\n", 2)[0] - return strings.TrimSpace(truncated) -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/obfuscate.go b/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/obfuscate.go deleted file mode 100644 index fd5ac9dd..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/obfuscate.go +++ /dev/null @@ -1,354 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -// Package obfuscate implements quantizing and obfuscating of tags and resources for -// a set of spans matching a certain criteria. -// -// This module is used in the Datadog Agent, the Go tracing client (dd-trace-go) and in the -// OpenTelemetry Collector Datadog exporter./ End-user behavior is stable, but there are no -// stability guarantees on its public Go API. Nonetheless, if editing try to avoid breaking -// API changes if possible and double check the API usage on all module dependents. -package obfuscate - -import ( - "bytes" - - "go.uber.org/atomic" - - "github.com/DataDog/datadog-go/v5/statsd" -) - -// Obfuscator quantizes and obfuscates spans. The obfuscator is not safe for -// concurrent use. -type Obfuscator struct { - opts *Config - es *jsonObfuscator // nil if disabled - openSearch *jsonObfuscator // nil if disabled - mongo *jsonObfuscator // nil if disabled - sqlExecPlan *jsonObfuscator // nil if disabled - sqlExecPlanNormalize *jsonObfuscator // nil if disabled - ccObfuscator *creditCard // nil if disabled - // sqlLiteralEscapes reports whether we should treat escape characters literally or as escape characters. - // Different SQL engines behave in different ways and the tokenizer needs to be generic. - sqlLiteralEscapes *atomic.Bool - // queryCache keeps a cache of already obfuscated queries. - queryCache *measuredCache - log Logger -} - -// Logger is able to log certain log messages. -type Logger interface { - // Debugf logs the given message using the given format. - Debugf(format string, params ...interface{}) -} - -type noopLogger struct{} - -func (noopLogger) Debugf(_ string, _ ...interface{}) {} - -// setSQLLiteralEscapes sets whether or not escape characters should be treated literally by the SQL obfuscator. -func (o *Obfuscator) setSQLLiteralEscapes(ok bool) { - if ok { - o.sqlLiteralEscapes.Store(true) - } else { - o.sqlLiteralEscapes.Store(false) - } -} - -// useSQLLiteralEscapes reports whether escape characters will be treated literally by the SQL obfuscator. -// Some SQL engines require it and others don't. It will be detected as SQL queries are being obfuscated -// through calls to ObfuscateSQLString and automatically set for future. -func (o *Obfuscator) useSQLLiteralEscapes() bool { - return o.sqlLiteralEscapes.Load() -} - -// Config holds the configuration for obfuscating sensitive data for various span types. -type Config struct { - // SQL holds the obfuscation configuration for SQL queries. - SQL SQLConfig - - // ES holds the obfuscation configuration for ElasticSearch bodies. - ES JSONConfig - - // OpenSearch holds the obfuscation configuration for OpenSearch bodies. - OpenSearch JSONConfig - - // Mongo holds the obfuscation configuration for MongoDB queries. - Mongo JSONConfig - - // SQLExecPlan holds the obfuscation configuration for SQL Exec Plans. This is strictly for safety related obfuscation, - // not normalization. Normalization of exec plans is configured in SQLExecPlanNormalize. - SQLExecPlan JSONConfig - - // SQLExecPlanNormalize holds the normalization configuration for SQL Exec Plans. - SQLExecPlanNormalize JSONConfig - - // HTTP holds the obfuscation settings for HTTP URLs. - HTTP HTTPConfig - - // Redis holds the obfuscation settings for Redis commands. - Redis RedisConfig - - // Memcached holds the obfuscation settings for Memcached commands. - Memcached MemcachedConfig - - // Memcached holds the obfuscation settings for obfuscation of CC numbers in meta. - CreditCard CreditCardsConfig - - // Statsd specifies the statsd client to use for reporting metrics. - Statsd StatsClient - - // Logger specifies the logger to use when outputting messages. - // If unset, no logs will be outputted. - Logger Logger -} - -// StatsClient implementations are able to emit stats. -type StatsClient interface { - // Gauge reports a gauge stat with the given name, value, tags and rate. - Gauge(name string, value float64, tags []string, rate float64) error -} - -// ObfuscationMode specifies the obfuscation mode to use for go-sqllexer pkg. -type ObfuscationMode string - -// ObfuscationMode valid values -const ( - NormalizeOnly = ObfuscationMode("normalize_only") - ObfuscateOnly = ObfuscationMode("obfuscate_only") - ObfuscateAndNormalize = ObfuscationMode("obfuscate_and_normalize") -) - -// SQLConfig holds the config for obfuscating SQL. -type SQLConfig struct { - // DBMS identifies the type of database management system (e.g. MySQL, Postgres, and SQL Server). - // Valid values for this can be found at https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/database.md#connection-level-attributes - DBMS string `json:"dbms"` - - // TableNames specifies whether the obfuscator should also extract the table names that a query addresses, - // in addition to obfuscating. - TableNames bool `json:"table_names" yaml:"table_names"` - - // CollectCommands specifies whether the obfuscator should extract and return commands as SQL metadata when obfuscating. - CollectCommands bool `json:"collect_commands" yaml:"collect_commands"` - - // CollectComments specifies whether the obfuscator should extract and return comments as SQL metadata when obfuscating. - CollectComments bool `json:"collect_comments" yaml:"collect_comments"` - - // CollectProcedures specifies whether the obfuscator should extract and return procedure names as SQL metadata when obfuscating. - CollectProcedures bool `json:"collect_procedures" yaml:"collect_procedures"` - - // ReplaceDigits specifies whether digits in table names and identifiers should be obfuscated. - ReplaceDigits bool `json:"replace_digits" yaml:"replace_digits"` - - // KeepSQLAlias reports whether SQL aliases ("AS") should be truncated. - KeepSQLAlias bool `json:"keep_sql_alias"` - - // DollarQuotedFunc reports whether to treat "$func$" delimited dollar-quoted strings - // differently and not obfuscate them as a string. To read more about dollar quoted - // strings see: - // - // https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-DOLLAR-QUOTING - DollarQuotedFunc bool `json:"dollar_quoted_func"` - - // ObfuscationMode specifies the obfuscation mode to use for go-sqllexer pkg. - // When specified, obfuscator will attempt to use go-sqllexer pkg to obfuscate (and normalize) SQL queries. - // Valid values are "normalize_only", "obfuscate_only", "obfuscate_and_normalize" - ObfuscationMode ObfuscationMode `json:"obfuscation_mode" yaml:"obfuscation_mode"` - - // RemoveSpaceBetweenParentheses specifies whether to remove spaces between parentheses. - // By default, spaces are inserted between parentheses during normalization. - // This option is only valid when ObfuscationMode is "normalize_only" or "obfuscate_and_normalize". - RemoveSpaceBetweenParentheses bool `json:"remove_space_between_parentheses" yaml:"remove_space_between_parentheses"` - - // KeepNull specifies whether to disable obfuscate NULL value with ?. - // This option is only valid when ObfuscationMode is "obfuscate_only" or "obfuscate_and_normalize". - KeepNull bool `json:"keep_null" yaml:"keep_null"` - - // KeepBoolean specifies whether to disable obfuscate boolean value with ?. - // This option is only valid when ObfuscationMode is "obfuscate_only" or "obfuscate_and_normalize". - KeepBoolean bool `json:"keep_boolean" yaml:"keep_boolean"` - - // KeepPositionalParameter specifies whether to disable obfuscate positional parameter with ?. - // This option is only valid when ObfuscationMode is "obfuscate_only" or "obfuscate_and_normalize". - KeepPositionalParameter bool `json:"keep_positional_parameter" yaml:"keep_positional_parameter"` - - // KeepTrailingSemicolon specifies whether to keep trailing semicolon. - // By default, trailing semicolon is removed during normalization. - // This option is only valid when ObfuscationMode is "normalize_only" or "obfuscate_and_normalize". - KeepTrailingSemicolon bool `json:"keep_trailing_semicolon" yaml:"keep_trailing_semicolon"` - - // KeepIdentifierQuotation specifies whether to keep identifier quotation, e.g. "my_table" or [my_table]. - // By default, identifier quotation is removed during normalization. - // This option is only valid when ObfuscationMode is "normalize_only" or "obfuscate_and_normalize". - KeepIdentifierQuotation bool `json:"keep_identifier_quotation" yaml:"keep_identifier_quotation"` - - // Cache reports whether the obfuscator should use a LRU look-up cache for SQL obfuscations. - Cache bool -} - -// SQLMetadata holds metadata collected throughout the obfuscation of an SQL statement. It is only -// collected when enabled via SQLConfig. -type SQLMetadata struct { - // Size holds the byte size of the metadata collected. - Size int64 - // TablesCSV is a comma-separated list of tables that the query addresses. - TablesCSV string `json:"tables_csv"` - // Commands holds commands executed in an SQL statement. - // e.g. SELECT, UPDATE, INSERT, DELETE, etc. - Commands []string `json:"commands"` - // Comments holds comments in an SQL statement. - Comments []string `json:"comments"` - // Procedures holds procedure names in an SQL statement. - Procedures []string `json:"procedures"` -} - -// HTTPConfig holds the configuration settings for HTTP obfuscation. -type HTTPConfig struct { - // RemoveQueryStrings determines query strings to be removed from HTTP URLs. - RemoveQueryString bool `mapstructure:"remove_query_string" json:"remove_query_string"` - - // RemovePathDigits determines digits in path segments to be obfuscated. - RemovePathDigits bool `mapstructure:"remove_paths_with_digits" json:"remove_path_digits"` -} - -// RedisConfig holds the configuration settings for Redis obfuscation -type RedisConfig struct { - // Enabled specifies whether this feature should be enabled. - Enabled bool `mapstructure:"enabled"` - - // RemoveAllArgs specifies whether all arguments to a given Redis - // command should be obfuscated. - RemoveAllArgs bool `mapstructure:"remove_all_args"` -} - -// MemcachedConfig holds the configuration settings for Memcached obfuscation -type MemcachedConfig struct { - // Enabled specifies whether this feature should be enabled. - Enabled bool `mapstructure:"enabled"` - - // KeepCommand specifies whether the command of a given Memcached - // query should be kept. If false, the entire tag is removed. - KeepCommand bool `mapstructure:"keep_command"` -} - -// JSONConfig holds the obfuscation configuration for sensitive -// data found in JSON objects. -type JSONConfig struct { - // Enabled will specify whether obfuscation should be enabled. - Enabled bool `mapstructure:"enabled"` - - // KeepValues will specify a set of keys for which their values will - // not be obfuscated. - KeepValues []string `mapstructure:"keep_values"` - - // ObfuscateSQLValues will specify a set of keys for which their values - // will be passed through SQL obfuscation - ObfuscateSQLValues []string `mapstructure:"obfuscate_sql_values"` -} - -// CreditCardsConfig holds the configuration for credit card obfuscation in -// (Meta) tags. -type CreditCardsConfig struct { - // Enabled specifies whether this feature should be enabled. - Enabled bool `mapstructure:"enabled"` - - // Luhn specifies whether Luhn checksum validation should be enabled. - // https://dev.to/shiraazm/goluhn-a-simple-library-for-generating-calculating-and-verifying-luhn-numbers-588j - // It reduces false positives, but increases the CPU time X3. - Luhn bool `mapstructure:"luhn"` -} - -// NewObfuscator creates a new obfuscator -func NewObfuscator(cfg Config) *Obfuscator { - if cfg.Logger == nil { - cfg.Logger = noopLogger{} - } - o := Obfuscator{ - opts: &cfg, - queryCache: newMeasuredCache(cacheOptions{On: cfg.SQL.Cache, Statsd: cfg.Statsd}), - sqlLiteralEscapes: atomic.NewBool(false), - log: cfg.Logger, - } - if cfg.ES.Enabled { - o.es = newJSONObfuscator(&cfg.ES, &o) - } - if cfg.OpenSearch.Enabled { - o.openSearch = newJSONObfuscator(&cfg.OpenSearch, &o) - } - if cfg.Mongo.Enabled { - o.mongo = newJSONObfuscator(&cfg.Mongo, &o) - } - if cfg.SQLExecPlan.Enabled { - o.sqlExecPlan = newJSONObfuscator(&cfg.SQLExecPlan, &o) - } - if cfg.SQLExecPlanNormalize.Enabled { - o.sqlExecPlanNormalize = newJSONObfuscator(&cfg.SQLExecPlanNormalize, &o) - } - if cfg.CreditCard.Enabled { - o.ccObfuscator = newCCObfuscator(&cfg.CreditCard) - } - if cfg.Statsd == nil { - cfg.Statsd = &statsd.NoOpClient{} - } - return &o -} - -// Stop cleans up after a finished Obfuscator. -func (o *Obfuscator) Stop() { - o.queryCache.Close() -} - -// compactWhitespaces compacts all whitespaces in t. -func compactWhitespaces(t string) string { - n := len(t) - r := make([]byte, n) - spaceCode := uint8(32) - isWhitespace := func(char uint8) bool { return char == spaceCode } - nr := 0 - offset := 0 - for i := 0; i < n; i++ { - if isWhitespace(t[i]) { - copy(r[nr:], t[nr+offset:i]) - r[i-offset] = spaceCode - nr = i + 1 - offset - for j := i + 1; j < n; j++ { - if !isWhitespace(t[j]) { - offset += j - i - 1 - i = j - break - } else if j == n-1 { - offset += j - i - i = j - break - } - } - } - } - copy(r[nr:], t[nr+offset:n]) - r = r[:n-offset] - return string(bytes.Trim(r, " ")) -} - -// replaceDigits replaces consecutive sequences of digits with '?', -// example: "jobs_2020_1597876964" --> "jobs_?_?" -func replaceDigits(buffer []byte) []byte { - scanningDigit := false - filtered := buffer[:0] - for _, b := range buffer { - // digits are encoded as 1 byte in utf8 - if isDigit(rune(b)) { - if scanningDigit { - continue - } - scanningDigit = true - filtered = append(filtered, byte('?')) - continue - } - scanningDigit = false - filtered = append(filtered, b) - } - return filtered -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/redis.go b/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/redis.go deleted file mode 100644 index 70a1323e..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/redis.go +++ /dev/null @@ -1,301 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package obfuscate - -import ( - "strings" -) - -// redisTruncationMark is used as suffix by tracing libraries to indicate that a -// command was truncated. -const redisTruncationMark = "..." - -const maxRedisNbCommands = 3 - -// Redis commands consisting in 2 words -var redisCompoundCommandSet = map[string]bool{ - "CLIENT": true, "CLUSTER": true, "COMMAND": true, "CONFIG": true, "DEBUG": true, "SCRIPT": true} - -// QuantizeRedisString returns a quantized version of a Redis query. -// -// TODO(gbbr): Refactor this method to use the tokenizer and -// remove "compactWhitespaces". This method is buggy when commands -// contain quoted strings with newlines. -func (*Obfuscator) QuantizeRedisString(query string) string { - query = compactWhitespaces(query) - - var resource strings.Builder - truncated := false - nbCmds := 0 - - for len(query) > 0 && nbCmds < maxRedisNbCommands { - var rawLine string - - // Read the next command - idx := strings.IndexByte(query, '\n') - if idx == -1 { - rawLine = query - query = "" - } else { - rawLine = query[:idx] - query = query[idx+1:] - } - - line := strings.Trim(rawLine, " ") - if len(line) == 0 { - continue - } - - // Parse arguments - args := strings.SplitN(line, " ", 3) - - if strings.HasSuffix(args[0], redisTruncationMark) { - truncated = true - continue - } - - command := strings.ToUpper(args[0]) - - if redisCompoundCommandSet[command] && len(args) > 1 { - if strings.HasSuffix(args[1], redisTruncationMark) { - truncated = true - continue - } - - command += " " + strings.ToUpper(args[1]) - } - - // Write the command representation - resource.WriteByte(' ') - resource.WriteString(command) - - nbCmds++ - truncated = false - } - - if nbCmds == maxRedisNbCommands || truncated { - resource.WriteString(" ...") - } - - return strings.Trim(resource.String(), " ") -} - -// ObfuscateRedisString obfuscates the given Redis command. -func (*Obfuscator) ObfuscateRedisString(rediscmd string) string { - t := newRedisTokenizer([]byte(rediscmd)) - var ( - str strings.Builder - cmd string - args []string - ) - for { - tok, typ, done := t.scan() - switch typ { - case redisTokenCommand: - // new command starting - if cmd != "" { - // a previous command was buffered, obfuscate it - obfuscateRedisCmd(&str, cmd, args...) - str.WriteByte('\n') - } - cmd = tok - args = args[:0] - case redisTokenArgument: - args = append(args, tok) - } - if done { - // last command - obfuscateRedisCmd(&str, cmd, args...) - break - } - } - return str.String() -} - -func obfuscateRedisCmd(out *strings.Builder, cmd string, args ...string) { - out.WriteString(cmd) - if len(args) == 0 { - return - } - out.WriteByte(' ') - - switch strings.ToUpper(cmd) { - case "AUTH": - // Obfuscate everything after command - // • AUTH password - if len(args) > 0 { - args[0] = "?" - args = args[:1] - } - - case "APPEND", "GETSET", "LPUSHX", "GEORADIUSBYMEMBER", "RPUSHX", - "SET", "SETNX", "SISMEMBER", "ZRANK", "ZREVRANK", "ZSCORE": - // Obfuscate 2nd argument: - // • APPEND key value - // • GETSET key value - // • LPUSHX key value - // • GEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key] - // • RPUSHX key value - // • SET key value [expiration EX seconds|PX milliseconds] [NX|XX] - // • SETNX key value - // • SISMEMBER key member - // • ZRANK key member - // • ZREVRANK key member - // • ZSCORE key member - obfuscateRedisArgN(args, 1) - - case "HSET", "HSETNX", "LREM", "LSET", "SETBIT", "SETEX", "PSETEX", - "SETRANGE", "ZINCRBY", "SMOVE", "RESTORE": - // Obfuscate 3rd argument: - // • HSET key field value - // • HSETNX key field value - // • LREM key count value - // • LSET key index value - // • SETBIT key offset value - // • SETEX key seconds value - // • PSETEX key milliseconds value - // • SETRANGE key offset value - // • ZINCRBY key increment member - // • SMOVE source destination member - // • RESTORE key ttl serialized-value [REPLACE] - obfuscateRedisArgN(args, 2) - - case "LINSERT": - // Obfuscate 4th argument: - // • LINSERT key BEFORE|AFTER pivot value - obfuscateRedisArgN(args, 3) - - case "GEOHASH", "GEOPOS", "GEODIST", "LPUSH", "RPUSH", "SREM", - "ZREM", "SADD": - // Obfuscate all arguments after the first one. - // • GEOHASH key member [member ...] - // • GEOPOS key member [member ...] - // • GEODIST key member1 member2 [unit] - // • LPUSH key value [value ...] - // • RPUSH key value [value ...] - // • SREM key member [member ...] - // • ZREM key member [member ...] - // • SADD key member [member ...] - if len(args) > 1 { - args[1] = "?" - args = args[:2] - } - - case "GEOADD": - // Obfuscating every 3rd argument starting from first - // • GEOADD key longitude latitude member [longitude latitude member ...] - obfuscateRedisArgsStep(args, 1, 3) - - case "HMSET": - // Every 2nd argument starting from first. - // • HMSET key field value [field value ...] - obfuscateRedisArgsStep(args, 1, 2) - - case "MSET", "MSETNX": - // Every 2nd argument starting from command. - // • MSET key value [key value ...] - // • MSETNX key value [key value ...] - obfuscateRedisArgsStep(args, 0, 2) - - case "CONFIG": - // Obfuscate 2nd argument to SET sub-command. - // • CONFIG SET parameter value - if strings.ToUpper(args[0]) == "SET" { - obfuscateRedisArgN(args, 2) - } - - case "BITFIELD": - // Obfuscate 3rd argument to SET sub-command: - // • BITFIELD key [GET type offset] [SET type offset value] [INCRBY type offset increment] [OVERFLOW WRAP|SAT|FAIL] - var n int - for i, arg := range args { - if strings.ToUpper(arg) == "SET" { - n = i - } - if n > 0 && i-n == 3 { - args[i] = "?" - break - } - } - - case "ZADD": - // Obfuscate every 2nd argument after potential optional ones. - // • ZADD key [NX|XX] [CH] [INCR] score member [score member ...] - var i int - loop: - for i = range args { - if i == 0 { - continue // key - } - switch args[i] { - case "NX", "XX", "CH", "INCR": - // continue - default: - break loop - } - } - obfuscateRedisArgsStep(args, i, 2) - - default: - // Obfuscate nothing. - } - out.WriteString(strings.Join(args, " ")) -} - -// RemoveAllRedisArgs will take in a command and obfuscate all arguments following -// the command, regardless of if the command is valid Redis or not -func (*Obfuscator) RemoveAllRedisArgs(rediscmd string) string { - fullCmd := strings.Fields(rediscmd) - if len(fullCmd) == 0 { - return "" - } - cmd, args := fullCmd[0], fullCmd[1:] - - var out strings.Builder - out.WriteString(cmd) - if len(args) == 0 { - return out.String() - } - - out.WriteByte(' ') - switch strings.ToUpper(cmd) { - case "BITFIELD": - out.WriteString("?") - for _, a := range args { - arg := strings.ToUpper(a) - if arg == "SET" || arg == "GET" || arg == "INCRBY" { - out.WriteString(strings.Join([]string{"", a, "?"}, " ")) - } - } - case "CONFIG": - arg := strings.ToUpper(args[0]) - if arg == "GET" || arg == "SET" || arg == "RESETSTAT" || arg == "REWRITE" { - out.WriteString(strings.Join([]string{args[0], "?"}, " ")) - } else { - out.WriteString("?") - } - default: - out.WriteString("?") - } - - return out.String() -} - -func obfuscateRedisArgN(args []string, n int) { - if len(args) > n { - args[n] = "?" - } -} - -func obfuscateRedisArgsStep(args []string, start, step int) { - if start+step-1 >= len(args) { - // can't reach target - return - } - for i := start + step - 1; i < len(args); i += step { - args[i] = "?" - } -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/redis_tokenizer.go b/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/redis_tokenizer.go deleted file mode 100644 index d4ef2dc3..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/redis_tokenizer.go +++ /dev/null @@ -1,187 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package obfuscate - -import ( - "bytes" - "strings" -) - -// redisTokenType specifies the token type returned by the tokenizer. -type redisTokenType int - -const ( - // redisTokenCommand is a command token. For compound tokens, it is - // only the first part up to a space. - redisTokenCommand redisTokenType = iota - - // redisTokenArgument is an argument token. - redisTokenArgument -) - -// String implements fmt.Stringer. -func (t redisTokenType) String() string { - return map[redisTokenType]string{ - redisTokenCommand: "command", - redisTokenArgument: "argument", - }[t] -} - -// redisTokenizer tokenizes a Redis command string. The string can be on -// multiple lines. The tokenizer is capable of parsing quoted strings and escape -// sequences inside them. -type redisTokenizer struct { - data []byte - ch byte - off int - done bool - state redisParseState -} - -// redisParseState specifies the current state of the tokenizer. -type redisParseState int - -const ( - // redisStateCommand specifies that we are about to parse a command. - // It is usually the state at the beginning of the scan or after a - // new line. - redisStateCommand redisParseState = iota - - // redisStateArgument specifies that we are about to parse an argument - // to a command or the rest of the tokens in a compound command. - redisStateArgument -) - -// newRedisTokenizer returns a new tokenizer for the given data. -func newRedisTokenizer(data []byte) *redisTokenizer { - return &redisTokenizer{ - data: bytes.TrimSpace(data), - off: -1, - state: redisStateCommand, - } -} - -// scan returns the next token, it's type and a bool. The boolean specifies if -// the returned token was the last one. -func (t *redisTokenizer) scan() (tok string, typ redisTokenType, done bool) { - switch t.state { - case redisStateCommand: - return t.scanCommand() - default: - return t.scanArg() - } -} - -// next advances the scanner to the next character. -func (t *redisTokenizer) next() { - t.off++ - if t.off <= len(t.data)-1 { - t.ch = t.data[t.off] - return - } - t.done = true -} - -// scanCommand scans a command from the buffer. -func (t *redisTokenizer) scanCommand() (tok string, typ redisTokenType, done bool) { - var ( - str strings.Builder - started bool - ) - for { - t.next() - if t.done { - return str.String(), typ, t.done - } - switch t.ch { - case ' ': - if !started { - // skip spaces preceding token - t.skipSpace() - break - } - // done scanning command - t.state = redisStateArgument - t.skipSpace() - return str.String(), redisTokenCommand, t.done - case '\n': - return str.String(), redisTokenCommand, t.done - default: - str.WriteByte(t.ch) - } - started = true - } -} - -// scanArg scans an argument from the buffer. -func (t *redisTokenizer) scanArg() (tok string, typ redisTokenType, done bool) { - var ( - str strings.Builder - quoted bool // in quoted string - escape bool // escape sequence - ) - for { - t.next() - if t.done { - return str.String(), redisTokenArgument, t.done - } - switch t.ch { - case '\\': - str.WriteByte('\\') - if !escape { - // next character could be escaped - escape = true - continue - } - case '\n': - if !quoted { - // last argument, new command follows - t.state = redisStateCommand - return str.String(), redisTokenArgument, t.done - } - str.WriteByte('\n') - case '"': - str.WriteByte('"') - if !escape { - // this quote wasn't escaped, toggle quoted mode - quoted = !quoted - } - case ' ': - if !quoted { - t.skipSpace() - return str.String(), redisTokenArgument, t.done - } - str.WriteByte(' ') - default: - str.WriteByte(t.ch) - } - escape = false - } -} - -// unread is the reverse of next, unreading a character. -func (t *redisTokenizer) unread() { - if t.off < 1 { - return - } - t.off-- - t.ch = t.data[t.off] -} - -// skipSpace moves the cursor forward until it meets the last space -// in a sequence of contiguous spaces. -func (t *redisTokenizer) skipSpace() { - for t.ch == ' ' || t.ch == '\t' || t.ch == '\r' && !t.done { - t.next() - } - if t.ch == '\n' { - // next token is a command - t.state = redisStateCommand - } else { - // don't steal the first non-space character - t.unread() - } -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/sql.go b/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/sql.go deleted file mode 100644 index 18fc120a..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/sql.go +++ /dev/null @@ -1,502 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package obfuscate - -import ( - "bytes" - "errors" - "fmt" - "strings" - "unicode" - "unicode/utf8" - - sqllexer "github.com/DataDog/go-sqllexer" -) - -var questionMark = []byte("?") - -// metadataFinderFilter is a filter which attempts to collect metadata from a query, such as comments and tables. -// It is meant to run before all the other filters. -type metadataFinderFilter struct { - collectTableNames bool - collectCommands bool - collectComments bool - replaceDigits bool - - // size holds the byte size of the metadata collected by the filter. - size int64 - // tablesSeen keeps track of unique table names encountered by the filter. - tablesSeen map[string]struct{} - // tablesCSV specifies a comma-separated list of tables. - tablesCSV strings.Builder - // commands keeps track of commands encountered by the filter. - commands []string - // comments keeps track of comments encountered by the filter. - comments []string -} - -func (f *metadataFinderFilter) Filter(token, lastToken TokenKind, buffer []byte) (TokenKind, []byte, error) { - if f.collectComments && token == Comment { - // A comment with line-breaks will be brought to a single line. - comment := strings.TrimSpace(strings.Replace(string(buffer), "\n", " ", -1)) - f.size += int64(len(comment)) - f.comments = append(f.comments, comment) - } - if f.collectCommands { - switch token { - case Select, Update, Insert, Delete, Join, Alter, Drop, Create, Grant, Revoke, Commit, Begin, Truncate: - command := strings.ToUpper(token.String()) - f.size += int64(len(command)) - f.commands = append(f.commands, command) - } - } - if f.collectTableNames { - switch lastToken { - case From, Join: - // SELECT ... FROM [tableName] - // DELETE FROM [tableName] - // ... JOIN [tableName] - if r, _ := utf8.DecodeRune(buffer); !unicode.IsLetter(r) { - // first character in buffer is not a letter; we might have a nested - // query like SELECT * FROM (SELECT ...) - break - } - fallthrough - case Update, Into: - // UPDATE [tableName] - // INSERT INTO [tableName] - tableName := string(buffer) - if f.replaceDigits { - tableNameCopy := make([]byte, len(buffer)) - copy(tableNameCopy, buffer) - tableName = string(replaceDigits(tableNameCopy)) - } - f.storeTableName(tableName) - return TableName, buffer, nil - } - } - return token, buffer, nil -} - -func (f *metadataFinderFilter) storeTableName(name string) { - if _, ok := f.tablesSeen[name]; ok { - return - } - if f.tablesSeen == nil { - f.tablesSeen = make(map[string]struct{}, 1) - } - f.tablesSeen[name] = struct{}{} - if f.tablesCSV.Len() > 0 { - f.size++ - f.tablesCSV.WriteByte(',') - } - f.size += int64(len(name)) - f.tablesCSV.WriteString(name) -} - -// Results returns metadata collected by the filter for an SQL statement. -func (f *metadataFinderFilter) Results() SQLMetadata { - return SQLMetadata{ - Size: f.size, - TablesCSV: f.tablesCSV.String(), - Commands: f.commands, - Comments: f.comments, - } -} - -// Reset implements tokenFilter. -func (f *metadataFinderFilter) Reset() { - for k := range f.tablesSeen { - delete(f.tablesSeen, k) - } - f.size = 0 - f.tablesCSV.Reset() - f.commands = f.commands[:0] - f.comments = f.comments[:0] -} - -// discardFilter is a token filter which discards certain elements from a query, such as -// comments and AS aliases by returning a nil buffer. -type discardFilter struct { - keepSQLAlias bool -} - -// Filter the given token so that a `nil` slice is returned if the token is in the token filtered list. -func (f *discardFilter) Filter(token, lastToken TokenKind, buffer []byte) (TokenKind, []byte, error) { - // filters based on previous token - switch lastToken { - case FilteredBracketedIdentifier: - if token != ']' { - // we haven't found the closing bracket yet, keep going - if token != ID { - // the token between the brackets *must* be an identifier, - // otherwise the query is invalid. - return LexError, nil, fmt.Errorf("expected identifier in bracketed filter, got %d", token) - } - return FilteredBracketedIdentifier, nil, nil - } - fallthrough - case As: - if token == '[' { - // the identifier followed by AS is an MSSQL bracketed identifier - // and will continue to be discarded until we find the corresponding - // closing bracket counter-part. See GitHub issue DataDog/datadog-trace-agent#475. - return FilteredBracketedIdentifier, nil, nil - } - if f.keepSQLAlias { - return token, buffer, nil - } - return Filtered, nil, nil - } - - // filters based on the current token; if the next token should be ignored, - // return the same token value (not FilteredGroupable) and nil - switch token { - case Comment: - return Filtered, nil, nil - case ';': - return markFilteredGroupable(token), nil, nil - case As: - if !f.keepSQLAlias { - return As, nil, nil - } - fallthrough - default: - return token, buffer, nil - } -} - -// Reset implements tokenFilter. -func (f *discardFilter) Reset() {} - -// replaceFilter is a token filter which obfuscates strings and numbers in queries by replacing them -// with the "?" character. -type replaceFilter struct { - replaceDigits bool -} - -// Filter the given token so that it will be replaced if in the token replacement list -func (f *replaceFilter) Filter(token, lastToken TokenKind, buffer []byte) (tokenType TokenKind, tokenBytes []byte, err error) { - switch lastToken { - case Savepoint: - return markFilteredGroupable(token), questionMark, nil - case '=': - switch token { - case DoubleQuotedString: - // double-quoted strings after assignments are eligible for obfuscation - return markFilteredGroupable(token), questionMark, nil - } - } - switch token { - case DollarQuotedString, String, Number, Null, Variable, PreparedStatement, BooleanLiteral, EscapeSequence: - return markFilteredGroupable(token), questionMark, nil - case '?': - // Cases like 'ARRAY [ ?, ? ]' should be collapsed into 'ARRAY [ ? ]' - return markFilteredGroupable(token), questionMark, nil - case TableName, ID: - if f.replaceDigits { - return token, replaceDigits(buffer), nil - } - fallthrough - default: - return token, buffer, nil - } -} - -// Reset implements tokenFilter. -func (f *replaceFilter) Reset() {} - -// groupingFilter is a token filter which groups together items replaced by the replaceFilter. It is meant -// to run immediately after it. -type groupingFilter struct { - groupFilter int // counts the number of values, e.g. 3 = ?, ?, ? - groupMulti int // counts the number of groups, e.g. 2 = (?, ?), (?, ?, ?) -} - -// Filter the given token so that it will be discarded if a grouping pattern -// has been recognized. A grouping is composed by items like: -// - '( ?, ?, ? )' -// - '( ?, ? ), ( ?, ? )' -func (f *groupingFilter) Filter(token, lastToken TokenKind, buffer []byte) (tokenType TokenKind, tokenBytes []byte, err error) { - // increasing the number of groups means that we're filtering an entire group - // because it can be represented with a single '( ? )' - if (lastToken == '(' && isFilteredGroupable(token)) || (token == '(' && f.groupMulti > 0) { - f.groupMulti++ - } - - // Potential commands that could indicate the start of a subquery. - isStartOfSubquery := token == Select || token == Delete || token == Update || token == ID - - switch { - case f.groupMulti > 0 && lastToken == FilteredGroupableParenthesis && isStartOfSubquery: - // this is the start of a new group that seems to be a nested query; - // cancel grouping. - f.Reset() - return token, append([]byte("( "), buffer...), nil - case isFilteredGroupable(token): - // the previous filter has dropped this token so we should start - // counting the group filter so that we accept only one '?' for - // the same group - f.groupFilter++ - - if f.groupFilter > 1 { - return markFilteredGroupable(token), nil, nil - } - case f.groupFilter > 0 && (token == ',' || token == '?'): - // if we are in a group drop all commas - return markFilteredGroupable(token), nil, nil - case f.groupMulti > 1: - // drop all tokens since we're in a counting group - // and they're duplicated - return markFilteredGroupable(token), nil, nil - case token != ',' && token != '(' && token != ')' && !isFilteredGroupable(token): - // when we're out of a group reset the filter state - f.Reset() - } - - return token, buffer, nil -} - -// isFilteredGroupable reports whether token is to be considered filtered groupable. -func isFilteredGroupable(token TokenKind) bool { - switch token { - case FilteredGroupable, FilteredGroupableParenthesis: - return true - default: - return false - } -} - -// markFilteredGroupable returns the appropriate TokenKind to mark this token as -// filtered groupable. -func markFilteredGroupable(token TokenKind) TokenKind { - switch token { - case '(': - return FilteredGroupableParenthesis - default: - return FilteredGroupable - } -} - -// Reset resets the groupingFilter so that it may be used again. -func (f *groupingFilter) Reset() { - f.groupFilter = 0 - f.groupMulti = 0 -} - -// ObfuscateSQLString quantizes and obfuscates the given input SQL query string. Quantization removes -// some elements such as comments and aliases and obfuscation attempts to hide sensitive information -// in strings and numbers by redacting them. -func (o *Obfuscator) ObfuscateSQLString(in string) (*ObfuscatedQuery, error) { - return o.ObfuscateSQLStringWithOptions(in, &o.opts.SQL) -} - -// ObfuscateSQLStringWithOptions accepts an optional SQLOptions to change the behavior of the obfuscator -// to quantize and obfuscate the given input SQL query string. Quantization removes some elements such as comments -// and aliases and obfuscation attempts to hide sensitive information in strings and numbers by redacting them. -func (o *Obfuscator) ObfuscateSQLStringWithOptions(in string, opts *SQLConfig) (*ObfuscatedQuery, error) { - if opts.ObfuscationMode != "" { - // If obfuscation mode is specified, we will use go-sqllexer pkg - // to obfuscate (and normalize) the query. - return o.ObfuscateWithSQLLexer(in, opts) - } - - if v, ok := o.queryCache.Get(in); ok { - return v.(*ObfuscatedQuery), nil - } - oq, err := o.obfuscateSQLString(in, opts) - if err != nil { - return oq, err - } - o.queryCache.Set(in, oq, oq.Cost()) - return oq, nil -} - -func (o *Obfuscator) obfuscateSQLString(in string, opts *SQLConfig) (*ObfuscatedQuery, error) { - lesc := o.useSQLLiteralEscapes() - tok := NewSQLTokenizer(in, lesc, opts) - out, err := attemptObfuscation(tok) - if err != nil && tok.SeenEscape() { - // If the tokenizer failed, but saw an escape character in the process, - // try again treating escapes differently - tok = NewSQLTokenizer(in, !lesc, opts) - if out, err2 := attemptObfuscation(tok); err2 == nil { - // If the second attempt succeeded, change the default behavior so that - // on the next run we get it right in the first run. - o.setSQLLiteralEscapes(!lesc) - return out, nil - } - } - return out, err -} - -// ObfuscatedQuery specifies information about an obfuscated SQL query. -type ObfuscatedQuery struct { - Query string `json:"query"` // the obfuscated SQL query - Metadata SQLMetadata `json:"metadata"` // metadata extracted from the SQL query -} - -// Cost returns the number of bytes needed to store all the fields -// of this ObfuscatedQuery. -func (oq *ObfuscatedQuery) Cost() int64 { - return int64(len(oq.Query)) + oq.Metadata.Size -} - -// attemptObfuscation attempts to obfuscate the SQL query loaded into the tokenizer, using the given set of filters. -func attemptObfuscation(tokenizer *SQLTokenizer) (*ObfuscatedQuery, error) { - var ( - out = bytes.NewBuffer(make([]byte, 0, len(tokenizer.buf))) - err error - lastToken TokenKind - metadata = metadataFinderFilter{ - collectTableNames: tokenizer.cfg.TableNames, - collectCommands: tokenizer.cfg.CollectCommands, - collectComments: tokenizer.cfg.CollectComments, - replaceDigits: tokenizer.cfg.ReplaceDigits, - } - discard = discardFilter{keepSQLAlias: tokenizer.cfg.KeepSQLAlias} - replace = replaceFilter{replaceDigits: tokenizer.cfg.ReplaceDigits} - grouping groupingFilter - ) - defer metadata.Reset() - // call Scan() function until tokens are available or if a LEX_ERROR is raised. After - // retrieving a token, send it to the tokenFilter chains so that the token is discarded - // or replaced. - for { - token, buff := tokenizer.Scan() - if token == EndChar { - break - } - if token == LexError { - return nil, fmt.Errorf("%v", tokenizer.Err()) - } - - if token, buff, err = metadata.Filter(token, lastToken, buff); err != nil { - return nil, err - } - if token, buff, err = discard.Filter(token, lastToken, buff); err != nil { - return nil, err - } - if token, buff, err = replace.Filter(token, lastToken, buff); err != nil { - return nil, err - } - if token, buff, err = grouping.Filter(token, lastToken, buff); err != nil { - return nil, err - } - if buff != nil { - if out.Len() != 0 { - switch token { - case ',': - case '=': - if lastToken == ':' { - // do not add a space before an equals if a colon was - // present before it. - break - } - fallthrough - default: - out.WriteRune(' ') - } - } - out.Write(buff) - } - lastToken = token - } - if out.Len() == 0 { - return nil, errors.New("result is empty") - } - return &ObfuscatedQuery{ - Query: out.String(), - Metadata: metadata.Results(), - }, nil -} - -// ObfuscateSQLExecPlan obfuscates query conditions in the provided JSON encoded execution plan. If normalize=True, -// then cost and row estimates are also obfuscated away. -func (o *Obfuscator) ObfuscateSQLExecPlan(jsonPlan string, normalize bool) (string, error) { - if normalize { - return o.sqlExecPlanNormalize.obfuscate([]byte(jsonPlan)) - } - return o.sqlExecPlan.obfuscate([]byte(jsonPlan)) -} - -// ObfuscateWithSQLLexer obfuscates the given SQL query using the go-sqllexer package. -// If ObfuscationMode is set to ObfuscateOnly, the query will be obfuscated without normalizing it. -func (o *Obfuscator) ObfuscateWithSQLLexer(in string, opts *SQLConfig) (*ObfuscatedQuery, error) { - if opts.ObfuscationMode != NormalizeOnly && opts.ObfuscationMode != ObfuscateOnly && opts.ObfuscationMode != ObfuscateAndNormalize { - return nil, fmt.Errorf("invalid obfuscation mode: %s", opts.ObfuscationMode) - } - - var obfuscator *sqllexer.Obfuscator - - if opts.ObfuscationMode == ObfuscateOnly || opts.ObfuscationMode == ObfuscateAndNormalize { - obfuscator = sqllexer.NewObfuscator( - sqllexer.WithReplaceDigits(opts.ReplaceDigits), - sqllexer.WithDollarQuotedFunc(opts.DollarQuotedFunc), - sqllexer.WithReplacePositionalParameter(!opts.KeepPositionalParameter), - sqllexer.WithReplaceBoolean(!opts.KeepBoolean), - sqllexer.WithReplaceNull(!opts.KeepNull), - ) - } - - if opts.ObfuscationMode == ObfuscateOnly { - // Obfuscate the query without normalizing it. - out := obfuscator.Obfuscate(in, sqllexer.WithDBMS(sqllexer.DBMSType(opts.DBMS))) - return &ObfuscatedQuery{ - Query: out, - }, nil - } - - // we only want to cache normalized queries - if v, ok := o.queryCache.Get(in); ok { - return v.(*ObfuscatedQuery), nil - } - - // Obfuscate the query and normalize it. - normalizer := sqllexer.NewNormalizer( - sqllexer.WithCollectComments(opts.CollectComments), - sqllexer.WithCollectCommands(opts.CollectCommands), - sqllexer.WithCollectTables(opts.TableNames), - sqllexer.WithCollectProcedures(opts.CollectProcedures), - sqllexer.WithKeepSQLAlias(opts.KeepSQLAlias), - sqllexer.WithRemoveSpaceBetweenParentheses(opts.RemoveSpaceBetweenParentheses), - sqllexer.WithKeepTrailingSemicolon(opts.KeepTrailingSemicolon), - sqllexer.WithKeepIdentifierQuotation(opts.KeepIdentifierQuotation), - ) - - var out string - var statementMetadata *sqllexer.StatementMetadata - var err error - - if opts.ObfuscationMode == NormalizeOnly { - // Normalize the query without obfuscating it. - out, statementMetadata, err = normalizer.Normalize(in, sqllexer.WithDBMS(sqllexer.DBMSType(opts.DBMS))) - } else { - out, statementMetadata, err = sqllexer.ObfuscateAndNormalize( - in, - obfuscator, - normalizer, - sqllexer.WithDBMS(sqllexer.DBMSType(opts.DBMS)), - ) - } - if err != nil { - return nil, err - } - oq := &ObfuscatedQuery{ - Query: out, - Metadata: SQLMetadata{ - Size: int64(statementMetadata.Size), - TablesCSV: strings.Join(statementMetadata.Tables, ","), - Commands: statementMetadata.Commands, - Comments: statementMetadata.Comments, - Procedures: statementMetadata.Procedures, - }, - } - - o.queryCache.Set(in, oq, oq.Cost()) - - return oq, nil -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/sql_tokenizer.go b/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/sql_tokenizer.go deleted file mode 100644 index e379d7dd..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/obfuscate/sql_tokenizer.go +++ /dev/null @@ -1,929 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package obfuscate - -import ( - "bytes" - "fmt" - "strings" - "unicode" - "unicode/utf8" -) - -// tokenizer.go implemenents a lexer-like iterator that tokenizes SQL and CQL -// strings, so that an external component can filter or alter each token of the -// string. This implementation can't be used as a real SQL lexer (so a parser -// cannot build the AST) because many rules are ignored to make the tokenizer -// simpler. -// This implementation was inspired by https://github.com/youtube/vitess sql parser -// TODO: add the license to the NOTICE file - -// TokenKind specifies the type of the token being scanned. It may be one of the defined -// constants below or in some cases the actual rune itself. -type TokenKind uint32 - -// EndChar is used to signal that the scanner has finished reading the query. This happens when -// there are no more characters left in the query or when invalid encoding is discovered. EndChar -// is an invalid rune value that can not be found in any valid string. -const EndChar = unicode.MaxRune + 1 - -// list of available tokens; this list has been reduced because we don't -// need a full-fledged tokenizer to implement a Lexer -const ( - LexError = TokenKind(57346) + iota - - ID - Limit - Null - String - DoubleQuotedString - DollarQuotedString // https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-DOLLAR-QUOTING - DollarQuotedFunc // a dollar-quoted string delimited by the tag "$func$"; gets special treatment when feature "dollar_quoted_func" is set - Number - BooleanLiteral - ValueArg - ListArg - Comment - Variable - Savepoint - PreparedStatement - EscapeSequence - NullSafeEqual - LE - GE - NE - Not - As - Alter - Drop - Create - Grant - Revoke - Commit - Begin - Truncate - Select - From - Update - Delete - Insert - Into - Join - TableName - ColonCast - - // PostgreSQL specific JSON operators - JSONSelect // -> - JSONSelectText // ->> - JSONSelectPath // #> - JSONSelectPathText // #>> - JSONContains // @> - JSONContainsLeft // <@ - JSONKeyExists // ? - JSONAnyKeysExist // ?| - JSONAllKeysExist // ?& - JSONDelete // #- - - // FilteredGroupable specifies that the given token has been discarded by one of the - // token filters and that it is groupable together with consecutive FilteredGroupable - // tokens. - FilteredGroupable - - // FilteredGroupableParenthesis is a parenthesis marked as filtered groupable. It is the - // beginning of either a group of values ('(') or a nested query. We track is as - // a special case for when it may start a nested query as opposed to just another - // value group to be obfuscated. - FilteredGroupableParenthesis - - // Filtered specifies that the token is a comma and was discarded by one - // of the filters. - Filtered - - // FilteredBracketedIdentifier specifies that we are currently discarding - // a bracketed identifier (MSSQL). - // See issue https://github.com/DataDog/datadog-trace-agent/issues/475. - FilteredBracketedIdentifier -) - -var tokenKindStrings = map[TokenKind]string{ - LexError: "LexError", - ID: "ID", - Limit: "Limit", - Null: "Null", - String: "String", - DoubleQuotedString: "DoubleQuotedString", - DollarQuotedString: "DollarQuotedString", - DollarQuotedFunc: "DollarQuotedFunc", - Number: "Number", - BooleanLiteral: "BooleanLiteral", - ValueArg: "ValueArg", - ListArg: "ListArg", - Comment: "Comment", - Variable: "Variable", - Savepoint: "Savepoint", - PreparedStatement: "PreparedStatement", - EscapeSequence: "EscapeSequence", - NullSafeEqual: "NullSafeEqual", - LE: "LE", - GE: "GE", - NE: "NE", - Not: "NOT", - As: "As", - Alter: "Alter", - Drop: "Drop", - Create: "Create", - Grant: "Grant", - Revoke: "Revoke", - Commit: "Commit", - Begin: "Begin", - Truncate: "Truncate", - Select: "Select", - From: "From", - Update: "Update", - Delete: "Delete", - Insert: "Insert", - Into: "Into", - Join: "Join", - TableName: "TableName", - ColonCast: "ColonCast", - FilteredGroupable: "FilteredGroupable", - FilteredGroupableParenthesis: "FilteredGroupableParenthesis", - Filtered: "Filtered", - FilteredBracketedIdentifier: "FilteredBracketedIdentifier", - JSONSelect: "JSONSelect", - JSONSelectText: "JSONSelectText", - JSONSelectPath: "JSONSelectPath", - JSONSelectPathText: "JSONSelectPathText", - JSONContains: "JSONContains", - JSONContainsLeft: "JSONContainsLeft", - JSONKeyExists: "JSONKeyExists", - JSONAnyKeysExist: "JSONAnyKeysExist", - JSONAllKeysExist: "JSONAllKeysExist", - JSONDelete: "JSONDelete", -} - -func (k TokenKind) String() string { - str, ok := tokenKindStrings[k] - if !ok { - return "" - } - return str -} - -const ( - // DBMSSQLServer is a MS SQL Server - DBMSSQLServer = "mssql" - // DBMSPostgres is a PostgreSQL Server - DBMSPostgres = "postgresql" - // DBMSMySQL is a MySQL Server - DBMSMySQL = "mysql" - // DBMSOracle is an Oracle Server - DBMSOracle = "oracle" -) - -const escapeCharacter = '\\' - -// SQLTokenizer is the struct used to generate SQL -// tokens for the parser. -type SQLTokenizer struct { - pos int // byte offset of lastChar - lastChar rune // last read rune - buf []byte // buf holds the query that we are parsing - off int // off is the index into buf where the unread portion of the query begins. - err error // any error occurred while reading - - curlys uint32 // number of active open curly braces in top-level SQL escape sequences. - - literalEscapes bool // indicates we should not treat backslashes as escape characters - seenEscape bool // indicates whether this tokenizer has seen an escape character within a string - - cfg *SQLConfig -} - -// NewSQLTokenizer creates a new SQLTokenizer for the given SQL string. The literalEscapes argument specifies -// whether escape characters should be treated literally or as such. -func NewSQLTokenizer(sql string, literalEscapes bool, cfg *SQLConfig) *SQLTokenizer { - if cfg == nil { - cfg = new(SQLConfig) - } - return &SQLTokenizer{ - buf: []byte(sql), - cfg: cfg, - literalEscapes: literalEscapes, - } -} - -// Reset the underlying buffer and positions -func (tkn *SQLTokenizer) Reset(in string) { - tkn.pos = 0 - tkn.lastChar = 0 - tkn.buf = []byte(in) - tkn.off = 0 - tkn.err = nil -} - -// keywords used to recognize string tokens -var keywords = map[string]TokenKind{ - "NULL": Null, - "TRUE": BooleanLiteral, - "FALSE": BooleanLiteral, - "SAVEPOINT": Savepoint, - "LIMIT": Limit, - "AS": As, - "ALTER": Alter, - "CREATE": Create, - "GRANT": Grant, - "REVOKE": Revoke, - "COMMIT": Commit, - "BEGIN": Begin, - "TRUNCATE": Truncate, - "DROP": Drop, - "SELECT": Select, - "FROM": From, - "UPDATE": Update, - "DELETE": Delete, - "INSERT": Insert, - "INTO": Into, - "JOIN": Join, -} - -// Err returns the last error that the tokenizer encountered, or nil. -func (tkn *SQLTokenizer) Err() error { return tkn.err } - -func (tkn *SQLTokenizer) setErr(format string, args ...interface{}) { - if tkn.err != nil { - return - } - tkn.err = fmt.Errorf("at position %d: %v", tkn.pos, fmt.Errorf(format, args...)) -} - -// SeenEscape returns whether or not this tokenizer has seen an escape character within a scanned string -func (tkn *SQLTokenizer) SeenEscape() bool { return tkn.seenEscape } - -// Scan scans the tokenizer for the next token and returns -// the token type and the token buffer. -func (tkn *SQLTokenizer) Scan() (TokenKind, []byte) { - if tkn.lastChar == 0 { - tkn.advance() - } - tkn.SkipBlank() - - switch ch := tkn.lastChar; { - case isLeadingLetter(ch) && - !(tkn.cfg.DBMS == DBMSPostgres && ch == '@'): - // The '@' symbol should not be considered part of an identifier in - // postgres, so we skip this in the case where the DBMS is postgres - // and ch is '@'. - return tkn.scanIdentifier() - case isDigit(ch): - return tkn.scanNumber(false) - default: - tkn.advance() - if tkn.lastChar == EndChar && tkn.err != nil { - // advance discovered an invalid encoding. We should return early. - return LexError, nil - } - switch ch { - case EndChar: - if tkn.err != nil { - return LexError, nil - } - return EndChar, nil - case ':': - if tkn.lastChar == ':' { - tkn.advance() - return ColonCast, []byte("::") - } - if unicode.IsSpace(tkn.lastChar) { - // example scenario: "autovacuum: VACUUM ANALYZE fake.table" - return TokenKind(ch), tkn.bytes() - } - if tkn.lastChar != '=' { - return tkn.scanBindVar() - } - fallthrough - case '~': - switch tkn.lastChar { - case '*': - tkn.advance() - return TokenKind('~'), []byte("~*") - default: - return TokenKind(ch), tkn.bytes() - } - case '?': - if tkn.cfg.DBMS == DBMSPostgres { - switch tkn.lastChar { - case '|': - tkn.advance() - return JSONAnyKeysExist, []byte("?|") - case '&': - tkn.advance() - return JSONAllKeysExist, []byte("?&") - default: - return JSONKeyExists, tkn.bytes() - } - } - fallthrough - case '=', ',', ';', '(', ')', '+', '*', '&', '|', '^', ']': - return TokenKind(ch), tkn.bytes() - case '[': - if tkn.cfg.DBMS == DBMSSQLServer { - return tkn.scanString(']', DoubleQuotedString) - } - return TokenKind(ch), tkn.bytes() - case '.': - if isDigit(tkn.lastChar) { - return tkn.scanNumber(true) - } - return TokenKind(ch), tkn.bytes() - case '/': - switch tkn.lastChar { - case '/': - tkn.advance() - return tkn.scanCommentType1("//") - case '*': - tkn.advance() - return tkn.scanCommentType2() - default: - return TokenKind(ch), tkn.bytes() - } - case '-': - switch { - case tkn.lastChar == '-': - tkn.advance() - return tkn.scanCommentType1("--") - case tkn.lastChar == '>': - if tkn.cfg.DBMS == DBMSPostgres { - tkn.advance() - switch tkn.lastChar { - case '>': - tkn.advance() - return JSONSelectText, []byte("->>") - default: - return JSONSelect, []byte("->") - } - } - fallthrough - case isDigit(tkn.lastChar): - return tkn.scanNumber(false) - case tkn.lastChar == '.': - tkn.advance() - if isDigit(tkn.lastChar) { - return tkn.scanNumber(true) - } - tkn.lastChar = '.' - tkn.pos-- - fallthrough - default: - return TokenKind(ch), tkn.bytes() - } - case '#': - switch tkn.cfg.DBMS { - case DBMSSQLServer: - return tkn.scanIdentifier() - case DBMSPostgres: - switch tkn.lastChar { - case '>': - tkn.advance() - switch tkn.lastChar { - case '>': - tkn.advance() - return JSONSelectPathText, []byte("#>>") - default: - return JSONSelectPath, []byte("#>") - } - case '-': - tkn.advance() - return JSONDelete, []byte("#-") - default: - return TokenKind(ch), tkn.bytes() - } - default: - tkn.advance() - return tkn.scanCommentType1("#") - } - case '<': - switch tkn.lastChar { - case '>': - tkn.advance() - return NE, []byte("<>") - case '=': - tkn.advance() - switch tkn.lastChar { - case '>': - tkn.advance() - return NullSafeEqual, []byte("<=>") - default: - return LE, []byte("<=") - } - case '@': - if tkn.cfg.DBMS == DBMSPostgres { - // check for JSONContainsLeft (<@) - tkn.advance() - return JSONContainsLeft, []byte("<@") - } - fallthrough - default: - return TokenKind(ch), tkn.bytes() - } - case '>': - if tkn.lastChar == '=' { - tkn.advance() - return GE, []byte(">=") - } - return TokenKind(ch), tkn.bytes() - case '!': - switch tkn.lastChar { - case '=': - tkn.advance() - return NE, []byte("!=") - case '~': - tkn.advance() - switch tkn.lastChar { - case '*': - tkn.advance() - return NE, []byte("!~*") - default: - return NE, []byte("!~") - } - default: - if isValidCharAfterOperator(tkn.lastChar) { - return Not, tkn.bytes() - } - tkn.setErr(`unexpected char "%c" (%d) after "!"`, tkn.lastChar, tkn.lastChar) - return LexError, tkn.bytes() - } - case '\'': - return tkn.scanString(ch, String) - case '"': - return tkn.scanString(ch, DoubleQuotedString) - case '`': - return tkn.scanString(ch, ID) - case '%': - if tkn.lastChar == '(' { - return tkn.scanVariableIdentifier('%') - } - if isLetter(tkn.lastChar) { - // format parameter (e.g. '%s') - return tkn.scanFormatParameter('%') - } - // modulo operator (e.g. 'id % 8') - return TokenKind(ch), tkn.bytes() - case '$': - if isDigit(tkn.lastChar) { - // TODO(gbbr): the first digit after $ does not necessarily guarantee - // that this isn't a dollar-quoted string constant. We might eventually - // want to cover for this use-case too (e.g. $1$some text$1$). - return tkn.scanPreparedStatement('$') - } - - // A special case for a string starts with single $ but does not end with $. - // For example in SQLServer, you can have "MG..... OUTPUT $action, inserted.*" - // $action in the OUTPUT clause of a MERGE statement is a special identifier - // that returns one of three values for each row: 'INSERT', 'UPDATE', or 'DELETE'. - // See: https://docs.microsoft.com/en-us/sql/t-sql/statements/merge-transact-sql?view=sql-server-ver15 - if tkn.cfg.DBMS == DBMSSQLServer && isLetter(tkn.lastChar) { - // When the DBMS is SQLServer and the last character is a letter, - // we should scan an identifier instead of a string. - return tkn.scanIdentifier() - } - - kind, tok := tkn.scanDollarQuotedString() - if kind == DollarQuotedFunc { - // this is considered an embedded query, we should try and - // obfuscate it - out, err := attemptObfuscation(NewSQLTokenizer(string(tok), tkn.literalEscapes, tkn.cfg)) - if err != nil { - // if we can't obfuscate it, treat it as a regular string - return DollarQuotedString, tok - } - tok = append(append([]byte("$func$"), []byte(out.Query)...), []byte("$func$")...) - } - return kind, tok - case '@': - if tkn.cfg.DBMS == DBMSPostgres { - // For postgres the @ symbol is reserved as an operator - // https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-OPERATORS - // And is used as a json operator - // https://www.postgresql.org/docs/9.5/functions-json.html - switch tkn.lastChar { - case '>': - tkn.advance() - return JSONContains, []byte("@>") - default: - return TokenKind(ch), tkn.bytes() - } - } - fallthrough - case '{': - if tkn.pos == 1 || tkn.curlys > 0 { - // Do not fully obfuscate top-level SQL escape sequences like {{[?=]call procedure-name[([parameter][,parameter]...)]}. - // We want these to display a bit more context than just a plain '?' - // See: https://docs.oracle.com/cd/E13157_01/wlevs/docs30/jdbc_drivers/sqlescape.html - tkn.curlys++ - return TokenKind(ch), tkn.bytes() - } - return tkn.scanEscapeSequence('{') - case '}': - if tkn.curlys == 0 { - // A closing curly brace has no place outside an in-progress top-level SQL escape sequence - // started by the '{' switch-case. - tkn.setErr(`unexpected byte %d`, ch) - return LexError, tkn.bytes() - } - tkn.curlys-- - return TokenKind(ch), tkn.bytes() - default: - tkn.setErr(`unexpected byte %d`, ch) - return LexError, tkn.bytes() - } - } -} - -// SkipBlank moves the tokenizer forward until hitting a non-whitespace character -// The whitespace definition used here is the same as unicode.IsSpace -func (tkn *SQLTokenizer) SkipBlank() { - for unicode.IsSpace(tkn.lastChar) { - tkn.advance() - } - tkn.bytes() -} - -// toUpper is a modified version of bytes.ToUpper. It returns an upper-cased version of the byte -// slice src with all Unicode letters mapped to their upper case. It is modified to also accept a -// byte slice dst as an argument, the underlying storage of which (up to the capacity of dst) -// will be used as the destination of the upper-case copy of src, if it fits. As a special case, -// toUpper will return src if the byte slice is already upper-case. This function is used rather -// than bytes.ToUpper to improve the memory performance of the obfuscator by saving unnecessary -// allocations happening in bytes.ToUpper -func toUpper(src, dst []byte) []byte { - dst = dst[:0] - isASCII, hasLower := true, false - for i := 0; i < len(src); i++ { - c := src[i] - if c >= utf8.RuneSelf { - isASCII = false - break - } - hasLower = hasLower || ('a' <= c && c <= 'z') - } - if cap(dst) < len(src) { - dst = make([]byte, 0, len(src)) - } - if isASCII { // optimize for ASCII-only byte slices. - if !hasLower { - // Just return src. - return src - } - dst = dst[:len(src)] - for i := 0; i < len(src); i++ { - c := src[i] - if 'a' <= c && c <= 'z' { - c -= 'a' - 'A' - } - dst[i] = c - } - return dst - } - // This *could* be optimized, but it's an uncommon case. - return bytes.Map(unicode.ToUpper, src) -} - -func (tkn *SQLTokenizer) scanIdentifier() (TokenKind, []byte) { - tkn.advance() - for isLetter(tkn.lastChar) || isDigit(tkn.lastChar) || strings.ContainsRune(".*$", tkn.lastChar) { - tkn.advance() - } - - t := tkn.bytes() - // Space allows us to upper-case identifiers 256 bytes long or less without allocating heap - // storage for them, since space is allocated on the stack. A size of 256 bytes was chosen - // based on the allowed length of sql identifiers in various sql implementations. - var space [256]byte - upper := toUpper(t, space[:0]) - if keywordID, found := keywords[string(upper)]; found { - return keywordID, t - } - return ID, t -} - -func (tkn *SQLTokenizer) scanVariableIdentifier(_ rune) (TokenKind, []byte) { - for tkn.advance(); tkn.lastChar != ')' && tkn.lastChar != EndChar; tkn.advance() { - continue - } - tkn.advance() - if !isLetter(tkn.lastChar) { - tkn.setErr(`invalid character after variable identifier: "%c" (%d)`, tkn.lastChar, tkn.lastChar) - return LexError, tkn.bytes() - } - tkn.advance() - return Variable, tkn.bytes() -} - -func (tkn *SQLTokenizer) scanFormatParameter(_ rune) (TokenKind, []byte) { - tkn.advance() - return Variable, tkn.bytes() -} - -// scanDollarQuotedString scans a Postgres dollar-quoted string constant. -// See: https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-DOLLAR-QUOTING -func (tkn *SQLTokenizer) scanDollarQuotedString() (TokenKind, []byte) { - kind, tag := tkn.scanString('$', String) - if kind == LexError { - return kind, tkn.bytes() - } - var ( - got int - buf bytes.Buffer - ) - delim := tag - // on empty strings, tkn.scanString returns the delimiters - if string(delim) != "$$" { - // on non-empty strings, the delimiter is $tag$ - delim = append([]byte{'$'}, delim...) - delim = append(delim, '$') - } - for { - ch := tkn.lastChar - tkn.advance() - if ch == EndChar { - tkn.setErr("unexpected EOF in dollar-quoted string") - return LexError, buf.Bytes() - } - if byte(ch) == delim[got] { - got++ - if got == len(delim) { - break - } - continue - } - if got > 0 { - _, err := buf.Write(delim[:got]) - if err != nil { - tkn.setErr("error reading dollar-quoted string: %v", err) - return LexError, buf.Bytes() - } - got = 0 - } - buf.WriteRune(ch) - } - if tkn.cfg.DollarQuotedFunc && string(delim) == "$func$" { - return DollarQuotedFunc, buf.Bytes() - } - return DollarQuotedString, buf.Bytes() -} - -func (tkn *SQLTokenizer) scanPreparedStatement(_ rune) (TokenKind, []byte) { - // a prepared statement expect a digit identifier like $1 - if !isDigit(tkn.lastChar) { - tkn.setErr(`prepared statements must start with digits, got "%c" (%d)`, tkn.lastChar, tkn.lastChar) - return LexError, tkn.bytes() - } - - // scanNumber keeps the prefix rune intact. - // read numbers and return an error if any - token, buff := tkn.scanNumber(false) - if token == LexError { - tkn.setErr("invalid number") - return LexError, tkn.bytes() - } - return PreparedStatement, buff -} - -func (tkn *SQLTokenizer) scanEscapeSequence(_ rune) (TokenKind, []byte) { - for tkn.lastChar != '}' && tkn.lastChar != EndChar { - tkn.advance() - } - - // we've reached the end of the string without finding - // the closing curly braces - if tkn.lastChar == EndChar { - tkn.setErr("unexpected EOF in escape sequence") - return LexError, tkn.bytes() - } - - tkn.advance() - return EscapeSequence, tkn.bytes() -} - -func (tkn *SQLTokenizer) scanBindVar() (TokenKind, []byte) { - token := ValueArg - if tkn.lastChar == ':' { - token = ListArg - tkn.advance() - } - if !isLetter(tkn.lastChar) && !isDigit(tkn.lastChar) { - tkn.setErr(`bind variables should start with letters or digits, got "%c" (%d)`, tkn.lastChar, tkn.lastChar) - return LexError, tkn.bytes() - } - for isLetter(tkn.lastChar) || isDigit(tkn.lastChar) || tkn.lastChar == '.' { - tkn.advance() - } - return token, tkn.bytes() -} - -func (tkn *SQLTokenizer) scanMantissa(base int) { - for digitVal(tkn.lastChar) < base { - tkn.advance() - } -} - -func (tkn *SQLTokenizer) scanNumber(seenDecimalPoint bool) (TokenKind, []byte) { - if seenDecimalPoint { - tkn.scanMantissa(10) - goto exponent - } - - if tkn.lastChar == '0' { - // int or float - tkn.advance() - if tkn.lastChar == 'x' || tkn.lastChar == 'X' { - // hexadecimal int - tkn.advance() - tkn.scanMantissa(16) - } else { - // octal int or float - tkn.scanMantissa(8) - if tkn.lastChar == '8' || tkn.lastChar == '9' { - tkn.scanMantissa(10) - } - if tkn.lastChar == '.' || tkn.lastChar == 'e' || tkn.lastChar == 'E' { - goto fraction - } - } - goto exit - } - - // decimal int or float - tkn.scanMantissa(10) - -fraction: - if tkn.lastChar == '.' { - tkn.advance() - tkn.scanMantissa(10) - } - -exponent: - if tkn.lastChar == 'e' || tkn.lastChar == 'E' { - tkn.advance() - if tkn.lastChar == '+' || tkn.lastChar == '-' { - tkn.advance() - } - tkn.scanMantissa(10) - } - -exit: - t := tkn.bytes() - if len(t) == 0 { - tkn.setErr("Parse error: ended up with zero-length number.") - return LexError, nil - } - return Number, t -} - -func (tkn *SQLTokenizer) scanString(delim rune, kind TokenKind) (TokenKind, []byte) { - buf := bytes.NewBuffer(tkn.buf[:0]) - for { - ch := tkn.lastChar - tkn.advance() - if ch == delim { - if tkn.lastChar == delim { - // doubling a delimiter is the default way to embed the delimiter within a string - tkn.advance() - } else { - // a single delimiter denotes the end of the string - break - } - } else if ch == escapeCharacter { - tkn.seenEscape = true - - if !tkn.literalEscapes { - // treat as an escape character - ch = tkn.lastChar - tkn.advance() - } - } - if ch == EndChar { - tkn.setErr("unexpected EOF in string") - return LexError, buf.Bytes() - } - buf.WriteRune(ch) - } - if kind == ID && buf.Len() == 0 || bytes.IndexFunc(buf.Bytes(), func(r rune) bool { return !unicode.IsSpace(r) }) == -1 { - // This string is an empty or white-space only identifier. - // We should keep the start and end delimiters in order to - // avoid creating invalid queries. - // See: https://github.com/DataDog/datadog-trace-agent/issues/316 - return kind, append(runeBytes(delim), runeBytes(delim)...) - } - return kind, buf.Bytes() -} - -func (tkn *SQLTokenizer) scanCommentType1(_ string) (TokenKind, []byte) { - for tkn.lastChar != EndChar { - if tkn.lastChar == '\n' { - tkn.advance() - break - } - tkn.advance() - } - return Comment, tkn.bytes() -} - -func (tkn *SQLTokenizer) scanCommentType2() (TokenKind, []byte) { - for { - if tkn.lastChar == '*' { - tkn.advance() - if tkn.lastChar == '/' { - tkn.advance() - break - } - continue - } - if tkn.lastChar == EndChar { - tkn.setErr("unexpected EOF in comment") - return LexError, tkn.bytes() - } - tkn.advance() - } - return Comment, tkn.bytes() -} - -// advance advances the tokenizer to the next rune. If the decoder encounters an error decoding, or -// the end of the buffer is reached, tkn.lastChar will be set to EndChar. In case of a decoding -// error, tkn.err will also be set. -func (tkn *SQLTokenizer) advance() { - ch, n := utf8.DecodeRune(tkn.buf[tkn.off:]) - if ch == utf8.RuneError && n < 2 { - tkn.pos++ - tkn.lastChar = EndChar - if n == 1 { - tkn.setErr("invalid UTF-8 encoding beginning with 0x%x", tkn.buf[tkn.off]) - } - return - } - if tkn.lastChar != 0 || tkn.pos > 0 { - // we are past the first character - tkn.pos += n - } - tkn.off += n - tkn.lastChar = ch -} - -// bytes returns all the bytes that were advanced over since its last call. -// This excludes tkn.lastChar, which will remain in the buffer -func (tkn *SQLTokenizer) bytes() []byte { - if tkn.lastChar == EndChar { - ret := tkn.buf[:tkn.off] - tkn.buf = tkn.buf[tkn.off:] - tkn.off = 0 - return ret - } - lastLen := utf8.RuneLen(tkn.lastChar) - ret := tkn.buf[:tkn.off-lastLen] - tkn.buf = tkn.buf[tkn.off-lastLen:] - tkn.off = lastLen - return ret -} - -// Position exports the tokenizer's current position in the query -func (tkn *SQLTokenizer) Position() int { - return tkn.pos -} - -func isLeadingLetter(ch rune) bool { - return unicode.IsLetter(ch) || ch == '_' || ch == '@' -} - -func isLetter(ch rune) bool { - return isLeadingLetter(ch) || ch == '#' -} - -func digitVal(ch rune) int { - switch { - case '0' <= ch && ch <= '9': - return int(ch) - '0' - case 'a' <= ch && ch <= 'f': - return int(ch) - 'a' + 10 - case 'A' <= ch && ch <= 'F': - return int(ch) - 'A' + 10 - } - return 16 // larger than any legal digit val -} - -func isDigit(ch rune) bool { return '0' <= ch && ch <= '9' } - -// runeBytes converts the given rune to a slice of bytes. -func runeBytes(r rune) []byte { - buf := make([]byte, utf8.UTFMax) - n := utf8.EncodeRune(buf, r) - return buf[:n] -} - -// isValidCharAfterOperator returns true if c is a valid character after an operator -func isValidCharAfterOperator(c rune) bool { - return c == '(' || c == '`' || c == '\'' || c == '"' || c == '+' || c == '-' || unicode.IsSpace(c) || isLetter(c) || isDigit(c) -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/proto/LICENSE b/vendor/github.com/DataDog/datadog-agent/pkg/proto/LICENSE deleted file mode 100644 index b370545b..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/proto/LICENSE +++ /dev/null @@ -1,200 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2016-present Datadog, Inc. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/agent_payload.pb.go b/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/agent_payload.pb.go deleted file mode 100644 index 5d803ea9..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/agent_payload.pb.go +++ /dev/null @@ -1,240 +0,0 @@ -// protoc -I. -I$GOPATH/src --gogofaster_out=. span.proto tracer_payload.proto agent_payload.proto - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.34.0 -// protoc v5.26.1 -// source: datadog/trace/agent_payload.proto - -package trace - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// AgentPayload represents payload the agent sends to the intake. -type AgentPayload struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // hostName specifies hostname of where the agent is running. - HostName string `protobuf:"bytes,1,opt,name=hostName,proto3" json:"hostName,omitempty"` - // env specifies `env` set in agent configuration. - Env string `protobuf:"bytes,2,opt,name=env,proto3" json:"env,omitempty"` - // tracerPayloads specifies list of the payloads received from tracers. - TracerPayloads []*TracerPayload `protobuf:"bytes,5,rep,name=tracerPayloads,proto3" json:"tracerPayloads,omitempty"` - // tags specifies tags common in all `tracerPayloads`. - Tags map[string]string `protobuf:"bytes,6,rep,name=tags,proto3" json:"tags,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - // agentVersion specifies version of the agent. - AgentVersion string `protobuf:"bytes,7,opt,name=agentVersion,proto3" json:"agentVersion,omitempty"` - // targetTPS holds `TargetTPS` value in AgentConfig. - TargetTPS float64 `protobuf:"fixed64,8,opt,name=targetTPS,proto3" json:"targetTPS,omitempty"` - // errorTPS holds `ErrorTPS` value in AgentConfig. - ErrorTPS float64 `protobuf:"fixed64,9,opt,name=errorTPS,proto3" json:"errorTPS,omitempty"` - // rareSamplerEnabled holds `RareSamplerEnabled` value in AgentConfig - RareSamplerEnabled bool `protobuf:"varint,10,opt,name=rareSamplerEnabled,proto3" json:"rareSamplerEnabled,omitempty"` -} - -func (x *AgentPayload) Reset() { - *x = AgentPayload{} - if protoimpl.UnsafeEnabled { - mi := &file_datadog_trace_agent_payload_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *AgentPayload) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AgentPayload) ProtoMessage() {} - -func (x *AgentPayload) ProtoReflect() protoreflect.Message { - mi := &file_datadog_trace_agent_payload_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AgentPayload.ProtoReflect.Descriptor instead. -func (*AgentPayload) Descriptor() ([]byte, []int) { - return file_datadog_trace_agent_payload_proto_rawDescGZIP(), []int{0} -} - -func (x *AgentPayload) GetHostName() string { - if x != nil { - return x.HostName - } - return "" -} - -func (x *AgentPayload) GetEnv() string { - if x != nil { - return x.Env - } - return "" -} - -func (x *AgentPayload) GetTracerPayloads() []*TracerPayload { - if x != nil { - return x.TracerPayloads - } - return nil -} - -func (x *AgentPayload) GetTags() map[string]string { - if x != nil { - return x.Tags - } - return nil -} - -func (x *AgentPayload) GetAgentVersion() string { - if x != nil { - return x.AgentVersion - } - return "" -} - -func (x *AgentPayload) GetTargetTPS() float64 { - if x != nil { - return x.TargetTPS - } - return 0 -} - -func (x *AgentPayload) GetErrorTPS() float64 { - if x != nil { - return x.ErrorTPS - } - return 0 -} - -func (x *AgentPayload) GetRareSamplerEnabled() bool { - if x != nil { - return x.RareSamplerEnabled - } - return false -} - -var File_datadog_trace_agent_payload_proto protoreflect.FileDescriptor - -var file_datadog_trace_agent_payload_proto_rawDesc = []byte{ - 0x0a, 0x21, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2f, - 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x74, 0x72, 0x61, - 0x63, 0x65, 0x1a, 0x22, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2f, 0x74, 0x72, 0x61, 0x63, - 0x65, 0x2f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x84, 0x03, 0x0a, 0x0c, 0x41, 0x67, 0x65, 0x6e, 0x74, - 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x4e, - 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x4e, - 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, 0x76, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x65, 0x6e, 0x76, 0x12, 0x44, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x72, 0x50, - 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, - 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x54, 0x72, - 0x61, 0x63, 0x65, 0x72, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x0e, 0x74, 0x72, 0x61, - 0x63, 0x65, 0x72, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x12, 0x39, 0x0a, 0x04, 0x74, - 0x61, 0x67, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x64, 0x61, 0x74, 0x61, - 0x64, 0x6f, 0x67, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x50, - 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x56, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x61, 0x67, - 0x65, 0x6e, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x61, - 0x72, 0x67, 0x65, 0x74, 0x54, 0x50, 0x53, 0x18, 0x08, 0x20, 0x01, 0x28, 0x01, 0x52, 0x09, 0x74, - 0x61, 0x72, 0x67, 0x65, 0x74, 0x54, 0x50, 0x53, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x54, 0x50, 0x53, 0x18, 0x09, 0x20, 0x01, 0x28, 0x01, 0x52, 0x08, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x54, 0x50, 0x53, 0x12, 0x2e, 0x0a, 0x12, 0x72, 0x61, 0x72, 0x65, 0x53, 0x61, 0x6d, 0x70, - 0x6c, 0x65, 0x72, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x12, 0x72, 0x61, 0x72, 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x45, 0x6e, 0x61, - 0x62, 0x6c, 0x65, 0x64, 0x1a, 0x37, 0x0a, 0x09, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, - 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x16, 0x5a, - 0x14, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x67, 0x6f, 0x2f, - 0x74, 0x72, 0x61, 0x63, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_datadog_trace_agent_payload_proto_rawDescOnce sync.Once - file_datadog_trace_agent_payload_proto_rawDescData = file_datadog_trace_agent_payload_proto_rawDesc -) - -func file_datadog_trace_agent_payload_proto_rawDescGZIP() []byte { - file_datadog_trace_agent_payload_proto_rawDescOnce.Do(func() { - file_datadog_trace_agent_payload_proto_rawDescData = protoimpl.X.CompressGZIP(file_datadog_trace_agent_payload_proto_rawDescData) - }) - return file_datadog_trace_agent_payload_proto_rawDescData -} - -var file_datadog_trace_agent_payload_proto_msgTypes = make([]protoimpl.MessageInfo, 2) -var file_datadog_trace_agent_payload_proto_goTypes = []interface{}{ - (*AgentPayload)(nil), // 0: datadog.trace.AgentPayload - nil, // 1: datadog.trace.AgentPayload.TagsEntry - (*TracerPayload)(nil), // 2: datadog.trace.TracerPayload -} -var file_datadog_trace_agent_payload_proto_depIdxs = []int32{ - 2, // 0: datadog.trace.AgentPayload.tracerPayloads:type_name -> datadog.trace.TracerPayload - 1, // 1: datadog.trace.AgentPayload.tags:type_name -> datadog.trace.AgentPayload.TagsEntry - 2, // [2:2] is the sub-list for method output_type - 2, // [2:2] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name -} - -func init() { file_datadog_trace_agent_payload_proto_init() } -func file_datadog_trace_agent_payload_proto_init() { - if File_datadog_trace_agent_payload_proto != nil { - return - } - file_datadog_trace_tracer_payload_proto_init() - if !protoimpl.UnsafeEnabled { - file_datadog_trace_agent_payload_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AgentPayload); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_datadog_trace_agent_payload_proto_rawDesc, - NumEnums: 0, - NumMessages: 2, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_datadog_trace_agent_payload_proto_goTypes, - DependencyIndexes: file_datadog_trace_agent_payload_proto_depIdxs, - MessageInfos: file_datadog_trace_agent_payload_proto_msgTypes, - }.Build() - File_datadog_trace_agent_payload_proto = out.File - file_datadog_trace_agent_payload_proto_rawDesc = nil - file_datadog_trace_agent_payload_proto_goTypes = nil - file_datadog_trace_agent_payload_proto_depIdxs = nil -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/agent_payload_gen.go b/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/agent_payload_gen.go deleted file mode 100644 index 26cefad5..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/agent_payload_gen.go +++ /dev/null @@ -1,200 +0,0 @@ -package trace - -// Code generated by github.com/tinylib/msgp DO NOT EDIT. - -import ( - "github.com/tinylib/msgp/msgp" -) - -// MarshalMsg implements msgp.Marshaler -func (z *AgentPayload) MarshalMsg(b []byte) (o []byte, err error) { - o = msgp.Require(b, z.Msgsize()) - // map header, size 8 - // string "HostName" - o = append(o, 0x88, 0xa8, 0x48, 0x6f, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65) - o = msgp.AppendString(o, z.HostName) - // string "Env" - o = append(o, 0xa3, 0x45, 0x6e, 0x76) - o = msgp.AppendString(o, z.Env) - // string "TracerPayloads" - o = append(o, 0xae, 0x54, 0x72, 0x61, 0x63, 0x65, 0x72, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x73) - o = msgp.AppendArrayHeader(o, uint32(len(z.TracerPayloads))) - for za0001 := range z.TracerPayloads { - if z.TracerPayloads[za0001] == nil { - o = msgp.AppendNil(o) - } else { - o, err = z.TracerPayloads[za0001].MarshalMsg(o) - if err != nil { - err = msgp.WrapError(err, "TracerPayloads", za0001) - return - } - } - } - // string "Tags" - o = append(o, 0xa4, 0x54, 0x61, 0x67, 0x73) - o = msgp.AppendMapHeader(o, uint32(len(z.Tags))) - for za0002, za0003 := range z.Tags { - o = msgp.AppendString(o, za0002) - o = msgp.AppendString(o, za0003) - } - // string "AgentVersion" - o = append(o, 0xac, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e) - o = msgp.AppendString(o, z.AgentVersion) - // string "TargetTPS" - o = append(o, 0xa9, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x54, 0x50, 0x53) - o = msgp.AppendFloat64(o, z.TargetTPS) - // string "ErrorTPS" - o = append(o, 0xa8, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x54, 0x50, 0x53) - o = msgp.AppendFloat64(o, z.ErrorTPS) - // string "RareSamplerEnabled" - o = append(o, 0xb2, 0x52, 0x61, 0x72, 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64) - o = msgp.AppendBool(o, z.RareSamplerEnabled) - return -} - -// UnmarshalMsg implements msgp.Unmarshaler -func (z *AgentPayload) UnmarshalMsg(bts []byte) (o []byte, err error) { - var field []byte - _ = field - var zb0001 uint32 - zb0001, bts, err = msgp.ReadMapHeaderBytes(bts) - if err != nil { - err = msgp.WrapError(err) - return - } - for zb0001 > 0 { - zb0001-- - field, bts, err = msgp.ReadMapKeyZC(bts) - if err != nil { - err = msgp.WrapError(err) - return - } - switch msgp.UnsafeString(field) { - case "HostName": - z.HostName, bts, err = msgp.ReadStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "HostName") - return - } - case "Env": - z.Env, bts, err = msgp.ReadStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "Env") - return - } - case "TracerPayloads": - var zb0002 uint32 - zb0002, bts, err = msgp.ReadArrayHeaderBytes(bts) - if err != nil { - err = msgp.WrapError(err, "TracerPayloads") - return - } - if cap(z.TracerPayloads) >= int(zb0002) { - z.TracerPayloads = (z.TracerPayloads)[:zb0002] - } else { - z.TracerPayloads = make([]*TracerPayload, zb0002) - } - for za0001 := range z.TracerPayloads { - if msgp.IsNil(bts) { - bts, err = msgp.ReadNilBytes(bts) - if err != nil { - return - } - z.TracerPayloads[za0001] = nil - } else { - if z.TracerPayloads[za0001] == nil { - z.TracerPayloads[za0001] = new(TracerPayload) - } - bts, err = z.TracerPayloads[za0001].UnmarshalMsg(bts) - if err != nil { - err = msgp.WrapError(err, "TracerPayloads", za0001) - return - } - } - } - case "Tags": - var zb0003 uint32 - zb0003, bts, err = msgp.ReadMapHeaderBytes(bts) - if err != nil { - err = msgp.WrapError(err, "Tags") - return - } - if z.Tags == nil { - z.Tags = make(map[string]string, zb0003) - } else if len(z.Tags) > 0 { - for key := range z.Tags { - delete(z.Tags, key) - } - } - for zb0003 > 0 { - var za0002 string - var za0003 string - zb0003-- - za0002, bts, err = msgp.ReadStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "Tags") - return - } - za0003, bts, err = msgp.ReadStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "Tags", za0002) - return - } - z.Tags[za0002] = za0003 - } - case "AgentVersion": - z.AgentVersion, bts, err = msgp.ReadStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "AgentVersion") - return - } - case "TargetTPS": - z.TargetTPS, bts, err = msgp.ReadFloat64Bytes(bts) - if err != nil { - err = msgp.WrapError(err, "TargetTPS") - return - } - case "ErrorTPS": - z.ErrorTPS, bts, err = msgp.ReadFloat64Bytes(bts) - if err != nil { - err = msgp.WrapError(err, "ErrorTPS") - return - } - case "RareSamplerEnabled": - z.RareSamplerEnabled, bts, err = msgp.ReadBoolBytes(bts) - if err != nil { - err = msgp.WrapError(err, "RareSamplerEnabled") - return - } - default: - bts, err = msgp.Skip(bts) - if err != nil { - err = msgp.WrapError(err) - return - } - } - } - o = bts - return -} - -// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message -func (z *AgentPayload) Msgsize() (s int) { - s = 1 + 9 + msgp.StringPrefixSize + len(z.HostName) + 4 + msgp.StringPrefixSize + len(z.Env) + 15 + msgp.ArrayHeaderSize - for za0001 := range z.TracerPayloads { - if z.TracerPayloads[za0001] == nil { - s += msgp.NilSize - } else { - s += z.TracerPayloads[za0001].Msgsize() - } - } - s += 5 + msgp.MapHeaderSize - if z.Tags != nil { - for za0002, za0003 := range z.Tags { - _ = za0003 - s += msgp.StringPrefixSize + len(za0002) + msgp.StringPrefixSize + len(za0003) - } - } - s += 13 + msgp.StringPrefixSize + len(z.AgentVersion) + 10 + msgp.Float64Size + 9 + msgp.Float64Size + 19 + msgp.BoolSize - return -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/agent_payload_vtproto.pb.go b/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/agent_payload_vtproto.pb.go deleted file mode 100644 index e4d4f171..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/agent_payload_vtproto.pb.go +++ /dev/null @@ -1,523 +0,0 @@ -// Code generated by protoc-gen-go-vtproto. DO NOT EDIT. -// protoc-gen-go-vtproto version: v0.4.0 -// source: datadog/trace/agent_payload.proto - -package trace - -import ( - binary "encoding/binary" - fmt "fmt" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - io "io" - math "math" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -func (m *AgentPayload) MarshalVT() (dAtA []byte, err error) { - if m == nil { - return nil, nil - } - size := m.SizeVT() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBufferVT(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *AgentPayload) MarshalToVT(dAtA []byte) (int, error) { - size := m.SizeVT() - return m.MarshalToSizedBufferVT(dAtA[:size]) -} - -func (m *AgentPayload) MarshalToSizedBufferVT(dAtA []byte) (int, error) { - if m == nil { - return 0, nil - } - i := len(dAtA) - _ = i - var l int - _ = l - if m.unknownFields != nil { - i -= len(m.unknownFields) - copy(dAtA[i:], m.unknownFields) - } - if m.RareSamplerEnabled { - i-- - if m.RareSamplerEnabled { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x50 - } - if m.ErrorTPS != 0 { - i -= 8 - binary.LittleEndian.PutUint64(dAtA[i:], uint64(math.Float64bits(float64(m.ErrorTPS)))) - i-- - dAtA[i] = 0x49 - } - if m.TargetTPS != 0 { - i -= 8 - binary.LittleEndian.PutUint64(dAtA[i:], uint64(math.Float64bits(float64(m.TargetTPS)))) - i-- - dAtA[i] = 0x41 - } - if len(m.AgentVersion) > 0 { - i -= len(m.AgentVersion) - copy(dAtA[i:], m.AgentVersion) - i = encodeVarint(dAtA, i, uint64(len(m.AgentVersion))) - i-- - dAtA[i] = 0x3a - } - if len(m.Tags) > 0 { - for k := range m.Tags { - v := m.Tags[k] - baseI := i - i -= len(v) - copy(dAtA[i:], v) - i = encodeVarint(dAtA, i, uint64(len(v))) - i-- - dAtA[i] = 0x12 - i -= len(k) - copy(dAtA[i:], k) - i = encodeVarint(dAtA, i, uint64(len(k))) - i-- - dAtA[i] = 0xa - i = encodeVarint(dAtA, i, uint64(baseI-i)) - i-- - dAtA[i] = 0x32 - } - } - if len(m.TracerPayloads) > 0 { - for iNdEx := len(m.TracerPayloads) - 1; iNdEx >= 0; iNdEx-- { - size, err := m.TracerPayloads[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarint(dAtA, i, uint64(size)) - i-- - dAtA[i] = 0x2a - } - } - if len(m.Env) > 0 { - i -= len(m.Env) - copy(dAtA[i:], m.Env) - i = encodeVarint(dAtA, i, uint64(len(m.Env))) - i-- - dAtA[i] = 0x12 - } - if len(m.HostName) > 0 { - i -= len(m.HostName) - copy(dAtA[i:], m.HostName) - i = encodeVarint(dAtA, i, uint64(len(m.HostName))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *AgentPayload) SizeVT() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.HostName) - if l > 0 { - n += 1 + l + sov(uint64(l)) - } - l = len(m.Env) - if l > 0 { - n += 1 + l + sov(uint64(l)) - } - if len(m.TracerPayloads) > 0 { - for _, e := range m.TracerPayloads { - l = e.SizeVT() - n += 1 + l + sov(uint64(l)) - } - } - if len(m.Tags) > 0 { - for k, v := range m.Tags { - _ = k - _ = v - mapEntrySize := 1 + len(k) + sov(uint64(len(k))) + 1 + len(v) + sov(uint64(len(v))) - n += mapEntrySize + 1 + sov(uint64(mapEntrySize)) - } - } - l = len(m.AgentVersion) - if l > 0 { - n += 1 + l + sov(uint64(l)) - } - if m.TargetTPS != 0 { - n += 9 - } - if m.ErrorTPS != 0 { - n += 9 - } - if m.RareSamplerEnabled { - n += 2 - } - n += len(m.unknownFields) - return n -} - -func (m *AgentPayload) UnmarshalVT(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: AgentPayload: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: AgentPayload: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field HostName", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.HostName = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Env", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Env = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TracerPayloads", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.TracerPayloads = append(m.TracerPayloads, &TracerPayload{}) - if err := m.TracerPayloads[len(m.TracerPayloads)-1].UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Tags", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Tags == nil { - m.Tags = make(map[string]string) - } - var mapkey string - var mapvalue string - for iNdEx < postIndex { - entryPreIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - if fieldNum == 1 { - var stringLenmapkey uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapkey |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapkey := int(stringLenmapkey) - if intStringLenmapkey < 0 { - return ErrInvalidLength - } - postStringIndexmapkey := iNdEx + intStringLenmapkey - if postStringIndexmapkey < 0 { - return ErrInvalidLength - } - if postStringIndexmapkey > l { - return io.ErrUnexpectedEOF - } - mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) - iNdEx = postStringIndexmapkey - } else if fieldNum == 2 { - var stringLenmapvalue uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapvalue |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapvalue := int(stringLenmapvalue) - if intStringLenmapvalue < 0 { - return ErrInvalidLength - } - postStringIndexmapvalue := iNdEx + intStringLenmapvalue - if postStringIndexmapvalue < 0 { - return ErrInvalidLength - } - if postStringIndexmapvalue > l { - return io.ErrUnexpectedEOF - } - mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue]) - iNdEx = postStringIndexmapvalue - } else { - iNdEx = entryPreIndex - skippy, err := skip(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength - } - if (iNdEx + skippy) > postIndex { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - m.Tags[mapkey] = mapvalue - iNdEx = postIndex - case 7: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AgentVersion", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.AgentVersion = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 8: - if wireType != 1 { - return fmt.Errorf("proto: wrong wireType = %d for field TargetTPS", wireType) - } - var v uint64 - if (iNdEx + 8) > l { - return io.ErrUnexpectedEOF - } - v = uint64(binary.LittleEndian.Uint64(dAtA[iNdEx:])) - iNdEx += 8 - m.TargetTPS = float64(math.Float64frombits(v)) - case 9: - if wireType != 1 { - return fmt.Errorf("proto: wrong wireType = %d for field ErrorTPS", wireType) - } - var v uint64 - if (iNdEx + 8) > l { - return io.ErrUnexpectedEOF - } - v = uint64(binary.LittleEndian.Uint64(dAtA[iNdEx:])) - iNdEx += 8 - m.ErrorTPS = float64(math.Float64frombits(v)) - case 10: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field RareSamplerEnabled", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.RareSamplerEnabled = bool(v != 0) - default: - iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/decoder_bytes.go b/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/decoder_bytes.go deleted file mode 100644 index d50cf8d7..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/decoder_bytes.go +++ /dev/null @@ -1,275 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -// Package trace defines the types and functions to encode/decode traces. -package trace - -import ( - "bytes" - "errors" - "math" - "strings" - "unicode/utf8" - - "github.com/tinylib/msgp/msgp" -) - -// repairUTF8 ensures all characters in s are UTF-8 by replacing non-UTF-8 characters -// with the replacement char � -func repairUTF8(s string) string { - in := strings.NewReader(s) - var out bytes.Buffer - out.Grow(len(s)) - - for { - r, _, err := in.ReadRune() - if err != nil { - // note: by contract, if `in` contains non-valid utf-8, no error is returned. Rather the utf-8 replacement - // character is returned. Therefore, the only error should usually be io.EOF indicating end of string. - // If any other error is returned by chance, we quit as well, outputting whatever part of the string we - // had already constructed. - return out.String() - } - out.WriteRune(r) - } -} - -// parseStringBytes reads the next type in the msgpack payload and -// converts the BinType or the StrType in a valid string. -func parseStringBytes(bts []byte) (string, []byte, error) { - if msgp.IsNil(bts) { - bts, err := msgp.ReadNilBytes(bts) - return "", bts, err - } - // read the generic representation type without decoding - t := msgp.NextType(bts) - - var ( - err error - i []byte - ) - switch t { - case msgp.BinType: - i, bts, err = msgp.ReadBytesZC(bts) - case msgp.StrType: - i, bts, err = msgp.ReadStringZC(bts) - default: - return "", bts, msgp.TypeError{Encoded: t, Method: msgp.StrType} - } - if err != nil { - return "", bts, err - } - if utf8.Valid(i) { - return string(i), bts, nil - } - return repairUTF8(msgp.UnsafeString(i)), bts, nil -} - -// parseFloat64Bytes parses a float64 even if the sent value is an int64 or an uint64; -// this is required because the encoding library could remove bytes from the encoded -// payload to reduce the size, if they're not needed. -func parseFloat64Bytes(bts []byte) (float64, []byte, error) { - if msgp.IsNil(bts) { - bts, err := msgp.ReadNilBytes(bts) - return 0, bts, err - } - // read the generic representation type without decoding - t := msgp.NextType(bts) - - var err error - switch t { - case msgp.IntType: - var i int64 - i, bts, err = msgp.ReadInt64Bytes(bts) - if err != nil { - return 0, bts, err - } - - return float64(i), bts, nil - case msgp.UintType: - var i uint64 - i, bts, err = msgp.ReadUint64Bytes(bts) - if err != nil { - return 0, bts, err - } - - return float64(i), bts, nil - case msgp.Float64Type: - var f float64 - f, bts, err = msgp.ReadFloat64Bytes(bts) - if err != nil { - return 0, bts, err - } - - return f, bts, nil - default: - return 0, bts, msgp.TypeError{Encoded: t, Method: msgp.Float64Type} - } -} - -// cast to int64 values that are int64 but that are sent in uint64 -// over the wire. Set to 0 if they overflow the MaxInt64 size. This -// cast should be used ONLY while decoding int64 values that are -// sent as uint64 to reduce the payload size, otherwise the approach -// is not correct in the general sense. -func castInt64(v uint64) (int64, bool) { - if v > math.MaxInt64 { - return 0, false - } - return int64(v), true -} - -// parseInt64Bytes parses an int64 even if the sent value is an uint64; -// this is required because the encoding library could remove bytes from the encoded -// payload to reduce the size, if they're not needed. -func parseInt64Bytes(bts []byte) (int64, []byte, error) { - if msgp.IsNil(bts) { - bts, err := msgp.ReadNilBytes(bts) - return 0, bts, err - } - // read the generic representation type without decoding - t := msgp.NextType(bts) - - var ( - i int64 - u uint64 - err error - ) - switch t { - case msgp.IntType: - i, bts, err = msgp.ReadInt64Bytes(bts) - if err != nil { - return 0, bts, err - } - return i, bts, nil - case msgp.UintType: - u, bts, err = msgp.ReadUint64Bytes(bts) - if err != nil { - return 0, bts, err - } - - // force-cast - i, ok := castInt64(u) - if !ok { - return 0, bts, errors.New("found uint64, overflows int64") - } - return i, bts, nil - default: - return 0, bts, msgp.TypeError{Encoded: t, Method: msgp.IntType} - } -} - -// parseUint64Bytes parses an uint64 even if the sent value is an int64; -// this is required because the language used for the encoding library -// may not have unsigned types. An example is early version of Java -// (and so JRuby interpreter) that encodes uint64 as int64: -// http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html -func parseUint64Bytes(bts []byte) (uint64, []byte, error) { - if msgp.IsNil(bts) { - bts, err := msgp.ReadNilBytes(bts) - return 0, bts, err - } - // read the generic representation type without decoding - t := msgp.NextType(bts) - - var ( - i int64 - u uint64 - err error - ) - switch t { - case msgp.UintType: - u, bts, err = msgp.ReadUint64Bytes(bts) - if err != nil { - return 0, bts, err - } - return u, bts, err - case msgp.IntType: - i, bts, err = msgp.ReadInt64Bytes(bts) - if err != nil { - return 0, bts, err - } - return uint64(i), bts, nil - default: - return 0, bts, msgp.TypeError{Encoded: t, Method: msgp.IntType} - } -} - -// cast to int32 values that are int32 but that are sent in uint32 -// over the wire. Set to 0 if they overflow the MaxInt32 size. This -// cast should be used ONLY while decoding int32 values that are -// sent as uint32 to reduce the payload size, otherwise the approach -// is not correct in the general sense. -func castInt32(v uint32) (int32, bool) { - if v > math.MaxInt32 { - return 0, false - } - return int32(v), true -} - -// parseInt32Bytes parses an int32 even if the sent value is an uint32; -// this is required because the encoding library could remove bytes from the encoded -// payload to reduce the size, if they're not needed. -func parseInt32Bytes(bts []byte) (int32, []byte, error) { - if msgp.IsNil(bts) { - bts, err := msgp.ReadNilBytes(bts) - return 0, bts, err - } - // read the generic representation type without decoding - t := msgp.NextType(bts) - - var ( - i int32 - u uint32 - err error - ) - switch t { - case msgp.IntType: - i, bts, err = msgp.ReadInt32Bytes(bts) - if err != nil { - return 0, bts, err - } - return i, bts, nil - case msgp.UintType: - u, bts, err = msgp.ReadUint32Bytes(bts) - if err != nil { - return 0, bts, err - } - - // force-cast - i, ok := castInt32(u) - if !ok { - return 0, bts, errors.New("found uint32, overflows int32") - } - return i, bts, nil - default: - return 0, bts, msgp.TypeError{Encoded: t, Method: msgp.IntType} - } -} - -// parseBytes reads the next BinType in the msgpack payload. -// -//nolint:unused // potentially useful; was used with prior proto definitions -func parseBytes(bts []byte) ([]byte, []byte, error) { - if msgp.IsNil(bts) { - bts, err := msgp.ReadNilBytes(bts) - return nil, bts, err - } - // read the generic representation type without decoding - t := msgp.NextType(bts) - - switch t { - case msgp.BinType: - unsafeBytes, bts, err := msgp.ReadBytesZC(bts) - if err != nil { - return nil, bts, err - } - safeBytes := make([]byte, len(unsafeBytes)) - copy(safeBytes, unsafeBytes) - return safeBytes, bts, nil - default: - return nil, bts, msgp.TypeError{Encoded: t, Method: msgp.BinType} - } -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/decoder_v05.go b/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/decoder_v05.go deleted file mode 100644 index f88e6cc8..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/decoder_v05.go +++ /dev/null @@ -1,223 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package trace - -import ( - "errors" - "fmt" - - "github.com/tinylib/msgp/msgp" -) - -// dictionaryString reads an int from decoder dc and returns the string -// at that index from dict. -func dictionaryString(bts []byte, dict []string) (string, []byte, error) { - var ( - ui uint32 - err error - ) - ui, bts, err = msgp.ReadUint32Bytes(bts) - if err != nil { - return "", bts, err - } - idx := int(ui) - if idx >= len(dict) { - return "", bts, fmt.Errorf("dictionary index %d out of range", idx) - } - return dict[idx], bts, nil -} - -// UnmarshalMsgDictionary decodes a trace using the specification from the v0.5 endpoint. -// For details, see the documentation for endpoint v0.5 in pkg/trace/api/version.go -func (t *Traces) UnmarshalMsgDictionary(bts []byte) error { - var err error - if _, bts, err = safeReadHeaderBytes(bts, msgp.ReadArrayHeaderBytes); err != nil { - return err - } - // read dictionary - var sz uint32 - if sz, bts, err = safeReadHeaderBytes(bts, msgp.ReadArrayHeaderBytes); err != nil { - return err - } - dict := make([]string, sz) - for i := range dict { - var str string - str, bts, err = parseStringBytes(bts) - if err != nil { - return err - } - dict[i] = str - } - // read traces - sz, bts, err = safeReadHeaderBytes(bts, msgp.ReadArrayHeaderBytes) - if err != nil { - return err - } - if cap(*t) >= int(sz) { - *t = (*t)[:sz] - } else { - *t = make(Traces, sz) - } - for i := range *t { - sz, bts, err = safeReadHeaderBytes(bts, msgp.ReadArrayHeaderBytes) - if err != nil { - return err - } - if cap((*t)[i]) >= int(sz) { - (*t)[i] = (*t)[i][:sz] - } else { - (*t)[i] = make(Trace, sz) - } - for j := range (*t)[i] { - if (*t)[i][j] == nil { - (*t)[i][j] = new(Span) - } - if bts, err = (*t)[i][j].UnmarshalMsgDictionary(bts, dict); err != nil { - return err - } - } - } - return nil -} - -// spanPropertyCount specifies the number of top-level properties that a span -// has. -const spanPropertyCount = 12 - -// UnmarshalMsgDictionary decodes a span from the given decoder dc, looking up strings -// in the given dictionary dict. For details, see the documentation for endpoint v0.5 -// in pkg/trace/api/version.go -func (z *Span) UnmarshalMsgDictionary(bts []byte, dict []string) ([]byte, error) { - var ( - sz uint32 - err error - ) - sz, bts, err = safeReadHeaderBytes(bts, msgp.ReadArrayHeaderBytes) - if err != nil { - return bts, err - } - if sz != spanPropertyCount { - return bts, errors.New("encoded span needs exactly 12 elements in array") - } - // Service (0) - z.Service, bts, err = dictionaryString(bts, dict) - if err != nil { - return bts, err - } - // Name (1) - z.Name, bts, err = dictionaryString(bts, dict) - if err != nil { - return bts, err - } - // Resource (2) - z.Resource, bts, err = dictionaryString(bts, dict) - if err != nil { - return bts, err - } - // TraceID (3) - z.TraceID, bts, err = parseUint64Bytes(bts) - if err != nil { - return bts, err - } - // SpanID (4) - z.SpanID, bts, err = parseUint64Bytes(bts) - if err != nil { - return bts, err - } - // ParentID (5) - z.ParentID, bts, err = parseUint64Bytes(bts) - if err != nil { - return bts, err - } - // Start (6) - z.Start, bts, err = parseInt64Bytes(bts) - if err != nil { - return bts, err - } - // Duration (7) - z.Duration, bts, err = parseInt64Bytes(bts) - if err != nil { - return bts, err - } - // Error (8) - z.Error, bts, err = parseInt32Bytes(bts) - if err != nil { - return bts, err - } - // Meta (9) - sz, bts, err = safeReadHeaderBytes(bts, msgp.ReadMapHeaderBytes) - if err != nil { - return bts, err - } - if z.Meta == nil && sz > 0 { - z.Meta = make(map[string]string, sz) - } else if len(z.Meta) > 0 { - for key := range z.Meta { - delete(z.Meta, key) - } - } - for sz > 0 { - sz-- - var key, val string - key, bts, err = dictionaryString(bts, dict) - if err != nil { - return bts, err - } - val, bts, err = dictionaryString(bts, dict) - if err != nil { - return bts, err - } - z.Meta[key] = val - } - // Metrics (10) - sz, bts, err = safeReadHeaderBytes(bts, msgp.ReadMapHeaderBytes) - if err != nil { - return bts, err - } - if z.Metrics == nil && sz > 0 { - z.Metrics = make(map[string]float64, sz) - } else if len(z.Metrics) > 0 { - for key := range z.Metrics { - delete(z.Metrics, key) - } - } - for sz > 0 { - sz-- - var ( - key string - val float64 - ) - key, bts, err = dictionaryString(bts, dict) - if err != nil { - return bts, err - } - val, bts, err = parseFloat64Bytes(bts) - if err != nil { - return bts, err - } - z.Metrics[key] = val - } - // Type (11) - z.Type, bts, err = dictionaryString(bts, dict) - if err != nil { - return bts, err - } - return bts, nil -} - -// safeReadHeaderBytes wraps msgp header readers (typically ReadArrayHeaderBytes and ReadMapHeaderBytes). -// It enforces the dictionary max size of 25MB and protects the caller from making unbounded allocations through `make(any, sz)`. -func safeReadHeaderBytes(b []byte, read func([]byte) (uint32, []byte, error)) (uint32, []byte, error) { - sz, bts, err := read(b) - if err != nil { - return 0, nil, err - } - if sz > 25*1e6 { - // Dictionary can't be larger than 25 MB - return 0, nil, errors.New("too long payload") - } - return sz, bts, err -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/span.pb.go b/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/span.pb.go deleted file mode 100644 index be7ee2bd..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/span.pb.go +++ /dev/null @@ -1,448 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.34.0 -// protoc v5.26.1 -// source: datadog/trace/span.proto - -package trace - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type SpanLink struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // @gotags: json:"trace_id" msg:"trace_id" - TraceID uint64 `protobuf:"varint,1,opt,name=traceID,proto3" json:"trace_id" msg:"trace_id"` // Required. - // @gotags: json:"trace_id_high" msg:"trace_id_high,omitempty" - TraceIDHigh uint64 `protobuf:"varint,2,opt,name=traceID_high,json=traceIDHigh,proto3" json:"trace_id_high" msg:"trace_id_high,omitempty"` // Optional. The high 64 bits of a referenced trace id. - // @gotags: json:"span_id" msg:"span_id" - SpanID uint64 `protobuf:"varint,3,opt,name=spanID,proto3" json:"span_id" msg:"span_id"` // Required. - // @gotags: msg:"attributes,omitempty" - Attributes map[string]string `protobuf:"bytes,4,rep,name=attributes,proto3" json:"attributes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3" msg:"attributes,omitempty"` // Optional. Simple mapping of keys to string values. - // @gotags: msg:"tracestate,omitempty" - Tracestate string `protobuf:"bytes,5,opt,name=tracestate,proto3" json:"tracestate,omitempty" msg:"tracestate,omitempty"` // Optional. W3C tracestate. - // @gotags: msg:"flags,omitempty" - Flags uint32 `protobuf:"varint,6,opt,name=flags,proto3" json:"flags,omitempty" msg:"flags,omitempty"` // Optional. W3C trace flags. If set, the high bit (bit 31) must be set. -} - -func (x *SpanLink) Reset() { - *x = SpanLink{} - if protoimpl.UnsafeEnabled { - mi := &file_datadog_trace_span_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SpanLink) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SpanLink) ProtoMessage() {} - -func (x *SpanLink) ProtoReflect() protoreflect.Message { - mi := &file_datadog_trace_span_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SpanLink.ProtoReflect.Descriptor instead. -func (*SpanLink) Descriptor() ([]byte, []int) { - return file_datadog_trace_span_proto_rawDescGZIP(), []int{0} -} - -func (x *SpanLink) GetTraceID() uint64 { - if x != nil { - return x.TraceID - } - return 0 -} - -func (x *SpanLink) GetTraceIDHigh() uint64 { - if x != nil { - return x.TraceIDHigh - } - return 0 -} - -func (x *SpanLink) GetSpanID() uint64 { - if x != nil { - return x.SpanID - } - return 0 -} - -func (x *SpanLink) GetAttributes() map[string]string { - if x != nil { - return x.Attributes - } - return nil -} - -func (x *SpanLink) GetTracestate() string { - if x != nil { - return x.Tracestate - } - return "" -} - -func (x *SpanLink) GetFlags() uint32 { - if x != nil { - return x.Flags - } - return 0 -} - -type Span struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // service is the name of the service with which this span is associated. - // @gotags: json:"service" msg:"service" - Service string `protobuf:"bytes,1,opt,name=service,proto3" json:"service" msg:"service"` - // name is the operation name of this span. - // @gotags: json:"name" msg:"name" - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name" msg:"name"` - // resource is the resource name of this span, also sometimes called the endpoint (for web spans). - // @gotags: json:"resource" msg:"resource" - Resource string `protobuf:"bytes,3,opt,name=resource,proto3" json:"resource" msg:"resource"` - // traceID is the ID of the trace to which this span belongs. - // @gotags: json:"trace_id" msg:"trace_id" - TraceID uint64 `protobuf:"varint,4,opt,name=traceID,proto3" json:"trace_id" msg:"trace_id"` - // spanID is the ID of this span. - // @gotags: json:"span_id" msg:"span_id" - SpanID uint64 `protobuf:"varint,5,opt,name=spanID,proto3" json:"span_id" msg:"span_id"` - // parentID is the ID of this span's parent, or zero if this span has no parent. - // @gotags: json:"parent_id" msg:"parent_id" - ParentID uint64 `protobuf:"varint,6,opt,name=parentID,proto3" json:"parent_id" msg:"parent_id"` - // start is the number of nanoseconds between the Unix epoch and the beginning of this span. - // @gotags: json:"start" msg:"start" - Start int64 `protobuf:"varint,7,opt,name=start,proto3" json:"start" msg:"start"` - // duration is the time length of this span in nanoseconds. - // @gotags: json:"duration" msg:"duration" - Duration int64 `protobuf:"varint,8,opt,name=duration,proto3" json:"duration" msg:"duration"` - // error is 1 if there is an error associated with this span, or 0 if there is not. - // @gotags: json:"error" msg:"error" - Error int32 `protobuf:"varint,9,opt,name=error,proto3" json:"error" msg:"error"` - // meta is a mapping from tag name to tag value for string-valued tags. - // @gotags: json:"meta,omitempty" msg:"meta,omitempty" - Meta map[string]string `protobuf:"bytes,10,rep,name=meta,proto3" json:"meta,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3" msg:"meta,omitempty"` - // metrics is a mapping from tag name to tag value for numeric-valued tags. - // @gotags: json:"metrics,omitempty" msg:"metrics,omitempty" - Metrics map[string]float64 `protobuf:"bytes,11,rep,name=metrics,proto3" json:"metrics,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"fixed64,2,opt,name=value,proto3" msg:"metrics,omitempty"` - // type is the type of the service with which this span is associated. Example values: web, db, lambda. - // @gotags: json:"type" msg:"type" - Type string `protobuf:"bytes,12,opt,name=type,proto3" json:"type" msg:"type"` - // meta_struct is a registry of structured "other" data used by, e.g., AppSec. - // @gotags: json:"meta_struct,omitempty" msg:"meta_struct,omitempty" - MetaStruct map[string][]byte `protobuf:"bytes,13,rep,name=meta_struct,json=metaStruct,proto3" json:"meta_struct,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3" msg:"meta_struct,omitempty"` - // span_links represents a collection of links, where each link defines a causal relationship between two spans. - // @gotags: json:"span_links,omitempty" msg:"span_links,omitempty" - SpanLinks []*SpanLink `protobuf:"bytes,14,rep,name=spanLinks,proto3" json:"span_links,omitempty" msg:"span_links,omitempty"` -} - -func (x *Span) Reset() { - *x = Span{} - if protoimpl.UnsafeEnabled { - mi := &file_datadog_trace_span_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Span) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Span) ProtoMessage() {} - -func (x *Span) ProtoReflect() protoreflect.Message { - mi := &file_datadog_trace_span_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Span.ProtoReflect.Descriptor instead. -func (*Span) Descriptor() ([]byte, []int) { - return file_datadog_trace_span_proto_rawDescGZIP(), []int{1} -} - -func (x *Span) GetService() string { - if x != nil { - return x.Service - } - return "" -} - -func (x *Span) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *Span) GetResource() string { - if x != nil { - return x.Resource - } - return "" -} - -func (x *Span) GetTraceID() uint64 { - if x != nil { - return x.TraceID - } - return 0 -} - -func (x *Span) GetSpanID() uint64 { - if x != nil { - return x.SpanID - } - return 0 -} - -func (x *Span) GetParentID() uint64 { - if x != nil { - return x.ParentID - } - return 0 -} - -func (x *Span) GetStart() int64 { - if x != nil { - return x.Start - } - return 0 -} - -func (x *Span) GetDuration() int64 { - if x != nil { - return x.Duration - } - return 0 -} - -func (x *Span) GetError() int32 { - if x != nil { - return x.Error - } - return 0 -} - -func (x *Span) GetMeta() map[string]string { - if x != nil { - return x.Meta - } - return nil -} - -func (x *Span) GetMetrics() map[string]float64 { - if x != nil { - return x.Metrics - } - return nil -} - -func (x *Span) GetType() string { - if x != nil { - return x.Type - } - return "" -} - -func (x *Span) GetMetaStruct() map[string][]byte { - if x != nil { - return x.MetaStruct - } - return nil -} - -func (x *Span) GetSpanLinks() []*SpanLink { - if x != nil { - return x.SpanLinks - } - return nil -} - -var File_datadog_trace_span_proto protoreflect.FileDescriptor - -var file_datadog_trace_span_proto_rawDesc = []byte{ - 0x0a, 0x18, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2f, - 0x73, 0x70, 0x61, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x64, 0x61, 0x74, 0x61, - 0x64, 0x6f, 0x67, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x22, 0x9d, 0x02, 0x0a, 0x08, 0x53, 0x70, - 0x61, 0x6e, 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x72, 0x61, 0x63, 0x65, 0x49, - 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x74, 0x72, 0x61, 0x63, 0x65, 0x49, 0x44, - 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x72, 0x61, 0x63, 0x65, 0x49, 0x44, 0x5f, 0x68, 0x69, 0x67, 0x68, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x74, 0x72, 0x61, 0x63, 0x65, 0x49, 0x44, 0x48, - 0x69, 0x67, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x70, 0x61, 0x6e, 0x49, 0x44, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x06, 0x73, 0x70, 0x61, 0x6e, 0x49, 0x44, 0x12, 0x47, 0x0a, 0x0a, 0x61, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x27, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, - 0x53, 0x70, 0x61, 0x6e, 0x4c, 0x69, 0x6e, 0x6b, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, - 0x74, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x74, 0x72, 0x61, 0x63, 0x65, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x72, 0x61, 0x63, 0x65, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x1a, 0x3d, 0x0a, 0x0f, 0x41, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, - 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, - 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x9a, 0x05, 0x0a, 0x04, 0x53, 0x70, - 0x61, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x18, 0x0a, 0x07, - 0x74, 0x72, 0x61, 0x63, 0x65, 0x49, 0x44, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x74, - 0x72, 0x61, 0x63, 0x65, 0x49, 0x44, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x70, 0x61, 0x6e, 0x49, 0x44, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x73, 0x70, 0x61, 0x6e, 0x49, 0x44, 0x12, 0x1a, - 0x0a, 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x44, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x44, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, - 0x61, 0x72, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, - 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, - 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x12, 0x31, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x1d, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, - 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, - 0x04, 0x6d, 0x65, 0x74, 0x61, 0x12, 0x3a, 0x0a, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, - 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, - 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x72, - 0x69, 0x63, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, - 0x73, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x44, 0x0a, 0x0b, 0x6d, 0x65, 0x74, 0x61, 0x5f, 0x73, 0x74, - 0x72, 0x75, 0x63, 0x74, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x64, 0x61, 0x74, - 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x53, 0x70, 0x61, 0x6e, 0x2e, - 0x4d, 0x65, 0x74, 0x61, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, - 0x0a, 0x6d, 0x65, 0x74, 0x61, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x12, 0x35, 0x0a, 0x09, 0x73, - 0x70, 0x61, 0x6e, 0x4c, 0x69, 0x6e, 0x6b, 0x73, 0x18, 0x0e, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, - 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x53, - 0x70, 0x61, 0x6e, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x09, 0x73, 0x70, 0x61, 0x6e, 0x4c, 0x69, 0x6e, - 0x6b, 0x73, 0x1a, 0x37, 0x0a, 0x09, 0x4d, 0x65, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, - 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, - 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x3a, 0x0a, 0x0c, 0x4d, - 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, - 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x3d, 0x0a, 0x0f, 0x4d, 0x65, 0x74, 0x61, 0x53, - 0x74, 0x72, 0x75, 0x63, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x16, 0x5a, 0x14, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x67, 0x6f, 0x2f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_datadog_trace_span_proto_rawDescOnce sync.Once - file_datadog_trace_span_proto_rawDescData = file_datadog_trace_span_proto_rawDesc -) - -func file_datadog_trace_span_proto_rawDescGZIP() []byte { - file_datadog_trace_span_proto_rawDescOnce.Do(func() { - file_datadog_trace_span_proto_rawDescData = protoimpl.X.CompressGZIP(file_datadog_trace_span_proto_rawDescData) - }) - return file_datadog_trace_span_proto_rawDescData -} - -var file_datadog_trace_span_proto_msgTypes = make([]protoimpl.MessageInfo, 6) -var file_datadog_trace_span_proto_goTypes = []interface{}{ - (*SpanLink)(nil), // 0: datadog.trace.SpanLink - (*Span)(nil), // 1: datadog.trace.Span - nil, // 2: datadog.trace.SpanLink.AttributesEntry - nil, // 3: datadog.trace.Span.MetaEntry - nil, // 4: datadog.trace.Span.MetricsEntry - nil, // 5: datadog.trace.Span.MetaStructEntry -} -var file_datadog_trace_span_proto_depIdxs = []int32{ - 2, // 0: datadog.trace.SpanLink.attributes:type_name -> datadog.trace.SpanLink.AttributesEntry - 3, // 1: datadog.trace.Span.meta:type_name -> datadog.trace.Span.MetaEntry - 4, // 2: datadog.trace.Span.metrics:type_name -> datadog.trace.Span.MetricsEntry - 5, // 3: datadog.trace.Span.meta_struct:type_name -> datadog.trace.Span.MetaStructEntry - 0, // 4: datadog.trace.Span.spanLinks:type_name -> datadog.trace.SpanLink - 5, // [5:5] is the sub-list for method output_type - 5, // [5:5] is the sub-list for method input_type - 5, // [5:5] is the sub-list for extension type_name - 5, // [5:5] is the sub-list for extension extendee - 0, // [0:5] is the sub-list for field type_name -} - -func init() { file_datadog_trace_span_proto_init() } -func file_datadog_trace_span_proto_init() { - if File_datadog_trace_span_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_datadog_trace_span_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SpanLink); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_datadog_trace_span_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Span); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_datadog_trace_span_proto_rawDesc, - NumEnums: 0, - NumMessages: 6, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_datadog_trace_span_proto_goTypes, - DependencyIndexes: file_datadog_trace_span_proto_depIdxs, - MessageInfos: file_datadog_trace_span_proto_msgTypes, - }.Build() - File_datadog_trace_span_proto = out.File - file_datadog_trace_span_proto_rawDesc = nil - file_datadog_trace_span_proto_goTypes = nil - file_datadog_trace_span_proto_depIdxs = nil -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/span_gen.go b/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/span_gen.go deleted file mode 100644 index c1b14871..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/span_gen.go +++ /dev/null @@ -1,577 +0,0 @@ -package trace - -// Code generated by github.com/tinylib/msgp DO NOT EDIT. - -import ( - "github.com/tinylib/msgp/msgp" -) - -// MarshalMsg implements msgp.Marshaler -func (z *Span) MarshalMsg(b []byte) (o []byte, err error) { - o = msgp.Require(b, z.Msgsize()) - // omitempty: check for empty values - zb0001Len := uint32(14) - var zb0001Mask uint16 /* 14 bits */ - if z.Meta == nil { - zb0001Len-- - zb0001Mask |= 0x200 - } - if z.Metrics == nil { - zb0001Len-- - zb0001Mask |= 0x400 - } - if z.MetaStruct == nil { - zb0001Len-- - zb0001Mask |= 0x1000 - } - if z.SpanLinks == nil { - zb0001Len-- - zb0001Mask |= 0x2000 - } - // variable map header, size zb0001Len - o = append(o, 0x80|uint8(zb0001Len)) - if zb0001Len == 0 { - return - } - // string "service" - o = append(o, 0xa7, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65) - o = msgp.AppendString(o, z.Service) - // string "name" - o = append(o, 0xa4, 0x6e, 0x61, 0x6d, 0x65) - o = msgp.AppendString(o, z.Name) - // string "resource" - o = append(o, 0xa8, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65) - o = msgp.AppendString(o, z.Resource) - // string "trace_id" - o = append(o, 0xa8, 0x74, 0x72, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64) - o = msgp.AppendUint64(o, z.TraceID) - // string "span_id" - o = append(o, 0xa7, 0x73, 0x70, 0x61, 0x6e, 0x5f, 0x69, 0x64) - o = msgp.AppendUint64(o, z.SpanID) - // string "parent_id" - o = append(o, 0xa9, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64) - o = msgp.AppendUint64(o, z.ParentID) - // string "start" - o = append(o, 0xa5, 0x73, 0x74, 0x61, 0x72, 0x74) - o = msgp.AppendInt64(o, z.Start) - // string "duration" - o = append(o, 0xa8, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e) - o = msgp.AppendInt64(o, z.Duration) - // string "error" - o = append(o, 0xa5, 0x65, 0x72, 0x72, 0x6f, 0x72) - o = msgp.AppendInt32(o, z.Error) - if (zb0001Mask & 0x200) == 0 { // if not empty - // string "meta" - o = append(o, 0xa4, 0x6d, 0x65, 0x74, 0x61) - o = msgp.AppendMapHeader(o, uint32(len(z.Meta))) - for za0001, za0002 := range z.Meta { - o = msgp.AppendString(o, za0001) - o = msgp.AppendString(o, za0002) - } - } - if (zb0001Mask & 0x400) == 0 { // if not empty - // string "metrics" - o = append(o, 0xa7, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73) - o = msgp.AppendMapHeader(o, uint32(len(z.Metrics))) - for za0003, za0004 := range z.Metrics { - o = msgp.AppendString(o, za0003) - o = msgp.AppendFloat64(o, za0004) - } - } - // string "type" - o = append(o, 0xa4, 0x74, 0x79, 0x70, 0x65) - o = msgp.AppendString(o, z.Type) - if (zb0001Mask & 0x1000) == 0 { // if not empty - // string "meta_struct" - o = append(o, 0xab, 0x6d, 0x65, 0x74, 0x61, 0x5f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74) - o = msgp.AppendMapHeader(o, uint32(len(z.MetaStruct))) - for za0005, za0006 := range z.MetaStruct { - o = msgp.AppendString(o, za0005) - o = msgp.AppendBytes(o, za0006) - } - } - if (zb0001Mask & 0x2000) == 0 { // if not empty - // string "span_links" - o = append(o, 0xaa, 0x73, 0x70, 0x61, 0x6e, 0x5f, 0x6c, 0x69, 0x6e, 0x6b, 0x73) - o = msgp.AppendArrayHeader(o, uint32(len(z.SpanLinks))) - for za0007 := range z.SpanLinks { - if z.SpanLinks[za0007] == nil { - o = msgp.AppendNil(o) - } else { - o, err = z.SpanLinks[za0007].MarshalMsg(o) - if err != nil { - err = msgp.WrapError(err, "SpanLinks", za0007) - return - } - } - } - } - return -} - -// UnmarshalMsg implements msgp.Unmarshaler -func (z *Span) UnmarshalMsg(bts []byte) (o []byte, err error) { - var field []byte - _ = field - var zb0001 uint32 - zb0001, bts, err = msgp.ReadMapHeaderBytes(bts) - if err != nil { - err = msgp.WrapError(err) - return - } - for zb0001 > 0 { - zb0001-- - field, bts, err = msgp.ReadMapKeyZC(bts) - if err != nil { - err = msgp.WrapError(err) - return - } - switch msgp.UnsafeString(field) { - case "service": - if msgp.IsNil(bts) { - bts, err = msgp.ReadNilBytes(bts) - z.Service = "" - break - } - z.Service, bts, err = parseStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "Service") - return - } - case "name": - if msgp.IsNil(bts) { - bts, err = msgp.ReadNilBytes(bts) - z.Name = "" - break - } - z.Name, bts, err = parseStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "Service") - return - } - case "resource": - if msgp.IsNil(bts) { - bts, err = msgp.ReadNilBytes(bts) - z.Resource = "" - break - } - z.Resource, bts, err = parseStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "Service") - return - } - case "trace_id": - if msgp.IsNil(bts) { - bts, err = msgp.ReadNilBytes(bts) - z.TraceID = 0 - break - } - z.TraceID, bts, err = parseUint64Bytes(bts) - if err != nil { - err = msgp.WrapError(err, "TraceID") - return - } - case "span_id": - if msgp.IsNil(bts) { - bts, err = msgp.ReadNilBytes(bts) - z.SpanID = 0 - break - } - z.SpanID, bts, err = parseUint64Bytes(bts) - if err != nil { - err = msgp.WrapError(err, "SpanID") - return - } - case "parent_id": - if msgp.IsNil(bts) { - bts, err = msgp.ReadNilBytes(bts) - z.ParentID = 0 - break - } - z.ParentID, bts, err = parseUint64Bytes(bts) - if err != nil { - err = msgp.WrapError(err, "ParentID") - return - } - case "start": - if msgp.IsNil(bts) { - bts, err = msgp.ReadNilBytes(bts) - z.Start = 0 - break - } - z.Start, bts, err = parseInt64Bytes(bts) - if err != nil { - err = msgp.WrapError(err, "Start") - return - } - case "duration": - if msgp.IsNil(bts) { - bts, err = msgp.ReadNilBytes(bts) - z.Duration = 0 - break - } - z.Duration, bts, err = parseInt64Bytes(bts) - if err != nil { - err = msgp.WrapError(err, "Duration") - return - } - case "error": - if msgp.IsNil(bts) { - bts, err = msgp.ReadNilBytes(bts) - z.Error = 0 - break - } - z.Error, bts, err = parseInt32Bytes(bts) - if err != nil { - err = msgp.WrapError(err, "Error") - return - } - case "meta": - if msgp.IsNil(bts) { - bts, err = msgp.ReadNilBytes(bts) - z.Meta = nil - break - } - var zb0002 uint32 - zb0002, bts, err = msgp.ReadMapHeaderBytes(bts) - if err != nil { - err = msgp.WrapError(err, "Meta") - return - } - if z.Meta == nil && zb0002 > 0 { - z.Meta = make(map[string]string, zb0002) - } else if len(z.Meta) > 0 { - for key := range z.Meta { - delete(z.Meta, key) - } - } - for zb0002 > 0 { - var za0001 string - var za0002 string - zb0002-- - za0001, bts, err = parseStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "Meta") - return - } - za0002, bts, err = parseStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "Meta", za0001) - return - } - z.Meta[za0001] = za0002 - } - case "metrics": - if msgp.IsNil(bts) { - bts, err = msgp.ReadNilBytes(bts) - z.Metrics = nil - break - } - var zb0003 uint32 - zb0003, bts, err = msgp.ReadMapHeaderBytes(bts) - if err != nil { - err = msgp.WrapError(err, "Metrics") - return - } - if z.Metrics == nil && zb0003 > 0 { - z.Metrics = make(map[string]float64, zb0003) - } else if len(z.Metrics) > 0 { - for key := range z.Metrics { - delete(z.Metrics, key) - } - } - for zb0003 > 0 { - var za0003 string - var za0004 float64 - zb0003-- - za0003, bts, err = parseStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "Metrics") - return - } - za0004, bts, err = parseFloat64Bytes(bts) - if err != nil { - err = msgp.WrapError(err, "Metrics", za0003) - return - } - z.Metrics[za0003] = za0004 - } - case "type": - if msgp.IsNil(bts) { - bts, err = msgp.ReadNilBytes(bts) - z.Type = "" - break - } - z.Type, bts, err = parseStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "Type") - return - } - case "meta_struct": - var zb0004 uint32 - zb0004, bts, err = msgp.ReadMapHeaderBytes(bts) - if err != nil { - err = msgp.WrapError(err, "MetaStruct") - return - } - if z.MetaStruct == nil { - z.MetaStruct = make(map[string][]byte, zb0004) - } else if len(z.MetaStruct) > 0 { - for key := range z.MetaStruct { - delete(z.MetaStruct, key) - } - } - for zb0004 > 0 { - var za0005 string - var za0006 []byte - zb0004-- - za0005, bts, err = msgp.ReadStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "MetaStruct") - return - } - za0006, bts, err = msgp.ReadBytesBytes(bts, za0006) - if err != nil { - err = msgp.WrapError(err, "MetaStruct", za0005) - return - } - z.MetaStruct[za0005] = za0006 - } - case "span_links": - var zb0005 uint32 - zb0005, bts, err = msgp.ReadArrayHeaderBytes(bts) - if err != nil { - err = msgp.WrapError(err, "SpanLinks") - return - } - if cap(z.SpanLinks) >= int(zb0005) { - z.SpanLinks = (z.SpanLinks)[:zb0005] - } else { - z.SpanLinks = make([]*SpanLink, zb0005) - } - for za0007 := range z.SpanLinks { - if msgp.IsNil(bts) { - bts, err = msgp.ReadNilBytes(bts) - if err != nil { - return - } - z.SpanLinks[za0007] = nil - } else { - if z.SpanLinks[za0007] == nil { - z.SpanLinks[za0007] = new(SpanLink) - } - bts, err = z.SpanLinks[za0007].UnmarshalMsg(bts) - if err != nil { - err = msgp.WrapError(err, "SpanLinks", za0007) - return - } - } - } - default: - bts, err = msgp.Skip(bts) - if err != nil { - err = msgp.WrapError(err) - return - } - } - } - o = bts - return -} - -// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message -func (z *Span) Msgsize() (s int) { - s = 1 + 8 + msgp.StringPrefixSize + len(z.Service) + 5 + msgp.StringPrefixSize + len(z.Name) + 9 + msgp.StringPrefixSize + len(z.Resource) + 9 + msgp.Uint64Size + 8 + msgp.Uint64Size + 10 + msgp.Uint64Size + 6 + msgp.Int64Size + 9 + msgp.Int64Size + 6 + msgp.Int32Size + 5 + msgp.MapHeaderSize - if z.Meta != nil { - for za0001, za0002 := range z.Meta { - _ = za0002 - s += msgp.StringPrefixSize + len(za0001) + msgp.StringPrefixSize + len(za0002) - } - } - s += 8 + msgp.MapHeaderSize - if z.Metrics != nil { - for za0003, za0004 := range z.Metrics { - _ = za0004 - s += msgp.StringPrefixSize + len(za0003) + msgp.Float64Size - } - } - s += 5 + msgp.StringPrefixSize + len(z.Type) + 12 + msgp.MapHeaderSize - if z.MetaStruct != nil { - for za0005, za0006 := range z.MetaStruct { - _ = za0006 - s += msgp.StringPrefixSize + len(za0005) + msgp.BytesPrefixSize + len(za0006) - } - } - s += 11 + msgp.ArrayHeaderSize - for za0007 := range z.SpanLinks { - if z.SpanLinks[za0007] == nil { - s += msgp.NilSize - } else { - s += z.SpanLinks[za0007].Msgsize() - } - } - return -} - -// MarshalMsg implements msgp.Marshaler -func (z *SpanLink) MarshalMsg(b []byte) (o []byte, err error) { - o = msgp.Require(b, z.Msgsize()) - // omitempty: check for empty values - zb0001Len := uint32(6) - var zb0001Mask uint8 /* 6 bits */ - if z.TraceIDHigh == 0 { - zb0001Len-- - zb0001Mask |= 0x2 - } - if z.Attributes == nil { - zb0001Len-- - zb0001Mask |= 0x8 - } - if z.Tracestate == "" { - zb0001Len-- - zb0001Mask |= 0x10 - } - if z.Flags == 0 { - zb0001Len-- - zb0001Mask |= 0x20 - } - // variable map header, size zb0001Len - o = append(o, 0x80|uint8(zb0001Len)) - if zb0001Len == 0 { - return - } - // string "trace_id" - o = append(o, 0xa8, 0x74, 0x72, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64) - o = msgp.AppendUint64(o, z.TraceID) - if (zb0001Mask & 0x2) == 0 { // if not empty - // string "trace_id_high" - o = append(o, 0xad, 0x74, 0x72, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x5f, 0x68, 0x69, 0x67, 0x68) - o = msgp.AppendUint64(o, z.TraceIDHigh) - } - // string "span_id" - o = append(o, 0xa7, 0x73, 0x70, 0x61, 0x6e, 0x5f, 0x69, 0x64) - o = msgp.AppendUint64(o, z.SpanID) - if (zb0001Mask & 0x8) == 0 { // if not empty - // string "attributes" - o = append(o, 0xaa, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73) - o = msgp.AppendMapHeader(o, uint32(len(z.Attributes))) - for za0001, za0002 := range z.Attributes { - o = msgp.AppendString(o, za0001) - o = msgp.AppendString(o, za0002) - } - } - if (zb0001Mask & 0x10) == 0 { // if not empty - // string "tracestate" - o = append(o, 0xaa, 0x74, 0x72, 0x61, 0x63, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65) - o = msgp.AppendString(o, z.Tracestate) - } - if (zb0001Mask & 0x20) == 0 { // if not empty - // string "flags" - o = append(o, 0xa5, 0x66, 0x6c, 0x61, 0x67, 0x73) - o = msgp.AppendUint32(o, z.Flags) - } - return -} - -// UnmarshalMsg implements msgp.Unmarshaler -func (z *SpanLink) UnmarshalMsg(bts []byte) (o []byte, err error) { - var field []byte - _ = field - var zb0001 uint32 - zb0001, bts, err = msgp.ReadMapHeaderBytes(bts) - if err != nil { - err = msgp.WrapError(err) - return - } - for zb0001 > 0 { - zb0001-- - field, bts, err = msgp.ReadMapKeyZC(bts) - if err != nil { - err = msgp.WrapError(err) - return - } - switch msgp.UnsafeString(field) { - case "trace_id": - z.TraceID, bts, err = msgp.ReadUint64Bytes(bts) - if err != nil { - err = msgp.WrapError(err, "TraceID") - return - } - case "trace_id_high": - z.TraceIDHigh, bts, err = msgp.ReadUint64Bytes(bts) - if err != nil { - err = msgp.WrapError(err, "TraceIDHigh") - return - } - case "span_id": - z.SpanID, bts, err = msgp.ReadUint64Bytes(bts) - if err != nil { - err = msgp.WrapError(err, "SpanID") - return - } - case "attributes": - var zb0002 uint32 - zb0002, bts, err = msgp.ReadMapHeaderBytes(bts) - if err != nil { - err = msgp.WrapError(err, "Attributes") - return - } - if z.Attributes == nil { - z.Attributes = make(map[string]string, zb0002) - } else if len(z.Attributes) > 0 { - for key := range z.Attributes { - delete(z.Attributes, key) - } - } - for zb0002 > 0 { - var za0001 string - var za0002 string - zb0002-- - za0001, bts, err = msgp.ReadStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "Attributes") - return - } - za0002, bts, err = msgp.ReadStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "Attributes", za0001) - return - } - z.Attributes[za0001] = za0002 - } - case "tracestate": - z.Tracestate, bts, err = msgp.ReadStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "Tracestate") - return - } - case "flags": - z.Flags, bts, err = msgp.ReadUint32Bytes(bts) - if err != nil { - err = msgp.WrapError(err, "Flags") - return - } - default: - bts, err = msgp.Skip(bts) - if err != nil { - err = msgp.WrapError(err) - return - } - } - } - o = bts - return -} - -// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message -func (z *SpanLink) Msgsize() (s int) { - s = 1 + 9 + msgp.Uint64Size + 14 + msgp.Uint64Size + 8 + msgp.Uint64Size + 11 + msgp.MapHeaderSize - if z.Attributes != nil { - for za0001, za0002 := range z.Attributes { - _ = za0002 - s += msgp.StringPrefixSize + len(za0001) + msgp.StringPrefixSize + len(za0002) - } - } - s += 11 + msgp.StringPrefixSize + len(z.Tracestate) + 6 + msgp.Uint32Size - return -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/span_utils.go b/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/span_utils.go deleted file mode 100644 index 7c4919a2..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/span_utils.go +++ /dev/null @@ -1,53 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package trace - -// spanCopiedFields records the fields that are copied in ShallowCopy. -// This should match exactly the fields set in (*Span).ShallowCopy. -// This is used by tests to enforce the correctness of ShallowCopy. -var spanCopiedFields = map[string]struct{}{ - "Service": {}, - "Name": {}, - "Resource": {}, - "TraceID": {}, - "SpanID": {}, - "ParentID": {}, - "Start": {}, - "Duration": {}, - "Error": {}, - "Meta": {}, - "Metrics": {}, - "Type": {}, - "MetaStruct": {}, - "SpanLinks": {}, -} - -// ShallowCopy returns a shallow copy of the copy-able portion of a Span. These are the -// public fields which will have a Get* method for them. The completeness of this -// method is enforced by the init function above. Instead of using pkg/proto/utils.ProtoCopier, -// which incurs heavy reflection cost for every copy at runtime, we use reflection once at -// startup to ensure our method is complete. -func (s *Span) ShallowCopy() *Span { - if s == nil { - return &Span{} - } - return &Span{ - Service: s.Service, - Name: s.Name, - Resource: s.Resource, - TraceID: s.TraceID, - SpanID: s.SpanID, - ParentID: s.ParentID, - Start: s.Start, - Duration: s.Duration, - Error: s.Error, - Meta: s.Meta, - Metrics: s.Metrics, - Type: s.Type, - MetaStruct: s.MetaStruct, - SpanLinks: s.SpanLinks, - } -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/span_vtproto.pb.go b/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/span_vtproto.pb.go deleted file mode 100644 index 7b6a7a03..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/span_vtproto.pb.go +++ /dev/null @@ -1,1445 +0,0 @@ -// Code generated by protoc-gen-go-vtproto. DO NOT EDIT. -// protoc-gen-go-vtproto version: v0.4.0 -// source: datadog/trace/span.proto - -package trace - -import ( - binary "encoding/binary" - fmt "fmt" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - io "io" - math "math" - bits "math/bits" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -func (m *SpanLink) MarshalVT() (dAtA []byte, err error) { - if m == nil { - return nil, nil - } - size := m.SizeVT() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBufferVT(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *SpanLink) MarshalToVT(dAtA []byte) (int, error) { - size := m.SizeVT() - return m.MarshalToSizedBufferVT(dAtA[:size]) -} - -func (m *SpanLink) MarshalToSizedBufferVT(dAtA []byte) (int, error) { - if m == nil { - return 0, nil - } - i := len(dAtA) - _ = i - var l int - _ = l - if m.unknownFields != nil { - i -= len(m.unknownFields) - copy(dAtA[i:], m.unknownFields) - } - if m.Flags != 0 { - i = encodeVarint(dAtA, i, uint64(m.Flags)) - i-- - dAtA[i] = 0x30 - } - if len(m.Tracestate) > 0 { - i -= len(m.Tracestate) - copy(dAtA[i:], m.Tracestate) - i = encodeVarint(dAtA, i, uint64(len(m.Tracestate))) - i-- - dAtA[i] = 0x2a - } - if len(m.Attributes) > 0 { - for k := range m.Attributes { - v := m.Attributes[k] - baseI := i - i -= len(v) - copy(dAtA[i:], v) - i = encodeVarint(dAtA, i, uint64(len(v))) - i-- - dAtA[i] = 0x12 - i -= len(k) - copy(dAtA[i:], k) - i = encodeVarint(dAtA, i, uint64(len(k))) - i-- - dAtA[i] = 0xa - i = encodeVarint(dAtA, i, uint64(baseI-i)) - i-- - dAtA[i] = 0x22 - } - } - if m.SpanID != 0 { - i = encodeVarint(dAtA, i, uint64(m.SpanID)) - i-- - dAtA[i] = 0x18 - } - if m.TraceIDHigh != 0 { - i = encodeVarint(dAtA, i, uint64(m.TraceIDHigh)) - i-- - dAtA[i] = 0x10 - } - if m.TraceID != 0 { - i = encodeVarint(dAtA, i, uint64(m.TraceID)) - i-- - dAtA[i] = 0x8 - } - return len(dAtA) - i, nil -} - -func (m *Span) MarshalVT() (dAtA []byte, err error) { - if m == nil { - return nil, nil - } - size := m.SizeVT() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBufferVT(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *Span) MarshalToVT(dAtA []byte) (int, error) { - size := m.SizeVT() - return m.MarshalToSizedBufferVT(dAtA[:size]) -} - -func (m *Span) MarshalToSizedBufferVT(dAtA []byte) (int, error) { - if m == nil { - return 0, nil - } - i := len(dAtA) - _ = i - var l int - _ = l - if m.unknownFields != nil { - i -= len(m.unknownFields) - copy(dAtA[i:], m.unknownFields) - } - if len(m.SpanLinks) > 0 { - for iNdEx := len(m.SpanLinks) - 1; iNdEx >= 0; iNdEx-- { - size, err := m.SpanLinks[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarint(dAtA, i, uint64(size)) - i-- - dAtA[i] = 0x72 - } - } - if len(m.MetaStruct) > 0 { - for k := range m.MetaStruct { - v := m.MetaStruct[k] - baseI := i - i -= len(v) - copy(dAtA[i:], v) - i = encodeVarint(dAtA, i, uint64(len(v))) - i-- - dAtA[i] = 0x12 - i -= len(k) - copy(dAtA[i:], k) - i = encodeVarint(dAtA, i, uint64(len(k))) - i-- - dAtA[i] = 0xa - i = encodeVarint(dAtA, i, uint64(baseI-i)) - i-- - dAtA[i] = 0x6a - } - } - if len(m.Type) > 0 { - i -= len(m.Type) - copy(dAtA[i:], m.Type) - i = encodeVarint(dAtA, i, uint64(len(m.Type))) - i-- - dAtA[i] = 0x62 - } - if len(m.Metrics) > 0 { - for k := range m.Metrics { - v := m.Metrics[k] - baseI := i - i -= 8 - binary.LittleEndian.PutUint64(dAtA[i:], uint64(math.Float64bits(float64(v)))) - i-- - dAtA[i] = 0x11 - i -= len(k) - copy(dAtA[i:], k) - i = encodeVarint(dAtA, i, uint64(len(k))) - i-- - dAtA[i] = 0xa - i = encodeVarint(dAtA, i, uint64(baseI-i)) - i-- - dAtA[i] = 0x5a - } - } - if len(m.Meta) > 0 { - for k := range m.Meta { - v := m.Meta[k] - baseI := i - i -= len(v) - copy(dAtA[i:], v) - i = encodeVarint(dAtA, i, uint64(len(v))) - i-- - dAtA[i] = 0x12 - i -= len(k) - copy(dAtA[i:], k) - i = encodeVarint(dAtA, i, uint64(len(k))) - i-- - dAtA[i] = 0xa - i = encodeVarint(dAtA, i, uint64(baseI-i)) - i-- - dAtA[i] = 0x52 - } - } - if m.Error != 0 { - i = encodeVarint(dAtA, i, uint64(m.Error)) - i-- - dAtA[i] = 0x48 - } - if m.Duration != 0 { - i = encodeVarint(dAtA, i, uint64(m.Duration)) - i-- - dAtA[i] = 0x40 - } - if m.Start != 0 { - i = encodeVarint(dAtA, i, uint64(m.Start)) - i-- - dAtA[i] = 0x38 - } - if m.ParentID != 0 { - i = encodeVarint(dAtA, i, uint64(m.ParentID)) - i-- - dAtA[i] = 0x30 - } - if m.SpanID != 0 { - i = encodeVarint(dAtA, i, uint64(m.SpanID)) - i-- - dAtA[i] = 0x28 - } - if m.TraceID != 0 { - i = encodeVarint(dAtA, i, uint64(m.TraceID)) - i-- - dAtA[i] = 0x20 - } - if len(m.Resource) > 0 { - i -= len(m.Resource) - copy(dAtA[i:], m.Resource) - i = encodeVarint(dAtA, i, uint64(len(m.Resource))) - i-- - dAtA[i] = 0x1a - } - if len(m.Name) > 0 { - i -= len(m.Name) - copy(dAtA[i:], m.Name) - i = encodeVarint(dAtA, i, uint64(len(m.Name))) - i-- - dAtA[i] = 0x12 - } - if len(m.Service) > 0 { - i -= len(m.Service) - copy(dAtA[i:], m.Service) - i = encodeVarint(dAtA, i, uint64(len(m.Service))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func encodeVarint(dAtA []byte, offset int, v uint64) int { - offset -= sov(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *SpanLink) SizeVT() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.TraceID != 0 { - n += 1 + sov(uint64(m.TraceID)) - } - if m.TraceIDHigh != 0 { - n += 1 + sov(uint64(m.TraceIDHigh)) - } - if m.SpanID != 0 { - n += 1 + sov(uint64(m.SpanID)) - } - if len(m.Attributes) > 0 { - for k, v := range m.Attributes { - _ = k - _ = v - mapEntrySize := 1 + len(k) + sov(uint64(len(k))) + 1 + len(v) + sov(uint64(len(v))) - n += mapEntrySize + 1 + sov(uint64(mapEntrySize)) - } - } - l = len(m.Tracestate) - if l > 0 { - n += 1 + l + sov(uint64(l)) - } - if m.Flags != 0 { - n += 1 + sov(uint64(m.Flags)) - } - n += len(m.unknownFields) - return n -} - -func (m *Span) SizeVT() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Service) - if l > 0 { - n += 1 + l + sov(uint64(l)) - } - l = len(m.Name) - if l > 0 { - n += 1 + l + sov(uint64(l)) - } - l = len(m.Resource) - if l > 0 { - n += 1 + l + sov(uint64(l)) - } - if m.TraceID != 0 { - n += 1 + sov(uint64(m.TraceID)) - } - if m.SpanID != 0 { - n += 1 + sov(uint64(m.SpanID)) - } - if m.ParentID != 0 { - n += 1 + sov(uint64(m.ParentID)) - } - if m.Start != 0 { - n += 1 + sov(uint64(m.Start)) - } - if m.Duration != 0 { - n += 1 + sov(uint64(m.Duration)) - } - if m.Error != 0 { - n += 1 + sov(uint64(m.Error)) - } - if len(m.Meta) > 0 { - for k, v := range m.Meta { - _ = k - _ = v - mapEntrySize := 1 + len(k) + sov(uint64(len(k))) + 1 + len(v) + sov(uint64(len(v))) - n += mapEntrySize + 1 + sov(uint64(mapEntrySize)) - } - } - if len(m.Metrics) > 0 { - for k, v := range m.Metrics { - _ = k - _ = v - mapEntrySize := 1 + len(k) + sov(uint64(len(k))) + 1 + 8 - n += mapEntrySize + 1 + sov(uint64(mapEntrySize)) - } - } - l = len(m.Type) - if l > 0 { - n += 1 + l + sov(uint64(l)) - } - if len(m.MetaStruct) > 0 { - for k, v := range m.MetaStruct { - _ = k - _ = v - l = 1 + len(v) + sov(uint64(len(v))) - mapEntrySize := 1 + len(k) + sov(uint64(len(k))) + l - n += mapEntrySize + 1 + sov(uint64(mapEntrySize)) - } - } - if len(m.SpanLinks) > 0 { - for _, e := range m.SpanLinks { - l = e.SizeVT() - n += 1 + l + sov(uint64(l)) - } - } - n += len(m.unknownFields) - return n -} - -func sov(x uint64) (n int) { - return (bits.Len64(x|1) + 6) / 7 -} -func soz(x uint64) (n int) { - return sov(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (m *SpanLink) UnmarshalVT(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: SpanLink: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: SpanLink: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field TraceID", wireType) - } - m.TraceID = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.TraceID |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field TraceIDHigh", wireType) - } - m.TraceIDHigh = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.TraceIDHigh |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field SpanID", wireType) - } - m.SpanID = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.SpanID |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Attributes", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Attributes == nil { - m.Attributes = make(map[string]string) - } - var mapkey string - var mapvalue string - for iNdEx < postIndex { - entryPreIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - if fieldNum == 1 { - var stringLenmapkey uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapkey |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapkey := int(stringLenmapkey) - if intStringLenmapkey < 0 { - return ErrInvalidLength - } - postStringIndexmapkey := iNdEx + intStringLenmapkey - if postStringIndexmapkey < 0 { - return ErrInvalidLength - } - if postStringIndexmapkey > l { - return io.ErrUnexpectedEOF - } - mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) - iNdEx = postStringIndexmapkey - } else if fieldNum == 2 { - var stringLenmapvalue uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapvalue |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapvalue := int(stringLenmapvalue) - if intStringLenmapvalue < 0 { - return ErrInvalidLength - } - postStringIndexmapvalue := iNdEx + intStringLenmapvalue - if postStringIndexmapvalue < 0 { - return ErrInvalidLength - } - if postStringIndexmapvalue > l { - return io.ErrUnexpectedEOF - } - mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue]) - iNdEx = postStringIndexmapvalue - } else { - iNdEx = entryPreIndex - skippy, err := skip(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength - } - if (iNdEx + skippy) > postIndex { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - m.Attributes[mapkey] = mapvalue - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Tracestate", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Tracestate = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 6: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Flags", wireType) - } - m.Flags = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Flags |= uint32(b&0x7F) << shift - if b < 0x80 { - break - } - } - default: - iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *Span) UnmarshalVT(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Span: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Span: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Service", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Service = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Resource", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Resource = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field TraceID", wireType) - } - m.TraceID = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.TraceID |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 5: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field SpanID", wireType) - } - m.SpanID = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.SpanID |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 6: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ParentID", wireType) - } - m.ParentID = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.ParentID |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 7: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Start", wireType) - } - m.Start = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Start |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 8: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Duration", wireType) - } - m.Duration = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Duration |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 9: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) - } - m.Error = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Error |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 10: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Meta", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Meta == nil { - m.Meta = make(map[string]string) - } - var mapkey string - var mapvalue string - for iNdEx < postIndex { - entryPreIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - if fieldNum == 1 { - var stringLenmapkey uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapkey |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapkey := int(stringLenmapkey) - if intStringLenmapkey < 0 { - return ErrInvalidLength - } - postStringIndexmapkey := iNdEx + intStringLenmapkey - if postStringIndexmapkey < 0 { - return ErrInvalidLength - } - if postStringIndexmapkey > l { - return io.ErrUnexpectedEOF - } - mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) - iNdEx = postStringIndexmapkey - } else if fieldNum == 2 { - var stringLenmapvalue uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapvalue |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapvalue := int(stringLenmapvalue) - if intStringLenmapvalue < 0 { - return ErrInvalidLength - } - postStringIndexmapvalue := iNdEx + intStringLenmapvalue - if postStringIndexmapvalue < 0 { - return ErrInvalidLength - } - if postStringIndexmapvalue > l { - return io.ErrUnexpectedEOF - } - mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue]) - iNdEx = postStringIndexmapvalue - } else { - iNdEx = entryPreIndex - skippy, err := skip(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength - } - if (iNdEx + skippy) > postIndex { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - m.Meta[mapkey] = mapvalue - iNdEx = postIndex - case 11: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Metrics", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Metrics == nil { - m.Metrics = make(map[string]float64) - } - var mapkey string - var mapvalue float64 - for iNdEx < postIndex { - entryPreIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - if fieldNum == 1 { - var stringLenmapkey uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapkey |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapkey := int(stringLenmapkey) - if intStringLenmapkey < 0 { - return ErrInvalidLength - } - postStringIndexmapkey := iNdEx + intStringLenmapkey - if postStringIndexmapkey < 0 { - return ErrInvalidLength - } - if postStringIndexmapkey > l { - return io.ErrUnexpectedEOF - } - mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) - iNdEx = postStringIndexmapkey - } else if fieldNum == 2 { - var mapvaluetemp uint64 - if (iNdEx + 8) > l { - return io.ErrUnexpectedEOF - } - mapvaluetemp = uint64(binary.LittleEndian.Uint64(dAtA[iNdEx:])) - iNdEx += 8 - mapvalue = math.Float64frombits(mapvaluetemp) - } else { - iNdEx = entryPreIndex - skippy, err := skip(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength - } - if (iNdEx + skippy) > postIndex { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - m.Metrics[mapkey] = mapvalue - iNdEx = postIndex - case 12: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Type = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 13: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field MetaStruct", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.MetaStruct == nil { - m.MetaStruct = make(map[string][]byte) - } - var mapkey string - var mapvalue []byte - for iNdEx < postIndex { - entryPreIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - if fieldNum == 1 { - var stringLenmapkey uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapkey |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapkey := int(stringLenmapkey) - if intStringLenmapkey < 0 { - return ErrInvalidLength - } - postStringIndexmapkey := iNdEx + intStringLenmapkey - if postStringIndexmapkey < 0 { - return ErrInvalidLength - } - if postStringIndexmapkey > l { - return io.ErrUnexpectedEOF - } - mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) - iNdEx = postStringIndexmapkey - } else if fieldNum == 2 { - var mapbyteLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - mapbyteLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intMapbyteLen := int(mapbyteLen) - if intMapbyteLen < 0 { - return ErrInvalidLength - } - postbytesIndex := iNdEx + intMapbyteLen - if postbytesIndex < 0 { - return ErrInvalidLength - } - if postbytesIndex > l { - return io.ErrUnexpectedEOF - } - mapvalue = make([]byte, mapbyteLen) - copy(mapvalue, dAtA[iNdEx:postbytesIndex]) - iNdEx = postbytesIndex - } else { - iNdEx = entryPreIndex - skippy, err := skip(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength - } - if (iNdEx + skippy) > postIndex { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - m.MetaStruct[mapkey] = mapvalue - iNdEx = postIndex - case 14: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SpanLinks", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.SpanLinks = append(m.SpanLinks, &SpanLink{}) - if err := m.SpanLinks[len(m.SpanLinks)-1].UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} - -func skip(dAtA []byte) (n int, err error) { - l := len(dAtA) - iNdEx := 0 - depth := 0 - for iNdEx < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflow - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflow - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - iNdEx++ - if dAtA[iNdEx-1] < 0x80 { - break - } - } - case 1: - iNdEx += 8 - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflow - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if length < 0 { - return 0, ErrInvalidLength - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroup - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLength - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLength = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflow = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroup = fmt.Errorf("proto: unexpected end of group") -) diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/stats.pb.go b/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/stats.pb.go deleted file mode 100644 index 52d51fff..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/stats.pb.go +++ /dev/null @@ -1,837 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.34.0 -// protoc v5.26.1 -// source: datadog/trace/stats.proto - -package trace - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// Trilean is an expanded boolean type that is meant to differentiate between being unset and false. -type Trilean int32 - -const ( - Trilean_NOT_SET Trilean = 0 - Trilean_TRUE Trilean = 1 - Trilean_FALSE Trilean = 2 -) - -// Enum value maps for Trilean. -var ( - Trilean_name = map[int32]string{ - 0: "NOT_SET", - 1: "TRUE", - 2: "FALSE", - } - Trilean_value = map[string]int32{ - "NOT_SET": 0, - "TRUE": 1, - "FALSE": 2, - } -) - -func (x Trilean) Enum() *Trilean { - p := new(Trilean) - *p = x - return p -} - -func (x Trilean) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (Trilean) Descriptor() protoreflect.EnumDescriptor { - return file_datadog_trace_stats_proto_enumTypes[0].Descriptor() -} - -func (Trilean) Type() protoreflect.EnumType { - return &file_datadog_trace_stats_proto_enumTypes[0] -} - -func (x Trilean) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use Trilean.Descriptor instead. -func (Trilean) EnumDescriptor() ([]byte, []int) { - return file_datadog_trace_stats_proto_rawDescGZIP(), []int{0} -} - -type TraceRootFlag int32 - -const ( - TraceRootFlag_DEPRECATED_NOT_SET TraceRootFlag = 0 - TraceRootFlag_DEPRECATED_TRUE TraceRootFlag = 1 - TraceRootFlag_DEPRECATED_FALSE TraceRootFlag = 2 -) - -// Enum value maps for TraceRootFlag. -var ( - TraceRootFlag_name = map[int32]string{ - 0: "DEPRECATED_NOT_SET", - 1: "DEPRECATED_TRUE", - 2: "DEPRECATED_FALSE", - } - TraceRootFlag_value = map[string]int32{ - "DEPRECATED_NOT_SET": 0, - "DEPRECATED_TRUE": 1, - "DEPRECATED_FALSE": 2, - } -) - -func (x TraceRootFlag) Enum() *TraceRootFlag { - p := new(TraceRootFlag) - *p = x - return p -} - -func (x TraceRootFlag) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (TraceRootFlag) Descriptor() protoreflect.EnumDescriptor { - return file_datadog_trace_stats_proto_enumTypes[1].Descriptor() -} - -func (TraceRootFlag) Type() protoreflect.EnumType { - return &file_datadog_trace_stats_proto_enumTypes[1] -} - -func (x TraceRootFlag) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use TraceRootFlag.Descriptor instead. -func (TraceRootFlag) EnumDescriptor() ([]byte, []int) { - return file_datadog_trace_stats_proto_rawDescGZIP(), []int{1} -} - -// StatsPayload is the payload used to send stats from the agent to the backend. -type StatsPayload struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - AgentHostname string `protobuf:"bytes,1,opt,name=agentHostname,proto3" json:"agentHostname,omitempty"` - AgentEnv string `protobuf:"bytes,2,opt,name=agentEnv,proto3" json:"agentEnv,omitempty"` - // @gotags: json:"stats,omitempty" msg:"Stats,omitempty" - Stats []*ClientStatsPayload `protobuf:"bytes,3,rep,name=stats,proto3" json:"stats,omitempty" msg:"Stats,omitempty"` - AgentVersion string `protobuf:"bytes,4,opt,name=agentVersion,proto3" json:"agentVersion,omitempty"` - ClientComputed bool `protobuf:"varint,5,opt,name=clientComputed,proto3" json:"clientComputed,omitempty"` - // splitPayload indicates if the payload is actually one of several payloads split out from a larger payload. - // This field can be used in the backend to signal if re-aggregation is necessary. - SplitPayload bool `protobuf:"varint,6,opt,name=splitPayload,proto3" json:"splitPayload,omitempty"` -} - -func (x *StatsPayload) Reset() { - *x = StatsPayload{} - if protoimpl.UnsafeEnabled { - mi := &file_datadog_trace_stats_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *StatsPayload) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*StatsPayload) ProtoMessage() {} - -func (x *StatsPayload) ProtoReflect() protoreflect.Message { - mi := &file_datadog_trace_stats_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use StatsPayload.ProtoReflect.Descriptor instead. -func (*StatsPayload) Descriptor() ([]byte, []int) { - return file_datadog_trace_stats_proto_rawDescGZIP(), []int{0} -} - -func (x *StatsPayload) GetAgentHostname() string { - if x != nil { - return x.AgentHostname - } - return "" -} - -func (x *StatsPayload) GetAgentEnv() string { - if x != nil { - return x.AgentEnv - } - return "" -} - -func (x *StatsPayload) GetStats() []*ClientStatsPayload { - if x != nil { - return x.Stats - } - return nil -} - -func (x *StatsPayload) GetAgentVersion() string { - if x != nil { - return x.AgentVersion - } - return "" -} - -func (x *StatsPayload) GetClientComputed() bool { - if x != nil { - return x.ClientComputed - } - return false -} - -func (x *StatsPayload) GetSplitPayload() bool { - if x != nil { - return x.SplitPayload - } - return false -} - -// ClientStatsPayload is the first layer of span stats aggregation. It is also -// the payload sent by tracers to the agent when stats in tracer are enabled. -type ClientStatsPayload struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Hostname is the tracer hostname. It's extracted from spans with "_dd.hostname" meta - // or set by tracer stats payload when hostname reporting is enabled. - Hostname string `protobuf:"bytes,1,opt,name=hostname,proto3" json:"hostname,omitempty"` - Env string `protobuf:"bytes,2,opt,name=env,proto3" json:"env,omitempty"` // env tag set on spans or in the tracers, used for aggregation - Version string `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"` // version tag set on spans or in the tracers, used for aggregation - // @gotags: json:"stats,omitempty" msg:"Stats,omitempty" - Stats []*ClientStatsBucket `protobuf:"bytes,4,rep,name=stats,proto3" json:"stats,omitempty" msg:"Stats,omitempty"` - Lang string `protobuf:"bytes,5,opt,name=lang,proto3" json:"lang,omitempty"` // informative field not used for aggregation - TracerVersion string `protobuf:"bytes,6,opt,name=tracerVersion,proto3" json:"tracerVersion,omitempty"` // informative field not used for aggregation - RuntimeID string `protobuf:"bytes,7,opt,name=runtimeID,proto3" json:"runtimeID,omitempty"` // used on stats payloads sent by the tracer to identify uniquely a message - Sequence uint64 `protobuf:"varint,8,opt,name=sequence,proto3" json:"sequence,omitempty"` // used on stats payloads sent by the tracer to identify uniquely a message - // AgentAggregation is set by the agent on tracer payloads modified by the agent aggregation layer - // characterizes counts only and distributions only payloads - AgentAggregation string `protobuf:"bytes,9,opt,name=agentAggregation,proto3" json:"agentAggregation,omitempty"` - // Service is the main service of the tracer. - // It is part of unified tagging: https://docs.datadoghq.com/getting_started/tagging/unified_service_tagging - Service string `protobuf:"bytes,10,opt,name=service,proto3" json:"service,omitempty"` - // ContainerID specifies the origin container ID. It is meant to be populated by the client and may - // be enhanced by the agent to ensure it is unique. - ContainerID string `protobuf:"bytes,11,opt,name=containerID,proto3" json:"containerID,omitempty"` - // Tags specifies a set of tags obtained from the orchestrator (where applicable) using the specified containerID. - // This field should be left empty by the client. It only applies to some specific environment. - Tags []string `protobuf:"bytes,12,rep,name=tags,proto3" json:"tags,omitempty"` - // The git commit SHA is obtained from a trace, where it may be set through a tracer <-> source code integration. - GitCommitSha string `protobuf:"bytes,13,opt,name=git_commit_sha,json=gitCommitSha,proto3" json:"git_commit_sha,omitempty"` - // The image tag is obtained from a container's set of tags. - ImageTag string `protobuf:"bytes,14,opt,name=image_tag,json=imageTag,proto3" json:"image_tag,omitempty"` -} - -func (x *ClientStatsPayload) Reset() { - *x = ClientStatsPayload{} - if protoimpl.UnsafeEnabled { - mi := &file_datadog_trace_stats_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ClientStatsPayload) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ClientStatsPayload) ProtoMessage() {} - -func (x *ClientStatsPayload) ProtoReflect() protoreflect.Message { - mi := &file_datadog_trace_stats_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ClientStatsPayload.ProtoReflect.Descriptor instead. -func (*ClientStatsPayload) Descriptor() ([]byte, []int) { - return file_datadog_trace_stats_proto_rawDescGZIP(), []int{1} -} - -func (x *ClientStatsPayload) GetHostname() string { - if x != nil { - return x.Hostname - } - return "" -} - -func (x *ClientStatsPayload) GetEnv() string { - if x != nil { - return x.Env - } - return "" -} - -func (x *ClientStatsPayload) GetVersion() string { - if x != nil { - return x.Version - } - return "" -} - -func (x *ClientStatsPayload) GetStats() []*ClientStatsBucket { - if x != nil { - return x.Stats - } - return nil -} - -func (x *ClientStatsPayload) GetLang() string { - if x != nil { - return x.Lang - } - return "" -} - -func (x *ClientStatsPayload) GetTracerVersion() string { - if x != nil { - return x.TracerVersion - } - return "" -} - -func (x *ClientStatsPayload) GetRuntimeID() string { - if x != nil { - return x.RuntimeID - } - return "" -} - -func (x *ClientStatsPayload) GetSequence() uint64 { - if x != nil { - return x.Sequence - } - return 0 -} - -func (x *ClientStatsPayload) GetAgentAggregation() string { - if x != nil { - return x.AgentAggregation - } - return "" -} - -func (x *ClientStatsPayload) GetService() string { - if x != nil { - return x.Service - } - return "" -} - -func (x *ClientStatsPayload) GetContainerID() string { - if x != nil { - return x.ContainerID - } - return "" -} - -func (x *ClientStatsPayload) GetTags() []string { - if x != nil { - return x.Tags - } - return nil -} - -func (x *ClientStatsPayload) GetGitCommitSha() string { - if x != nil { - return x.GitCommitSha - } - return "" -} - -func (x *ClientStatsPayload) GetImageTag() string { - if x != nil { - return x.ImageTag - } - return "" -} - -// ClientStatsBucket is a time bucket containing aggregated stats. -type ClientStatsBucket struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Start uint64 `protobuf:"varint,1,opt,name=start,proto3" json:"start,omitempty"` // bucket start in nanoseconds - Duration uint64 `protobuf:"varint,2,opt,name=duration,proto3" json:"duration,omitempty"` // bucket duration in nanoseconds - // @gotags: json:"stats,omitempty" msg:"Stats,omitempty" - Stats []*ClientGroupedStats `protobuf:"bytes,3,rep,name=stats,proto3" json:"stats,omitempty" msg:"Stats,omitempty"` - // AgentTimeShift is the shift applied by the agent stats aggregator on bucket start - // when the received bucket start is outside of the agent aggregation window - AgentTimeShift int64 `protobuf:"varint,4,opt,name=agentTimeShift,proto3" json:"agentTimeShift,omitempty"` -} - -func (x *ClientStatsBucket) Reset() { - *x = ClientStatsBucket{} - if protoimpl.UnsafeEnabled { - mi := &file_datadog_trace_stats_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ClientStatsBucket) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ClientStatsBucket) ProtoMessage() {} - -func (x *ClientStatsBucket) ProtoReflect() protoreflect.Message { - mi := &file_datadog_trace_stats_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ClientStatsBucket.ProtoReflect.Descriptor instead. -func (*ClientStatsBucket) Descriptor() ([]byte, []int) { - return file_datadog_trace_stats_proto_rawDescGZIP(), []int{2} -} - -func (x *ClientStatsBucket) GetStart() uint64 { - if x != nil { - return x.Start - } - return 0 -} - -func (x *ClientStatsBucket) GetDuration() uint64 { - if x != nil { - return x.Duration - } - return 0 -} - -func (x *ClientStatsBucket) GetStats() []*ClientGroupedStats { - if x != nil { - return x.Stats - } - return nil -} - -func (x *ClientStatsBucket) GetAgentTimeShift() int64 { - if x != nil { - return x.AgentTimeShift - } - return 0 -} - -// ClientGroupedStats aggregate stats on spans grouped by service, name, resource, status_code, type -type ClientGroupedStats struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Service string `protobuf:"bytes,1,opt,name=service,proto3" json:"service,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - Resource string `protobuf:"bytes,3,opt,name=resource,proto3" json:"resource,omitempty"` - HTTPStatusCode uint32 `protobuf:"varint,4,opt,name=HTTP_status_code,json=HTTPStatusCode,proto3" json:"HTTP_status_code,omitempty"` - Type string `protobuf:"bytes,5,opt,name=type,proto3" json:"type,omitempty"` - DBType string `protobuf:"bytes,6,opt,name=DB_type,json=DBType,proto3" json:"DB_type,omitempty"` // db_type might be used in the future to help in the obfuscation step - Hits uint64 `protobuf:"varint,7,opt,name=hits,proto3" json:"hits,omitempty"` // count of all spans aggregated in the groupedstats - Errors uint64 `protobuf:"varint,8,opt,name=errors,proto3" json:"errors,omitempty"` // count of error spans aggregated in the groupedstats - Duration uint64 `protobuf:"varint,9,opt,name=duration,proto3" json:"duration,omitempty"` // total duration in nanoseconds of spans aggregated in the bucket - OkSummary []byte `protobuf:"bytes,10,opt,name=okSummary,proto3" json:"okSummary,omitempty"` // ddsketch summary of ok spans latencies encoded in protobuf - ErrorSummary []byte `protobuf:"bytes,11,opt,name=errorSummary,proto3" json:"errorSummary,omitempty"` // ddsketch summary of error spans latencies encoded in protobuf - Synthetics bool `protobuf:"varint,12,opt,name=synthetics,proto3" json:"synthetics,omitempty"` // set to true on spans generated by synthetics traffic - TopLevelHits uint64 `protobuf:"varint,13,opt,name=topLevelHits,proto3" json:"topLevelHits,omitempty"` // count of top level spans aggregated in the groupedstats - SpanKind string `protobuf:"bytes,15,opt,name=span_kind,json=spanKind,proto3" json:"span_kind,omitempty"` // value of the span.kind tag on the span - // peer_tags are supplementary tags that further describe a peer entity - // E.g., `grpc.target` to describe the name of a gRPC peer, or `db.hostname` to describe the name of peer DB - PeerTags []string `protobuf:"bytes,16,rep,name=peer_tags,json=peerTags,proto3" json:"peer_tags,omitempty"` - IsTraceRoot Trilean `protobuf:"varint,17,opt,name=is_trace_root,json=isTraceRoot,proto3,enum=datadog.trace.Trilean" json:"is_trace_root,omitempty"` // this field's value is equal to span's ParentID == 0. -} - -func (x *ClientGroupedStats) Reset() { - *x = ClientGroupedStats{} - if protoimpl.UnsafeEnabled { - mi := &file_datadog_trace_stats_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ClientGroupedStats) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ClientGroupedStats) ProtoMessage() {} - -func (x *ClientGroupedStats) ProtoReflect() protoreflect.Message { - mi := &file_datadog_trace_stats_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ClientGroupedStats.ProtoReflect.Descriptor instead. -func (*ClientGroupedStats) Descriptor() ([]byte, []int) { - return file_datadog_trace_stats_proto_rawDescGZIP(), []int{3} -} - -func (x *ClientGroupedStats) GetService() string { - if x != nil { - return x.Service - } - return "" -} - -func (x *ClientGroupedStats) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *ClientGroupedStats) GetResource() string { - if x != nil { - return x.Resource - } - return "" -} - -func (x *ClientGroupedStats) GetHTTPStatusCode() uint32 { - if x != nil { - return x.HTTPStatusCode - } - return 0 -} - -func (x *ClientGroupedStats) GetType() string { - if x != nil { - return x.Type - } - return "" -} - -func (x *ClientGroupedStats) GetDBType() string { - if x != nil { - return x.DBType - } - return "" -} - -func (x *ClientGroupedStats) GetHits() uint64 { - if x != nil { - return x.Hits - } - return 0 -} - -func (x *ClientGroupedStats) GetErrors() uint64 { - if x != nil { - return x.Errors - } - return 0 -} - -func (x *ClientGroupedStats) GetDuration() uint64 { - if x != nil { - return x.Duration - } - return 0 -} - -func (x *ClientGroupedStats) GetOkSummary() []byte { - if x != nil { - return x.OkSummary - } - return nil -} - -func (x *ClientGroupedStats) GetErrorSummary() []byte { - if x != nil { - return x.ErrorSummary - } - return nil -} - -func (x *ClientGroupedStats) GetSynthetics() bool { - if x != nil { - return x.Synthetics - } - return false -} - -func (x *ClientGroupedStats) GetTopLevelHits() uint64 { - if x != nil { - return x.TopLevelHits - } - return 0 -} - -func (x *ClientGroupedStats) GetSpanKind() string { - if x != nil { - return x.SpanKind - } - return "" -} - -func (x *ClientGroupedStats) GetPeerTags() []string { - if x != nil { - return x.PeerTags - } - return nil -} - -func (x *ClientGroupedStats) GetIsTraceRoot() Trilean { - if x != nil { - return x.IsTraceRoot - } - return Trilean_NOT_SET -} - -var File_datadog_trace_stats_proto protoreflect.FileDescriptor - -var file_datadog_trace_stats_proto_rawDesc = []byte{ - 0x0a, 0x19, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2f, - 0x73, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x64, 0x61, 0x74, - 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x22, 0xf9, 0x01, 0x0a, 0x0c, 0x53, - 0x74, 0x61, 0x74, 0x73, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x61, - 0x67, 0x65, 0x6e, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0d, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, - 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x45, 0x6e, 0x76, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x45, 0x6e, 0x76, 0x12, 0x37, 0x0a, - 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x64, - 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x43, 0x6c, 0x69, - 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x52, - 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x56, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x61, 0x67, - 0x65, 0x6e, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x26, 0x0a, 0x0e, 0x63, 0x6c, - 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x0e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, - 0x65, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x50, 0x61, 0x79, 0x6c, 0x6f, - 0x61, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x50, - 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0xc7, 0x03, 0x0a, 0x12, 0x43, 0x6c, 0x69, 0x65, 0x6e, - 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x1a, 0x0a, - 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, 0x76, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x65, 0x6e, 0x76, 0x12, 0x18, 0x0a, 0x07, 0x76, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x36, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x04, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x74, - 0x72, 0x61, 0x63, 0x65, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, - 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x12, 0x12, 0x0a, - 0x04, 0x6c, 0x61, 0x6e, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x61, 0x6e, - 0x67, 0x12, 0x24, 0x0a, 0x0d, 0x74, 0x72, 0x61, 0x63, 0x65, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x63, 0x65, 0x72, - 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x75, 0x6e, 0x74, 0x69, - 0x6d, 0x65, 0x49, 0x44, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x49, 0x44, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, - 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, - 0x65, 0x12, 0x2a, 0x0a, 0x10, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x61, 0x67, 0x65, - 0x6e, 0x74, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, - 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x49, 0x44, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, 0x67, - 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x24, 0x0a, - 0x0e, 0x67, 0x69, 0x74, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x73, 0x68, 0x61, 0x18, - 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x67, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, - 0x53, 0x68, 0x61, 0x12, 0x1b, 0x0a, 0x09, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x61, 0x67, - 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x54, 0x61, 0x67, - 0x22, 0xa6, 0x01, 0x0a, 0x11, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, - 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x1a, 0x0a, 0x08, - 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, - 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x37, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, - 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, - 0x67, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x47, 0x72, - 0x6f, 0x75, 0x70, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, - 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x68, - 0x69, 0x66, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x61, 0x67, 0x65, 0x6e, 0x74, - 0x54, 0x69, 0x6d, 0x65, 0x53, 0x68, 0x69, 0x66, 0x74, 0x22, 0xff, 0x03, 0x0a, 0x12, 0x43, 0x6c, - 0x69, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x73, - 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, - 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x48, 0x54, - 0x54, 0x50, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x48, 0x54, 0x54, 0x50, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x43, 0x6f, 0x64, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x44, 0x42, 0x5f, 0x74, - 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x44, 0x42, 0x54, 0x79, 0x70, - 0x65, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x69, 0x74, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x04, 0x68, 0x69, 0x74, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, - 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x12, 0x1a, 0x0a, - 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x6f, 0x6b, 0x53, - 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x6f, 0x6b, - 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x22, 0x0a, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x65, - 0x72, 0x72, 0x6f, 0x72, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x1e, 0x0a, 0x0a, 0x73, - 0x79, 0x6e, 0x74, 0x68, 0x65, 0x74, 0x69, 0x63, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x0a, 0x73, 0x79, 0x6e, 0x74, 0x68, 0x65, 0x74, 0x69, 0x63, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x74, - 0x6f, 0x70, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x48, 0x69, 0x74, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x0c, 0x74, 0x6f, 0x70, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x48, 0x69, 0x74, 0x73, 0x12, - 0x1b, 0x0a, 0x09, 0x73, 0x70, 0x61, 0x6e, 0x5f, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x0f, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x73, 0x70, 0x61, 0x6e, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x1b, 0x0a, 0x09, - 0x70, 0x65, 0x65, 0x72, 0x5f, 0x74, 0x61, 0x67, 0x73, 0x18, 0x10, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x08, 0x70, 0x65, 0x65, 0x72, 0x54, 0x61, 0x67, 0x73, 0x12, 0x3a, 0x0a, 0x0d, 0x69, 0x73, 0x5f, - 0x74, 0x72, 0x61, 0x63, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x16, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, - 0x2e, 0x54, 0x72, 0x69, 0x6c, 0x65, 0x61, 0x6e, 0x52, 0x0b, 0x69, 0x73, 0x54, 0x72, 0x61, 0x63, - 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x4a, 0x04, 0x08, 0x0e, 0x10, 0x0f, 0x2a, 0x2b, 0x0a, 0x07, 0x54, - 0x72, 0x69, 0x6c, 0x65, 0x61, 0x6e, 0x12, 0x0b, 0x0a, 0x07, 0x4e, 0x4f, 0x54, 0x5f, 0x53, 0x45, - 0x54, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x54, 0x52, 0x55, 0x45, 0x10, 0x01, 0x12, 0x09, 0x0a, - 0x05, 0x46, 0x41, 0x4c, 0x53, 0x45, 0x10, 0x02, 0x2a, 0x52, 0x0a, 0x0d, 0x54, 0x72, 0x61, 0x63, - 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x46, 0x6c, 0x61, 0x67, 0x12, 0x16, 0x0a, 0x12, 0x44, 0x45, 0x50, - 0x52, 0x45, 0x43, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x53, 0x45, 0x54, 0x10, - 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x44, 0x45, 0x50, 0x52, 0x45, 0x43, 0x41, 0x54, 0x45, 0x44, 0x5f, - 0x54, 0x52, 0x55, 0x45, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x44, 0x45, 0x50, 0x52, 0x45, 0x43, - 0x41, 0x54, 0x45, 0x44, 0x5f, 0x46, 0x41, 0x4c, 0x53, 0x45, 0x10, 0x02, 0x42, 0x16, 0x5a, 0x14, - 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x67, 0x6f, 0x2f, 0x74, - 0x72, 0x61, 0x63, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_datadog_trace_stats_proto_rawDescOnce sync.Once - file_datadog_trace_stats_proto_rawDescData = file_datadog_trace_stats_proto_rawDesc -) - -func file_datadog_trace_stats_proto_rawDescGZIP() []byte { - file_datadog_trace_stats_proto_rawDescOnce.Do(func() { - file_datadog_trace_stats_proto_rawDescData = protoimpl.X.CompressGZIP(file_datadog_trace_stats_proto_rawDescData) - }) - return file_datadog_trace_stats_proto_rawDescData -} - -var file_datadog_trace_stats_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_datadog_trace_stats_proto_msgTypes = make([]protoimpl.MessageInfo, 4) -var file_datadog_trace_stats_proto_goTypes = []interface{}{ - (Trilean)(0), // 0: datadog.trace.Trilean - (TraceRootFlag)(0), // 1: datadog.trace.TraceRootFlag - (*StatsPayload)(nil), // 2: datadog.trace.StatsPayload - (*ClientStatsPayload)(nil), // 3: datadog.trace.ClientStatsPayload - (*ClientStatsBucket)(nil), // 4: datadog.trace.ClientStatsBucket - (*ClientGroupedStats)(nil), // 5: datadog.trace.ClientGroupedStats -} -var file_datadog_trace_stats_proto_depIdxs = []int32{ - 3, // 0: datadog.trace.StatsPayload.stats:type_name -> datadog.trace.ClientStatsPayload - 4, // 1: datadog.trace.ClientStatsPayload.stats:type_name -> datadog.trace.ClientStatsBucket - 5, // 2: datadog.trace.ClientStatsBucket.stats:type_name -> datadog.trace.ClientGroupedStats - 0, // 3: datadog.trace.ClientGroupedStats.is_trace_root:type_name -> datadog.trace.Trilean - 4, // [4:4] is the sub-list for method output_type - 4, // [4:4] is the sub-list for method input_type - 4, // [4:4] is the sub-list for extension type_name - 4, // [4:4] is the sub-list for extension extendee - 0, // [0:4] is the sub-list for field type_name -} - -func init() { file_datadog_trace_stats_proto_init() } -func file_datadog_trace_stats_proto_init() { - if File_datadog_trace_stats_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_datadog_trace_stats_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*StatsPayload); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_datadog_trace_stats_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ClientStatsPayload); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_datadog_trace_stats_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ClientStatsBucket); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_datadog_trace_stats_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ClientGroupedStats); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_datadog_trace_stats_proto_rawDesc, - NumEnums: 2, - NumMessages: 4, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_datadog_trace_stats_proto_goTypes, - DependencyIndexes: file_datadog_trace_stats_proto_depIdxs, - EnumInfos: file_datadog_trace_stats_proto_enumTypes, - MessageInfos: file_datadog_trace_stats_proto_msgTypes, - }.Build() - File_datadog_trace_stats_proto = out.File - file_datadog_trace_stats_proto_rawDesc = nil - file_datadog_trace_stats_proto_goTypes = nil - file_datadog_trace_stats_proto_depIdxs = nil -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/stats_gen.go b/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/stats_gen.go deleted file mode 100644 index 0747621c..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/stats_gen.go +++ /dev/null @@ -1,1844 +0,0 @@ -package trace - -// Code generated by github.com/tinylib/msgp DO NOT EDIT. - -import ( - "github.com/tinylib/msgp/msgp" -) - -// DecodeMsg implements msgp.Decodable -func (z *ClientGroupedStats) DecodeMsg(dc *msgp.Reader) (err error) { - var field []byte - _ = field - var zb0001 uint32 - zb0001, err = dc.ReadMapHeader() - if err != nil { - err = msgp.WrapError(err) - return - } - for zb0001 > 0 { - zb0001-- - field, err = dc.ReadMapKeyPtr() - if err != nil { - err = msgp.WrapError(err) - return - } - switch msgp.UnsafeString(field) { - case "Service": - z.Service, err = dc.ReadString() - if err != nil { - err = msgp.WrapError(err, "Service") - return - } - case "Name": - z.Name, err = dc.ReadString() - if err != nil { - err = msgp.WrapError(err, "Name") - return - } - case "Resource": - z.Resource, err = dc.ReadString() - if err != nil { - err = msgp.WrapError(err, "Resource") - return - } - case "HTTPStatusCode": - z.HTTPStatusCode, err = dc.ReadUint32() - if err != nil { - err = msgp.WrapError(err, "HTTPStatusCode") - return - } - case "Type": - z.Type, err = dc.ReadString() - if err != nil { - err = msgp.WrapError(err, "Type") - return - } - case "DBType": - z.DBType, err = dc.ReadString() - if err != nil { - err = msgp.WrapError(err, "DBType") - return - } - case "Hits": - z.Hits, err = dc.ReadUint64() - if err != nil { - err = msgp.WrapError(err, "Hits") - return - } - case "Errors": - z.Errors, err = dc.ReadUint64() - if err != nil { - err = msgp.WrapError(err, "Errors") - return - } - case "Duration": - z.Duration, err = dc.ReadUint64() - if err != nil { - err = msgp.WrapError(err, "Duration") - return - } - case "OkSummary": - z.OkSummary, err = dc.ReadBytes(z.OkSummary) - if err != nil { - err = msgp.WrapError(err, "OkSummary") - return - } - case "ErrorSummary": - z.ErrorSummary, err = dc.ReadBytes(z.ErrorSummary) - if err != nil { - err = msgp.WrapError(err, "ErrorSummary") - return - } - case "Synthetics": - z.Synthetics, err = dc.ReadBool() - if err != nil { - err = msgp.WrapError(err, "Synthetics") - return - } - case "TopLevelHits": - z.TopLevelHits, err = dc.ReadUint64() - if err != nil { - err = msgp.WrapError(err, "TopLevelHits") - return - } - case "SpanKind": - z.SpanKind, err = dc.ReadString() - if err != nil { - err = msgp.WrapError(err, "SpanKind") - return - } - case "PeerTags": - var zb0002 uint32 - zb0002, err = dc.ReadArrayHeader() - if err != nil { - err = msgp.WrapError(err, "PeerTags") - return - } - if cap(z.PeerTags) >= int(zb0002) { - z.PeerTags = (z.PeerTags)[:zb0002] - } else { - z.PeerTags = make([]string, zb0002) - } - for za0001 := range z.PeerTags { - z.PeerTags[za0001], err = dc.ReadString() - if err != nil { - err = msgp.WrapError(err, "PeerTags", za0001) - return - } - } - case "IsTraceRoot": - { - var zb0003 int32 - zb0003, err = dc.ReadInt32() - if err != nil { - err = msgp.WrapError(err, "IsTraceRoot") - return - } - z.IsTraceRoot = Trilean(zb0003) - } - default: - err = dc.Skip() - if err != nil { - err = msgp.WrapError(err) - return - } - } - } - return -} - -// EncodeMsg implements msgp.Encodable -func (z *ClientGroupedStats) EncodeMsg(en *msgp.Writer) (err error) { - // map header, size 16 - // write "Service" - err = en.Append(0xde, 0x0, 0x10, 0xa7, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65) - if err != nil { - return - } - err = en.WriteString(z.Service) - if err != nil { - err = msgp.WrapError(err, "Service") - return - } - // write "Name" - err = en.Append(0xa4, 0x4e, 0x61, 0x6d, 0x65) - if err != nil { - return - } - err = en.WriteString(z.Name) - if err != nil { - err = msgp.WrapError(err, "Name") - return - } - // write "Resource" - err = en.Append(0xa8, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65) - if err != nil { - return - } - err = en.WriteString(z.Resource) - if err != nil { - err = msgp.WrapError(err, "Resource") - return - } - // write "HTTPStatusCode" - err = en.Append(0xae, 0x48, 0x54, 0x54, 0x50, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x6f, 0x64, 0x65) - if err != nil { - return - } - err = en.WriteUint32(z.HTTPStatusCode) - if err != nil { - err = msgp.WrapError(err, "HTTPStatusCode") - return - } - // write "Type" - err = en.Append(0xa4, 0x54, 0x79, 0x70, 0x65) - if err != nil { - return - } - err = en.WriteString(z.Type) - if err != nil { - err = msgp.WrapError(err, "Type") - return - } - // write "DBType" - err = en.Append(0xa6, 0x44, 0x42, 0x54, 0x79, 0x70, 0x65) - if err != nil { - return - } - err = en.WriteString(z.DBType) - if err != nil { - err = msgp.WrapError(err, "DBType") - return - } - // write "Hits" - err = en.Append(0xa4, 0x48, 0x69, 0x74, 0x73) - if err != nil { - return - } - err = en.WriteUint64(z.Hits) - if err != nil { - err = msgp.WrapError(err, "Hits") - return - } - // write "Errors" - err = en.Append(0xa6, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73) - if err != nil { - return - } - err = en.WriteUint64(z.Errors) - if err != nil { - err = msgp.WrapError(err, "Errors") - return - } - // write "Duration" - err = en.Append(0xa8, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e) - if err != nil { - return - } - err = en.WriteUint64(z.Duration) - if err != nil { - err = msgp.WrapError(err, "Duration") - return - } - // write "OkSummary" - err = en.Append(0xa9, 0x4f, 0x6b, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79) - if err != nil { - return - } - err = en.WriteBytes(z.OkSummary) - if err != nil { - err = msgp.WrapError(err, "OkSummary") - return - } - // write "ErrorSummary" - err = en.Append(0xac, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79) - if err != nil { - return - } - err = en.WriteBytes(z.ErrorSummary) - if err != nil { - err = msgp.WrapError(err, "ErrorSummary") - return - } - // write "Synthetics" - err = en.Append(0xaa, 0x53, 0x79, 0x6e, 0x74, 0x68, 0x65, 0x74, 0x69, 0x63, 0x73) - if err != nil { - return - } - err = en.WriteBool(z.Synthetics) - if err != nil { - err = msgp.WrapError(err, "Synthetics") - return - } - // write "TopLevelHits" - err = en.Append(0xac, 0x54, 0x6f, 0x70, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x48, 0x69, 0x74, 0x73) - if err != nil { - return - } - err = en.WriteUint64(z.TopLevelHits) - if err != nil { - err = msgp.WrapError(err, "TopLevelHits") - return - } - // write "SpanKind" - err = en.Append(0xa8, 0x53, 0x70, 0x61, 0x6e, 0x4b, 0x69, 0x6e, 0x64) - if err != nil { - return - } - err = en.WriteString(z.SpanKind) - if err != nil { - err = msgp.WrapError(err, "SpanKind") - return - } - // write "PeerTags" - err = en.Append(0xa8, 0x50, 0x65, 0x65, 0x72, 0x54, 0x61, 0x67, 0x73) - if err != nil { - return - } - err = en.WriteArrayHeader(uint32(len(z.PeerTags))) - if err != nil { - err = msgp.WrapError(err, "PeerTags") - return - } - for za0001 := range z.PeerTags { - err = en.WriteString(z.PeerTags[za0001]) - if err != nil { - err = msgp.WrapError(err, "PeerTags", za0001) - return - } - } - // write "IsTraceRoot" - err = en.Append(0xab, 0x49, 0x73, 0x54, 0x72, 0x61, 0x63, 0x65, 0x52, 0x6f, 0x6f, 0x74) - if err != nil { - return - } - err = en.WriteInt32(int32(z.IsTraceRoot)) - if err != nil { - err = msgp.WrapError(err, "IsTraceRoot") - return - } - return -} - -// MarshalMsg implements msgp.Marshaler -func (z *ClientGroupedStats) MarshalMsg(b []byte) (o []byte, err error) { - o = msgp.Require(b, z.Msgsize()) - // map header, size 16 - // string "Service" - o = append(o, 0xde, 0x0, 0x10, 0xa7, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65) - o = msgp.AppendString(o, z.Service) - // string "Name" - o = append(o, 0xa4, 0x4e, 0x61, 0x6d, 0x65) - o = msgp.AppendString(o, z.Name) - // string "Resource" - o = append(o, 0xa8, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65) - o = msgp.AppendString(o, z.Resource) - // string "HTTPStatusCode" - o = append(o, 0xae, 0x48, 0x54, 0x54, 0x50, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x6f, 0x64, 0x65) - o = msgp.AppendUint32(o, z.HTTPStatusCode) - // string "Type" - o = append(o, 0xa4, 0x54, 0x79, 0x70, 0x65) - o = msgp.AppendString(o, z.Type) - // string "DBType" - o = append(o, 0xa6, 0x44, 0x42, 0x54, 0x79, 0x70, 0x65) - o = msgp.AppendString(o, z.DBType) - // string "Hits" - o = append(o, 0xa4, 0x48, 0x69, 0x74, 0x73) - o = msgp.AppendUint64(o, z.Hits) - // string "Errors" - o = append(o, 0xa6, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73) - o = msgp.AppendUint64(o, z.Errors) - // string "Duration" - o = append(o, 0xa8, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e) - o = msgp.AppendUint64(o, z.Duration) - // string "OkSummary" - o = append(o, 0xa9, 0x4f, 0x6b, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79) - o = msgp.AppendBytes(o, z.OkSummary) - // string "ErrorSummary" - o = append(o, 0xac, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79) - o = msgp.AppendBytes(o, z.ErrorSummary) - // string "Synthetics" - o = append(o, 0xaa, 0x53, 0x79, 0x6e, 0x74, 0x68, 0x65, 0x74, 0x69, 0x63, 0x73) - o = msgp.AppendBool(o, z.Synthetics) - // string "TopLevelHits" - o = append(o, 0xac, 0x54, 0x6f, 0x70, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x48, 0x69, 0x74, 0x73) - o = msgp.AppendUint64(o, z.TopLevelHits) - // string "SpanKind" - o = append(o, 0xa8, 0x53, 0x70, 0x61, 0x6e, 0x4b, 0x69, 0x6e, 0x64) - o = msgp.AppendString(o, z.SpanKind) - // string "PeerTags" - o = append(o, 0xa8, 0x50, 0x65, 0x65, 0x72, 0x54, 0x61, 0x67, 0x73) - o = msgp.AppendArrayHeader(o, uint32(len(z.PeerTags))) - for za0001 := range z.PeerTags { - o = msgp.AppendString(o, z.PeerTags[za0001]) - } - // string "IsTraceRoot" - o = append(o, 0xab, 0x49, 0x73, 0x54, 0x72, 0x61, 0x63, 0x65, 0x52, 0x6f, 0x6f, 0x74) - o = msgp.AppendInt32(o, int32(z.IsTraceRoot)) - return -} - -// UnmarshalMsg implements msgp.Unmarshaler -func (z *ClientGroupedStats) UnmarshalMsg(bts []byte) (o []byte, err error) { - var field []byte - _ = field - var zb0001 uint32 - zb0001, bts, err = msgp.ReadMapHeaderBytes(bts) - if err != nil { - err = msgp.WrapError(err) - return - } - for zb0001 > 0 { - zb0001-- - field, bts, err = msgp.ReadMapKeyZC(bts) - if err != nil { - err = msgp.WrapError(err) - return - } - switch msgp.UnsafeString(field) { - case "Service": - z.Service, bts, err = msgp.ReadStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "Service") - return - } - case "Name": - z.Name, bts, err = msgp.ReadStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "Name") - return - } - case "Resource": - z.Resource, bts, err = msgp.ReadStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "Resource") - return - } - case "HTTPStatusCode": - z.HTTPStatusCode, bts, err = msgp.ReadUint32Bytes(bts) - if err != nil { - err = msgp.WrapError(err, "HTTPStatusCode") - return - } - case "Type": - z.Type, bts, err = msgp.ReadStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "Type") - return - } - case "DBType": - z.DBType, bts, err = msgp.ReadStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "DBType") - return - } - case "Hits": - z.Hits, bts, err = msgp.ReadUint64Bytes(bts) - if err != nil { - err = msgp.WrapError(err, "Hits") - return - } - case "Errors": - z.Errors, bts, err = msgp.ReadUint64Bytes(bts) - if err != nil { - err = msgp.WrapError(err, "Errors") - return - } - case "Duration": - z.Duration, bts, err = msgp.ReadUint64Bytes(bts) - if err != nil { - err = msgp.WrapError(err, "Duration") - return - } - case "OkSummary": - z.OkSummary, bts, err = msgp.ReadBytesBytes(bts, z.OkSummary) - if err != nil { - err = msgp.WrapError(err, "OkSummary") - return - } - case "ErrorSummary": - z.ErrorSummary, bts, err = msgp.ReadBytesBytes(bts, z.ErrorSummary) - if err != nil { - err = msgp.WrapError(err, "ErrorSummary") - return - } - case "Synthetics": - z.Synthetics, bts, err = msgp.ReadBoolBytes(bts) - if err != nil { - err = msgp.WrapError(err, "Synthetics") - return - } - case "TopLevelHits": - z.TopLevelHits, bts, err = msgp.ReadUint64Bytes(bts) - if err != nil { - err = msgp.WrapError(err, "TopLevelHits") - return - } - case "SpanKind": - z.SpanKind, bts, err = msgp.ReadStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "SpanKind") - return - } - case "PeerTags": - var zb0002 uint32 - zb0002, bts, err = msgp.ReadArrayHeaderBytes(bts) - if err != nil { - err = msgp.WrapError(err, "PeerTags") - return - } - if cap(z.PeerTags) >= int(zb0002) { - z.PeerTags = (z.PeerTags)[:zb0002] - } else { - z.PeerTags = make([]string, zb0002) - } - for za0001 := range z.PeerTags { - z.PeerTags[za0001], bts, err = msgp.ReadStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "PeerTags", za0001) - return - } - } - case "IsTraceRoot": - { - var zb0003 int32 - zb0003, bts, err = msgp.ReadInt32Bytes(bts) - if err != nil { - err = msgp.WrapError(err, "IsTraceRoot") - return - } - z.IsTraceRoot = Trilean(zb0003) - } - default: - bts, err = msgp.Skip(bts) - if err != nil { - err = msgp.WrapError(err) - return - } - } - } - o = bts - return -} - -// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message -func (z *ClientGroupedStats) Msgsize() (s int) { - s = 3 + 8 + msgp.StringPrefixSize + len(z.Service) + 5 + msgp.StringPrefixSize + len(z.Name) + 9 + msgp.StringPrefixSize + len(z.Resource) + 15 + msgp.Uint32Size + 5 + msgp.StringPrefixSize + len(z.Type) + 7 + msgp.StringPrefixSize + len(z.DBType) + 5 + msgp.Uint64Size + 7 + msgp.Uint64Size + 9 + msgp.Uint64Size + 10 + msgp.BytesPrefixSize + len(z.OkSummary) + 13 + msgp.BytesPrefixSize + len(z.ErrorSummary) + 11 + msgp.BoolSize + 13 + msgp.Uint64Size + 9 + msgp.StringPrefixSize + len(z.SpanKind) + 9 + msgp.ArrayHeaderSize - for za0001 := range z.PeerTags { - s += msgp.StringPrefixSize + len(z.PeerTags[za0001]) - } - s += 12 + msgp.Int32Size - return -} - -// DecodeMsg implements msgp.Decodable -func (z *ClientStatsBucket) DecodeMsg(dc *msgp.Reader) (err error) { - var field []byte - _ = field - var zb0001 uint32 - zb0001, err = dc.ReadMapHeader() - if err != nil { - err = msgp.WrapError(err) - return - } - for zb0001 > 0 { - zb0001-- - field, err = dc.ReadMapKeyPtr() - if err != nil { - err = msgp.WrapError(err) - return - } - switch msgp.UnsafeString(field) { - case "Start": - z.Start, err = dc.ReadUint64() - if err != nil { - err = msgp.WrapError(err, "Start") - return - } - case "Duration": - z.Duration, err = dc.ReadUint64() - if err != nil { - err = msgp.WrapError(err, "Duration") - return - } - case "Stats": - var zb0002 uint32 - zb0002, err = dc.ReadArrayHeader() - if err != nil { - err = msgp.WrapError(err, "Stats") - return - } - if cap(z.Stats) >= int(zb0002) { - z.Stats = (z.Stats)[:zb0002] - } else { - z.Stats = make([]*ClientGroupedStats, zb0002) - } - for za0001 := range z.Stats { - if dc.IsNil() { - err = dc.ReadNil() - if err != nil { - err = msgp.WrapError(err, "Stats", za0001) - return - } - z.Stats[za0001] = nil - } else { - if z.Stats[za0001] == nil { - z.Stats[za0001] = new(ClientGroupedStats) - } - err = z.Stats[za0001].DecodeMsg(dc) - if err != nil { - err = msgp.WrapError(err, "Stats", za0001) - return - } - } - } - case "AgentTimeShift": - z.AgentTimeShift, err = dc.ReadInt64() - if err != nil { - err = msgp.WrapError(err, "AgentTimeShift") - return - } - default: - err = dc.Skip() - if err != nil { - err = msgp.WrapError(err) - return - } - } - } - return -} - -// EncodeMsg implements msgp.Encodable -func (z *ClientStatsBucket) EncodeMsg(en *msgp.Writer) (err error) { - // omitempty: check for empty values - zb0001Len := uint32(4) - var zb0001Mask uint8 /* 4 bits */ - if z.Stats == nil { - zb0001Len-- - zb0001Mask |= 0x4 - } - // variable map header, size zb0001Len - err = en.Append(0x80 | uint8(zb0001Len)) - if err != nil { - return - } - if zb0001Len == 0 { - return - } - // write "Start" - err = en.Append(0xa5, 0x53, 0x74, 0x61, 0x72, 0x74) - if err != nil { - return - } - err = en.WriteUint64(z.Start) - if err != nil { - err = msgp.WrapError(err, "Start") - return - } - // write "Duration" - err = en.Append(0xa8, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e) - if err != nil { - return - } - err = en.WriteUint64(z.Duration) - if err != nil { - err = msgp.WrapError(err, "Duration") - return - } - if (zb0001Mask & 0x4) == 0 { // if not empty - // write "Stats" - err = en.Append(0xa5, 0x53, 0x74, 0x61, 0x74, 0x73) - if err != nil { - return - } - err = en.WriteArrayHeader(uint32(len(z.Stats))) - if err != nil { - err = msgp.WrapError(err, "Stats") - return - } - for za0001 := range z.Stats { - if z.Stats[za0001] == nil { - err = en.WriteNil() - if err != nil { - return - } - } else { - err = z.Stats[za0001].EncodeMsg(en) - if err != nil { - err = msgp.WrapError(err, "Stats", za0001) - return - } - } - } - } - // write "AgentTimeShift" - err = en.Append(0xae, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x68, 0x69, 0x66, 0x74) - if err != nil { - return - } - err = en.WriteInt64(z.AgentTimeShift) - if err != nil { - err = msgp.WrapError(err, "AgentTimeShift") - return - } - return -} - -// MarshalMsg implements msgp.Marshaler -func (z *ClientStatsBucket) MarshalMsg(b []byte) (o []byte, err error) { - o = msgp.Require(b, z.Msgsize()) - // omitempty: check for empty values - zb0001Len := uint32(4) - var zb0001Mask uint8 /* 4 bits */ - if z.Stats == nil { - zb0001Len-- - zb0001Mask |= 0x4 - } - // variable map header, size zb0001Len - o = append(o, 0x80|uint8(zb0001Len)) - if zb0001Len == 0 { - return - } - // string "Start" - o = append(o, 0xa5, 0x53, 0x74, 0x61, 0x72, 0x74) - o = msgp.AppendUint64(o, z.Start) - // string "Duration" - o = append(o, 0xa8, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e) - o = msgp.AppendUint64(o, z.Duration) - if (zb0001Mask & 0x4) == 0 { // if not empty - // string "Stats" - o = append(o, 0xa5, 0x53, 0x74, 0x61, 0x74, 0x73) - o = msgp.AppendArrayHeader(o, uint32(len(z.Stats))) - for za0001 := range z.Stats { - if z.Stats[za0001] == nil { - o = msgp.AppendNil(o) - } else { - o, err = z.Stats[za0001].MarshalMsg(o) - if err != nil { - err = msgp.WrapError(err, "Stats", za0001) - return - } - } - } - } - // string "AgentTimeShift" - o = append(o, 0xae, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x68, 0x69, 0x66, 0x74) - o = msgp.AppendInt64(o, z.AgentTimeShift) - return -} - -// UnmarshalMsg implements msgp.Unmarshaler -func (z *ClientStatsBucket) UnmarshalMsg(bts []byte) (o []byte, err error) { - var field []byte - _ = field - var zb0001 uint32 - zb0001, bts, err = msgp.ReadMapHeaderBytes(bts) - if err != nil { - err = msgp.WrapError(err) - return - } - for zb0001 > 0 { - zb0001-- - field, bts, err = msgp.ReadMapKeyZC(bts) - if err != nil { - err = msgp.WrapError(err) - return - } - switch msgp.UnsafeString(field) { - case "Start": - z.Start, bts, err = msgp.ReadUint64Bytes(bts) - if err != nil { - err = msgp.WrapError(err, "Start") - return - } - case "Duration": - z.Duration, bts, err = msgp.ReadUint64Bytes(bts) - if err != nil { - err = msgp.WrapError(err, "Duration") - return - } - case "Stats": - var zb0002 uint32 - zb0002, bts, err = msgp.ReadArrayHeaderBytes(bts) - if err != nil { - err = msgp.WrapError(err, "Stats") - return - } - if cap(z.Stats) >= int(zb0002) { - z.Stats = (z.Stats)[:zb0002] - } else { - z.Stats = make([]*ClientGroupedStats, zb0002) - } - for za0001 := range z.Stats { - if msgp.IsNil(bts) { - bts, err = msgp.ReadNilBytes(bts) - if err != nil { - return - } - z.Stats[za0001] = nil - } else { - if z.Stats[za0001] == nil { - z.Stats[za0001] = new(ClientGroupedStats) - } - bts, err = z.Stats[za0001].UnmarshalMsg(bts) - if err != nil { - err = msgp.WrapError(err, "Stats", za0001) - return - } - } - } - case "AgentTimeShift": - z.AgentTimeShift, bts, err = msgp.ReadInt64Bytes(bts) - if err != nil { - err = msgp.WrapError(err, "AgentTimeShift") - return - } - default: - bts, err = msgp.Skip(bts) - if err != nil { - err = msgp.WrapError(err) - return - } - } - } - o = bts - return -} - -// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message -func (z *ClientStatsBucket) Msgsize() (s int) { - s = 1 + 6 + msgp.Uint64Size + 9 + msgp.Uint64Size + 6 + msgp.ArrayHeaderSize - for za0001 := range z.Stats { - if z.Stats[za0001] == nil { - s += msgp.NilSize - } else { - s += z.Stats[za0001].Msgsize() - } - } - s += 15 + msgp.Int64Size - return -} - -// DecodeMsg implements msgp.Decodable -func (z *ClientStatsPayload) DecodeMsg(dc *msgp.Reader) (err error) { - var field []byte - _ = field - var zb0001 uint32 - zb0001, err = dc.ReadMapHeader() - if err != nil { - err = msgp.WrapError(err) - return - } - for zb0001 > 0 { - zb0001-- - field, err = dc.ReadMapKeyPtr() - if err != nil { - err = msgp.WrapError(err) - return - } - switch msgp.UnsafeString(field) { - case "Hostname": - z.Hostname, err = dc.ReadString() - if err != nil { - err = msgp.WrapError(err, "Hostname") - return - } - case "Env": - z.Env, err = dc.ReadString() - if err != nil { - err = msgp.WrapError(err, "Env") - return - } - case "Version": - z.Version, err = dc.ReadString() - if err != nil { - err = msgp.WrapError(err, "Version") - return - } - case "Stats": - var zb0002 uint32 - zb0002, err = dc.ReadArrayHeader() - if err != nil { - err = msgp.WrapError(err, "Stats") - return - } - if cap(z.Stats) >= int(zb0002) { - z.Stats = (z.Stats)[:zb0002] - } else { - z.Stats = make([]*ClientStatsBucket, zb0002) - } - for za0001 := range z.Stats { - if dc.IsNil() { - err = dc.ReadNil() - if err != nil { - err = msgp.WrapError(err, "Stats", za0001) - return - } - z.Stats[za0001] = nil - } else { - if z.Stats[za0001] == nil { - z.Stats[za0001] = new(ClientStatsBucket) - } - err = z.Stats[za0001].DecodeMsg(dc) - if err != nil { - err = msgp.WrapError(err, "Stats", za0001) - return - } - } - } - case "Lang": - z.Lang, err = dc.ReadString() - if err != nil { - err = msgp.WrapError(err, "Lang") - return - } - case "TracerVersion": - z.TracerVersion, err = dc.ReadString() - if err != nil { - err = msgp.WrapError(err, "TracerVersion") - return - } - case "RuntimeID": - z.RuntimeID, err = dc.ReadString() - if err != nil { - err = msgp.WrapError(err, "RuntimeID") - return - } - case "Sequence": - z.Sequence, err = dc.ReadUint64() - if err != nil { - err = msgp.WrapError(err, "Sequence") - return - } - case "AgentAggregation": - z.AgentAggregation, err = dc.ReadString() - if err != nil { - err = msgp.WrapError(err, "AgentAggregation") - return - } - case "Service": - z.Service, err = dc.ReadString() - if err != nil { - err = msgp.WrapError(err, "Service") - return - } - case "ContainerID": - z.ContainerID, err = dc.ReadString() - if err != nil { - err = msgp.WrapError(err, "ContainerID") - return - } - case "Tags": - var zb0003 uint32 - zb0003, err = dc.ReadArrayHeader() - if err != nil { - err = msgp.WrapError(err, "Tags") - return - } - if cap(z.Tags) >= int(zb0003) { - z.Tags = (z.Tags)[:zb0003] - } else { - z.Tags = make([]string, zb0003) - } - for za0002 := range z.Tags { - z.Tags[za0002], err = dc.ReadString() - if err != nil { - err = msgp.WrapError(err, "Tags", za0002) - return - } - } - case "GitCommitSha": - z.GitCommitSha, err = dc.ReadString() - if err != nil { - err = msgp.WrapError(err, "GitCommitSha") - return - } - case "ImageTag": - z.ImageTag, err = dc.ReadString() - if err != nil { - err = msgp.WrapError(err, "ImageTag") - return - } - default: - err = dc.Skip() - if err != nil { - err = msgp.WrapError(err) - return - } - } - } - return -} - -// EncodeMsg implements msgp.Encodable -func (z *ClientStatsPayload) EncodeMsg(en *msgp.Writer) (err error) { - // omitempty: check for empty values - zb0001Len := uint32(14) - var zb0001Mask uint16 /* 14 bits */ - if z.Stats == nil { - zb0001Len-- - zb0001Mask |= 0x8 - } - // variable map header, size zb0001Len - err = en.Append(0x80 | uint8(zb0001Len)) - if err != nil { - return - } - if zb0001Len == 0 { - return - } - // write "Hostname" - err = en.Append(0xa8, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65) - if err != nil { - return - } - err = en.WriteString(z.Hostname) - if err != nil { - err = msgp.WrapError(err, "Hostname") - return - } - // write "Env" - err = en.Append(0xa3, 0x45, 0x6e, 0x76) - if err != nil { - return - } - err = en.WriteString(z.Env) - if err != nil { - err = msgp.WrapError(err, "Env") - return - } - // write "Version" - err = en.Append(0xa7, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e) - if err != nil { - return - } - err = en.WriteString(z.Version) - if err != nil { - err = msgp.WrapError(err, "Version") - return - } - if (zb0001Mask & 0x8) == 0 { // if not empty - // write "Stats" - err = en.Append(0xa5, 0x53, 0x74, 0x61, 0x74, 0x73) - if err != nil { - return - } - err = en.WriteArrayHeader(uint32(len(z.Stats))) - if err != nil { - err = msgp.WrapError(err, "Stats") - return - } - for za0001 := range z.Stats { - if z.Stats[za0001] == nil { - err = en.WriteNil() - if err != nil { - return - } - } else { - err = z.Stats[za0001].EncodeMsg(en) - if err != nil { - err = msgp.WrapError(err, "Stats", za0001) - return - } - } - } - } - // write "Lang" - err = en.Append(0xa4, 0x4c, 0x61, 0x6e, 0x67) - if err != nil { - return - } - err = en.WriteString(z.Lang) - if err != nil { - err = msgp.WrapError(err, "Lang") - return - } - // write "TracerVersion" - err = en.Append(0xad, 0x54, 0x72, 0x61, 0x63, 0x65, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e) - if err != nil { - return - } - err = en.WriteString(z.TracerVersion) - if err != nil { - err = msgp.WrapError(err, "TracerVersion") - return - } - // write "RuntimeID" - err = en.Append(0xa9, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x49, 0x44) - if err != nil { - return - } - err = en.WriteString(z.RuntimeID) - if err != nil { - err = msgp.WrapError(err, "RuntimeID") - return - } - // write "Sequence" - err = en.Append(0xa8, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65) - if err != nil { - return - } - err = en.WriteUint64(z.Sequence) - if err != nil { - err = msgp.WrapError(err, "Sequence") - return - } - // write "AgentAggregation" - err = en.Append(0xb0, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e) - if err != nil { - return - } - err = en.WriteString(z.AgentAggregation) - if err != nil { - err = msgp.WrapError(err, "AgentAggregation") - return - } - // write "Service" - err = en.Append(0xa7, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65) - if err != nil { - return - } - err = en.WriteString(z.Service) - if err != nil { - err = msgp.WrapError(err, "Service") - return - } - // write "ContainerID" - err = en.Append(0xab, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x44) - if err != nil { - return - } - err = en.WriteString(z.ContainerID) - if err != nil { - err = msgp.WrapError(err, "ContainerID") - return - } - // write "Tags" - err = en.Append(0xa4, 0x54, 0x61, 0x67, 0x73) - if err != nil { - return - } - err = en.WriteArrayHeader(uint32(len(z.Tags))) - if err != nil { - err = msgp.WrapError(err, "Tags") - return - } - for za0002 := range z.Tags { - err = en.WriteString(z.Tags[za0002]) - if err != nil { - err = msgp.WrapError(err, "Tags", za0002) - return - } - } - // write "GitCommitSha" - err = en.Append(0xac, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x68, 0x61) - if err != nil { - return - } - err = en.WriteString(z.GitCommitSha) - if err != nil { - err = msgp.WrapError(err, "GitCommitSha") - return - } - // write "ImageTag" - err = en.Append(0xa8, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x54, 0x61, 0x67) - if err != nil { - return - } - err = en.WriteString(z.ImageTag) - if err != nil { - err = msgp.WrapError(err, "ImageTag") - return - } - return -} - -// MarshalMsg implements msgp.Marshaler -func (z *ClientStatsPayload) MarshalMsg(b []byte) (o []byte, err error) { - o = msgp.Require(b, z.Msgsize()) - // omitempty: check for empty values - zb0001Len := uint32(14) - var zb0001Mask uint16 /* 14 bits */ - if z.Stats == nil { - zb0001Len-- - zb0001Mask |= 0x8 - } - // variable map header, size zb0001Len - o = append(o, 0x80|uint8(zb0001Len)) - if zb0001Len == 0 { - return - } - // string "Hostname" - o = append(o, 0xa8, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65) - o = msgp.AppendString(o, z.Hostname) - // string "Env" - o = append(o, 0xa3, 0x45, 0x6e, 0x76) - o = msgp.AppendString(o, z.Env) - // string "Version" - o = append(o, 0xa7, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e) - o = msgp.AppendString(o, z.Version) - if (zb0001Mask & 0x8) == 0 { // if not empty - // string "Stats" - o = append(o, 0xa5, 0x53, 0x74, 0x61, 0x74, 0x73) - o = msgp.AppendArrayHeader(o, uint32(len(z.Stats))) - for za0001 := range z.Stats { - if z.Stats[za0001] == nil { - o = msgp.AppendNil(o) - } else { - o, err = z.Stats[za0001].MarshalMsg(o) - if err != nil { - err = msgp.WrapError(err, "Stats", za0001) - return - } - } - } - } - // string "Lang" - o = append(o, 0xa4, 0x4c, 0x61, 0x6e, 0x67) - o = msgp.AppendString(o, z.Lang) - // string "TracerVersion" - o = append(o, 0xad, 0x54, 0x72, 0x61, 0x63, 0x65, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e) - o = msgp.AppendString(o, z.TracerVersion) - // string "RuntimeID" - o = append(o, 0xa9, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x49, 0x44) - o = msgp.AppendString(o, z.RuntimeID) - // string "Sequence" - o = append(o, 0xa8, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65) - o = msgp.AppendUint64(o, z.Sequence) - // string "AgentAggregation" - o = append(o, 0xb0, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e) - o = msgp.AppendString(o, z.AgentAggregation) - // string "Service" - o = append(o, 0xa7, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65) - o = msgp.AppendString(o, z.Service) - // string "ContainerID" - o = append(o, 0xab, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x44) - o = msgp.AppendString(o, z.ContainerID) - // string "Tags" - o = append(o, 0xa4, 0x54, 0x61, 0x67, 0x73) - o = msgp.AppendArrayHeader(o, uint32(len(z.Tags))) - for za0002 := range z.Tags { - o = msgp.AppendString(o, z.Tags[za0002]) - } - // string "GitCommitSha" - o = append(o, 0xac, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x68, 0x61) - o = msgp.AppendString(o, z.GitCommitSha) - // string "ImageTag" - o = append(o, 0xa8, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x54, 0x61, 0x67) - o = msgp.AppendString(o, z.ImageTag) - return -} - -// UnmarshalMsg implements msgp.Unmarshaler -func (z *ClientStatsPayload) UnmarshalMsg(bts []byte) (o []byte, err error) { - var field []byte - _ = field - var zb0001 uint32 - zb0001, bts, err = msgp.ReadMapHeaderBytes(bts) - if err != nil { - err = msgp.WrapError(err) - return - } - for zb0001 > 0 { - zb0001-- - field, bts, err = msgp.ReadMapKeyZC(bts) - if err != nil { - err = msgp.WrapError(err) - return - } - switch msgp.UnsafeString(field) { - case "Hostname": - z.Hostname, bts, err = msgp.ReadStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "Hostname") - return - } - case "Env": - z.Env, bts, err = msgp.ReadStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "Env") - return - } - case "Version": - z.Version, bts, err = msgp.ReadStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "Version") - return - } - case "Stats": - var zb0002 uint32 - zb0002, bts, err = msgp.ReadArrayHeaderBytes(bts) - if err != nil { - err = msgp.WrapError(err, "Stats") - return - } - if cap(z.Stats) >= int(zb0002) { - z.Stats = (z.Stats)[:zb0002] - } else { - z.Stats = make([]*ClientStatsBucket, zb0002) - } - for za0001 := range z.Stats { - if msgp.IsNil(bts) { - bts, err = msgp.ReadNilBytes(bts) - if err != nil { - return - } - z.Stats[za0001] = nil - } else { - if z.Stats[za0001] == nil { - z.Stats[za0001] = new(ClientStatsBucket) - } - bts, err = z.Stats[za0001].UnmarshalMsg(bts) - if err != nil { - err = msgp.WrapError(err, "Stats", za0001) - return - } - } - } - case "Lang": - z.Lang, bts, err = msgp.ReadStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "Lang") - return - } - case "TracerVersion": - z.TracerVersion, bts, err = msgp.ReadStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "TracerVersion") - return - } - case "RuntimeID": - z.RuntimeID, bts, err = msgp.ReadStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "RuntimeID") - return - } - case "Sequence": - z.Sequence, bts, err = msgp.ReadUint64Bytes(bts) - if err != nil { - err = msgp.WrapError(err, "Sequence") - return - } - case "AgentAggregation": - z.AgentAggregation, bts, err = msgp.ReadStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "AgentAggregation") - return - } - case "Service": - z.Service, bts, err = msgp.ReadStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "Service") - return - } - case "ContainerID": - z.ContainerID, bts, err = msgp.ReadStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "ContainerID") - return - } - case "Tags": - var zb0003 uint32 - zb0003, bts, err = msgp.ReadArrayHeaderBytes(bts) - if err != nil { - err = msgp.WrapError(err, "Tags") - return - } - if cap(z.Tags) >= int(zb0003) { - z.Tags = (z.Tags)[:zb0003] - } else { - z.Tags = make([]string, zb0003) - } - for za0002 := range z.Tags { - z.Tags[za0002], bts, err = msgp.ReadStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "Tags", za0002) - return - } - } - case "GitCommitSha": - z.GitCommitSha, bts, err = msgp.ReadStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "GitCommitSha") - return - } - case "ImageTag": - z.ImageTag, bts, err = msgp.ReadStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "ImageTag") - return - } - default: - bts, err = msgp.Skip(bts) - if err != nil { - err = msgp.WrapError(err) - return - } - } - } - o = bts - return -} - -// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message -func (z *ClientStatsPayload) Msgsize() (s int) { - s = 1 + 9 + msgp.StringPrefixSize + len(z.Hostname) + 4 + msgp.StringPrefixSize + len(z.Env) + 8 + msgp.StringPrefixSize + len(z.Version) + 6 + msgp.ArrayHeaderSize - for za0001 := range z.Stats { - if z.Stats[za0001] == nil { - s += msgp.NilSize - } else { - s += z.Stats[za0001].Msgsize() - } - } - s += 5 + msgp.StringPrefixSize + len(z.Lang) + 14 + msgp.StringPrefixSize + len(z.TracerVersion) + 10 + msgp.StringPrefixSize + len(z.RuntimeID) + 9 + msgp.Uint64Size + 17 + msgp.StringPrefixSize + len(z.AgentAggregation) + 8 + msgp.StringPrefixSize + len(z.Service) + 12 + msgp.StringPrefixSize + len(z.ContainerID) + 5 + msgp.ArrayHeaderSize - for za0002 := range z.Tags { - s += msgp.StringPrefixSize + len(z.Tags[za0002]) - } - s += 13 + msgp.StringPrefixSize + len(z.GitCommitSha) + 9 + msgp.StringPrefixSize + len(z.ImageTag) - return -} - -// DecodeMsg implements msgp.Decodable -func (z *StatsPayload) DecodeMsg(dc *msgp.Reader) (err error) { - var field []byte - _ = field - var zb0001 uint32 - zb0001, err = dc.ReadMapHeader() - if err != nil { - err = msgp.WrapError(err) - return - } - for zb0001 > 0 { - zb0001-- - field, err = dc.ReadMapKeyPtr() - if err != nil { - err = msgp.WrapError(err) - return - } - switch msgp.UnsafeString(field) { - case "AgentHostname": - z.AgentHostname, err = dc.ReadString() - if err != nil { - err = msgp.WrapError(err, "AgentHostname") - return - } - case "AgentEnv": - z.AgentEnv, err = dc.ReadString() - if err != nil { - err = msgp.WrapError(err, "AgentEnv") - return - } - case "Stats": - var zb0002 uint32 - zb0002, err = dc.ReadArrayHeader() - if err != nil { - err = msgp.WrapError(err, "Stats") - return - } - if cap(z.Stats) >= int(zb0002) { - z.Stats = (z.Stats)[:zb0002] - } else { - z.Stats = make([]*ClientStatsPayload, zb0002) - } - for za0001 := range z.Stats { - if dc.IsNil() { - err = dc.ReadNil() - if err != nil { - err = msgp.WrapError(err, "Stats", za0001) - return - } - z.Stats[za0001] = nil - } else { - if z.Stats[za0001] == nil { - z.Stats[za0001] = new(ClientStatsPayload) - } - err = z.Stats[za0001].DecodeMsg(dc) - if err != nil { - err = msgp.WrapError(err, "Stats", za0001) - return - } - } - } - case "AgentVersion": - z.AgentVersion, err = dc.ReadString() - if err != nil { - err = msgp.WrapError(err, "AgentVersion") - return - } - case "ClientComputed": - z.ClientComputed, err = dc.ReadBool() - if err != nil { - err = msgp.WrapError(err, "ClientComputed") - return - } - case "SplitPayload": - z.SplitPayload, err = dc.ReadBool() - if err != nil { - err = msgp.WrapError(err, "SplitPayload") - return - } - default: - err = dc.Skip() - if err != nil { - err = msgp.WrapError(err) - return - } - } - } - return -} - -// EncodeMsg implements msgp.Encodable -func (z *StatsPayload) EncodeMsg(en *msgp.Writer) (err error) { - // omitempty: check for empty values - zb0001Len := uint32(6) - var zb0001Mask uint8 /* 6 bits */ - if z.Stats == nil { - zb0001Len-- - zb0001Mask |= 0x4 - } - // variable map header, size zb0001Len - err = en.Append(0x80 | uint8(zb0001Len)) - if err != nil { - return - } - if zb0001Len == 0 { - return - } - // write "AgentHostname" - err = en.Append(0xad, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65) - if err != nil { - return - } - err = en.WriteString(z.AgentHostname) - if err != nil { - err = msgp.WrapError(err, "AgentHostname") - return - } - // write "AgentEnv" - err = en.Append(0xa8, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x45, 0x6e, 0x76) - if err != nil { - return - } - err = en.WriteString(z.AgentEnv) - if err != nil { - err = msgp.WrapError(err, "AgentEnv") - return - } - if (zb0001Mask & 0x4) == 0 { // if not empty - // write "Stats" - err = en.Append(0xa5, 0x53, 0x74, 0x61, 0x74, 0x73) - if err != nil { - return - } - err = en.WriteArrayHeader(uint32(len(z.Stats))) - if err != nil { - err = msgp.WrapError(err, "Stats") - return - } - for za0001 := range z.Stats { - if z.Stats[za0001] == nil { - err = en.WriteNil() - if err != nil { - return - } - } else { - err = z.Stats[za0001].EncodeMsg(en) - if err != nil { - err = msgp.WrapError(err, "Stats", za0001) - return - } - } - } - } - // write "AgentVersion" - err = en.Append(0xac, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e) - if err != nil { - return - } - err = en.WriteString(z.AgentVersion) - if err != nil { - err = msgp.WrapError(err, "AgentVersion") - return - } - // write "ClientComputed" - err = en.Append(0xae, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64) - if err != nil { - return - } - err = en.WriteBool(z.ClientComputed) - if err != nil { - err = msgp.WrapError(err, "ClientComputed") - return - } - // write "SplitPayload" - err = en.Append(0xac, 0x53, 0x70, 0x6c, 0x69, 0x74, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64) - if err != nil { - return - } - err = en.WriteBool(z.SplitPayload) - if err != nil { - err = msgp.WrapError(err, "SplitPayload") - return - } - return -} - -// MarshalMsg implements msgp.Marshaler -func (z *StatsPayload) MarshalMsg(b []byte) (o []byte, err error) { - o = msgp.Require(b, z.Msgsize()) - // omitempty: check for empty values - zb0001Len := uint32(6) - var zb0001Mask uint8 /* 6 bits */ - if z.Stats == nil { - zb0001Len-- - zb0001Mask |= 0x4 - } - // variable map header, size zb0001Len - o = append(o, 0x80|uint8(zb0001Len)) - if zb0001Len == 0 { - return - } - // string "AgentHostname" - o = append(o, 0xad, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65) - o = msgp.AppendString(o, z.AgentHostname) - // string "AgentEnv" - o = append(o, 0xa8, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x45, 0x6e, 0x76) - o = msgp.AppendString(o, z.AgentEnv) - if (zb0001Mask & 0x4) == 0 { // if not empty - // string "Stats" - o = append(o, 0xa5, 0x53, 0x74, 0x61, 0x74, 0x73) - o = msgp.AppendArrayHeader(o, uint32(len(z.Stats))) - for za0001 := range z.Stats { - if z.Stats[za0001] == nil { - o = msgp.AppendNil(o) - } else { - o, err = z.Stats[za0001].MarshalMsg(o) - if err != nil { - err = msgp.WrapError(err, "Stats", za0001) - return - } - } - } - } - // string "AgentVersion" - o = append(o, 0xac, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e) - o = msgp.AppendString(o, z.AgentVersion) - // string "ClientComputed" - o = append(o, 0xae, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64) - o = msgp.AppendBool(o, z.ClientComputed) - // string "SplitPayload" - o = append(o, 0xac, 0x53, 0x70, 0x6c, 0x69, 0x74, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64) - o = msgp.AppendBool(o, z.SplitPayload) - return -} - -// UnmarshalMsg implements msgp.Unmarshaler -func (z *StatsPayload) UnmarshalMsg(bts []byte) (o []byte, err error) { - var field []byte - _ = field - var zb0001 uint32 - zb0001, bts, err = msgp.ReadMapHeaderBytes(bts) - if err != nil { - err = msgp.WrapError(err) - return - } - for zb0001 > 0 { - zb0001-- - field, bts, err = msgp.ReadMapKeyZC(bts) - if err != nil { - err = msgp.WrapError(err) - return - } - switch msgp.UnsafeString(field) { - case "AgentHostname": - z.AgentHostname, bts, err = msgp.ReadStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "AgentHostname") - return - } - case "AgentEnv": - z.AgentEnv, bts, err = msgp.ReadStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "AgentEnv") - return - } - case "Stats": - var zb0002 uint32 - zb0002, bts, err = msgp.ReadArrayHeaderBytes(bts) - if err != nil { - err = msgp.WrapError(err, "Stats") - return - } - if cap(z.Stats) >= int(zb0002) { - z.Stats = (z.Stats)[:zb0002] - } else { - z.Stats = make([]*ClientStatsPayload, zb0002) - } - for za0001 := range z.Stats { - if msgp.IsNil(bts) { - bts, err = msgp.ReadNilBytes(bts) - if err != nil { - return - } - z.Stats[za0001] = nil - } else { - if z.Stats[za0001] == nil { - z.Stats[za0001] = new(ClientStatsPayload) - } - bts, err = z.Stats[za0001].UnmarshalMsg(bts) - if err != nil { - err = msgp.WrapError(err, "Stats", za0001) - return - } - } - } - case "AgentVersion": - z.AgentVersion, bts, err = msgp.ReadStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "AgentVersion") - return - } - case "ClientComputed": - z.ClientComputed, bts, err = msgp.ReadBoolBytes(bts) - if err != nil { - err = msgp.WrapError(err, "ClientComputed") - return - } - case "SplitPayload": - z.SplitPayload, bts, err = msgp.ReadBoolBytes(bts) - if err != nil { - err = msgp.WrapError(err, "SplitPayload") - return - } - default: - bts, err = msgp.Skip(bts) - if err != nil { - err = msgp.WrapError(err) - return - } - } - } - o = bts - return -} - -// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message -func (z *StatsPayload) Msgsize() (s int) { - s = 1 + 14 + msgp.StringPrefixSize + len(z.AgentHostname) + 9 + msgp.StringPrefixSize + len(z.AgentEnv) + 6 + msgp.ArrayHeaderSize - for za0001 := range z.Stats { - if z.Stats[za0001] == nil { - s += msgp.NilSize - } else { - s += z.Stats[za0001].Msgsize() - } - } - s += 13 + msgp.StringPrefixSize + len(z.AgentVersion) + 15 + msgp.BoolSize + 13 + msgp.BoolSize - return -} - -// DecodeMsg implements msgp.Decodable -func (z *TraceRootFlag) DecodeMsg(dc *msgp.Reader) (err error) { - { - var zb0001 int32 - zb0001, err = dc.ReadInt32() - if err != nil { - err = msgp.WrapError(err) - return - } - (*z) = TraceRootFlag(zb0001) - } - return -} - -// EncodeMsg implements msgp.Encodable -func (z TraceRootFlag) EncodeMsg(en *msgp.Writer) (err error) { - err = en.WriteInt32(int32(z)) - if err != nil { - err = msgp.WrapError(err) - return - } - return -} - -// MarshalMsg implements msgp.Marshaler -func (z TraceRootFlag) MarshalMsg(b []byte) (o []byte, err error) { - o = msgp.Require(b, z.Msgsize()) - o = msgp.AppendInt32(o, int32(z)) - return -} - -// UnmarshalMsg implements msgp.Unmarshaler -func (z *TraceRootFlag) UnmarshalMsg(bts []byte) (o []byte, err error) { - { - var zb0001 int32 - zb0001, bts, err = msgp.ReadInt32Bytes(bts) - if err != nil { - err = msgp.WrapError(err) - return - } - (*z) = TraceRootFlag(zb0001) - } - o = bts - return -} - -// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message -func (z TraceRootFlag) Msgsize() (s int) { - s = msgp.Int32Size - return -} - -// DecodeMsg implements msgp.Decodable -func (z *Trilean) DecodeMsg(dc *msgp.Reader) (err error) { - { - var zb0001 int32 - zb0001, err = dc.ReadInt32() - if err != nil { - err = msgp.WrapError(err) - return - } - (*z) = Trilean(zb0001) - } - return -} - -// EncodeMsg implements msgp.Encodable -func (z Trilean) EncodeMsg(en *msgp.Writer) (err error) { - err = en.WriteInt32(int32(z)) - if err != nil { - err = msgp.WrapError(err) - return - } - return -} - -// MarshalMsg implements msgp.Marshaler -func (z Trilean) MarshalMsg(b []byte) (o []byte, err error) { - o = msgp.Require(b, z.Msgsize()) - o = msgp.AppendInt32(o, int32(z)) - return -} - -// UnmarshalMsg implements msgp.Unmarshaler -func (z *Trilean) UnmarshalMsg(bts []byte) (o []byte, err error) { - { - var zb0001 int32 - zb0001, bts, err = msgp.ReadInt32Bytes(bts) - if err != nil { - err = msgp.WrapError(err) - return - } - (*z) = Trilean(zb0001) - } - o = bts - return -} - -// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message -func (z Trilean) Msgsize() (s int) { - s = msgp.Int32Size - return -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/stats_vtproto.pb.go b/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/stats_vtproto.pb.go deleted file mode 100644 index 002bfad3..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/stats_vtproto.pb.go +++ /dev/null @@ -1,1968 +0,0 @@ -// Code generated by protoc-gen-go-vtproto. DO NOT EDIT. -// protoc-gen-go-vtproto version: v0.4.0 -// source: datadog/trace/stats.proto - -package trace - -import ( - fmt "fmt" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - io "io" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -func (m *StatsPayload) MarshalVT() (dAtA []byte, err error) { - if m == nil { - return nil, nil - } - size := m.SizeVT() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBufferVT(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *StatsPayload) MarshalToVT(dAtA []byte) (int, error) { - size := m.SizeVT() - return m.MarshalToSizedBufferVT(dAtA[:size]) -} - -func (m *StatsPayload) MarshalToSizedBufferVT(dAtA []byte) (int, error) { - if m == nil { - return 0, nil - } - i := len(dAtA) - _ = i - var l int - _ = l - if m.unknownFields != nil { - i -= len(m.unknownFields) - copy(dAtA[i:], m.unknownFields) - } - if m.SplitPayload { - i-- - if m.SplitPayload { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x30 - } - if m.ClientComputed { - i-- - if m.ClientComputed { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x28 - } - if len(m.AgentVersion) > 0 { - i -= len(m.AgentVersion) - copy(dAtA[i:], m.AgentVersion) - i = encodeVarint(dAtA, i, uint64(len(m.AgentVersion))) - i-- - dAtA[i] = 0x22 - } - if len(m.Stats) > 0 { - for iNdEx := len(m.Stats) - 1; iNdEx >= 0; iNdEx-- { - size, err := m.Stats[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarint(dAtA, i, uint64(size)) - i-- - dAtA[i] = 0x1a - } - } - if len(m.AgentEnv) > 0 { - i -= len(m.AgentEnv) - copy(dAtA[i:], m.AgentEnv) - i = encodeVarint(dAtA, i, uint64(len(m.AgentEnv))) - i-- - dAtA[i] = 0x12 - } - if len(m.AgentHostname) > 0 { - i -= len(m.AgentHostname) - copy(dAtA[i:], m.AgentHostname) - i = encodeVarint(dAtA, i, uint64(len(m.AgentHostname))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *ClientStatsPayload) MarshalVT() (dAtA []byte, err error) { - if m == nil { - return nil, nil - } - size := m.SizeVT() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBufferVT(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ClientStatsPayload) MarshalToVT(dAtA []byte) (int, error) { - size := m.SizeVT() - return m.MarshalToSizedBufferVT(dAtA[:size]) -} - -func (m *ClientStatsPayload) MarshalToSizedBufferVT(dAtA []byte) (int, error) { - if m == nil { - return 0, nil - } - i := len(dAtA) - _ = i - var l int - _ = l - if m.unknownFields != nil { - i -= len(m.unknownFields) - copy(dAtA[i:], m.unknownFields) - } - if len(m.ImageTag) > 0 { - i -= len(m.ImageTag) - copy(dAtA[i:], m.ImageTag) - i = encodeVarint(dAtA, i, uint64(len(m.ImageTag))) - i-- - dAtA[i] = 0x72 - } - if len(m.GitCommitSha) > 0 { - i -= len(m.GitCommitSha) - copy(dAtA[i:], m.GitCommitSha) - i = encodeVarint(dAtA, i, uint64(len(m.GitCommitSha))) - i-- - dAtA[i] = 0x6a - } - if len(m.Tags) > 0 { - for iNdEx := len(m.Tags) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.Tags[iNdEx]) - copy(dAtA[i:], m.Tags[iNdEx]) - i = encodeVarint(dAtA, i, uint64(len(m.Tags[iNdEx]))) - i-- - dAtA[i] = 0x62 - } - } - if len(m.ContainerID) > 0 { - i -= len(m.ContainerID) - copy(dAtA[i:], m.ContainerID) - i = encodeVarint(dAtA, i, uint64(len(m.ContainerID))) - i-- - dAtA[i] = 0x5a - } - if len(m.Service) > 0 { - i -= len(m.Service) - copy(dAtA[i:], m.Service) - i = encodeVarint(dAtA, i, uint64(len(m.Service))) - i-- - dAtA[i] = 0x52 - } - if len(m.AgentAggregation) > 0 { - i -= len(m.AgentAggregation) - copy(dAtA[i:], m.AgentAggregation) - i = encodeVarint(dAtA, i, uint64(len(m.AgentAggregation))) - i-- - dAtA[i] = 0x4a - } - if m.Sequence != 0 { - i = encodeVarint(dAtA, i, uint64(m.Sequence)) - i-- - dAtA[i] = 0x40 - } - if len(m.RuntimeID) > 0 { - i -= len(m.RuntimeID) - copy(dAtA[i:], m.RuntimeID) - i = encodeVarint(dAtA, i, uint64(len(m.RuntimeID))) - i-- - dAtA[i] = 0x3a - } - if len(m.TracerVersion) > 0 { - i -= len(m.TracerVersion) - copy(dAtA[i:], m.TracerVersion) - i = encodeVarint(dAtA, i, uint64(len(m.TracerVersion))) - i-- - dAtA[i] = 0x32 - } - if len(m.Lang) > 0 { - i -= len(m.Lang) - copy(dAtA[i:], m.Lang) - i = encodeVarint(dAtA, i, uint64(len(m.Lang))) - i-- - dAtA[i] = 0x2a - } - if len(m.Stats) > 0 { - for iNdEx := len(m.Stats) - 1; iNdEx >= 0; iNdEx-- { - size, err := m.Stats[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarint(dAtA, i, uint64(size)) - i-- - dAtA[i] = 0x22 - } - } - if len(m.Version) > 0 { - i -= len(m.Version) - copy(dAtA[i:], m.Version) - i = encodeVarint(dAtA, i, uint64(len(m.Version))) - i-- - dAtA[i] = 0x1a - } - if len(m.Env) > 0 { - i -= len(m.Env) - copy(dAtA[i:], m.Env) - i = encodeVarint(dAtA, i, uint64(len(m.Env))) - i-- - dAtA[i] = 0x12 - } - if len(m.Hostname) > 0 { - i -= len(m.Hostname) - copy(dAtA[i:], m.Hostname) - i = encodeVarint(dAtA, i, uint64(len(m.Hostname))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *ClientStatsBucket) MarshalVT() (dAtA []byte, err error) { - if m == nil { - return nil, nil - } - size := m.SizeVT() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBufferVT(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ClientStatsBucket) MarshalToVT(dAtA []byte) (int, error) { - size := m.SizeVT() - return m.MarshalToSizedBufferVT(dAtA[:size]) -} - -func (m *ClientStatsBucket) MarshalToSizedBufferVT(dAtA []byte) (int, error) { - if m == nil { - return 0, nil - } - i := len(dAtA) - _ = i - var l int - _ = l - if m.unknownFields != nil { - i -= len(m.unknownFields) - copy(dAtA[i:], m.unknownFields) - } - if m.AgentTimeShift != 0 { - i = encodeVarint(dAtA, i, uint64(m.AgentTimeShift)) - i-- - dAtA[i] = 0x20 - } - if len(m.Stats) > 0 { - for iNdEx := len(m.Stats) - 1; iNdEx >= 0; iNdEx-- { - size, err := m.Stats[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarint(dAtA, i, uint64(size)) - i-- - dAtA[i] = 0x1a - } - } - if m.Duration != 0 { - i = encodeVarint(dAtA, i, uint64(m.Duration)) - i-- - dAtA[i] = 0x10 - } - if m.Start != 0 { - i = encodeVarint(dAtA, i, uint64(m.Start)) - i-- - dAtA[i] = 0x8 - } - return len(dAtA) - i, nil -} - -func (m *ClientGroupedStats) MarshalVT() (dAtA []byte, err error) { - if m == nil { - return nil, nil - } - size := m.SizeVT() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBufferVT(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ClientGroupedStats) MarshalToVT(dAtA []byte) (int, error) { - size := m.SizeVT() - return m.MarshalToSizedBufferVT(dAtA[:size]) -} - -func (m *ClientGroupedStats) MarshalToSizedBufferVT(dAtA []byte) (int, error) { - if m == nil { - return 0, nil - } - i := len(dAtA) - _ = i - var l int - _ = l - if m.unknownFields != nil { - i -= len(m.unknownFields) - copy(dAtA[i:], m.unknownFields) - } - if m.IsTraceRoot != 0 { - i = encodeVarint(dAtA, i, uint64(m.IsTraceRoot)) - i-- - dAtA[i] = 0x1 - i-- - dAtA[i] = 0x88 - } - if len(m.PeerTags) > 0 { - for iNdEx := len(m.PeerTags) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.PeerTags[iNdEx]) - copy(dAtA[i:], m.PeerTags[iNdEx]) - i = encodeVarint(dAtA, i, uint64(len(m.PeerTags[iNdEx]))) - i-- - dAtA[i] = 0x1 - i-- - dAtA[i] = 0x82 - } - } - if len(m.SpanKind) > 0 { - i -= len(m.SpanKind) - copy(dAtA[i:], m.SpanKind) - i = encodeVarint(dAtA, i, uint64(len(m.SpanKind))) - i-- - dAtA[i] = 0x7a - } - if m.TopLevelHits != 0 { - i = encodeVarint(dAtA, i, uint64(m.TopLevelHits)) - i-- - dAtA[i] = 0x68 - } - if m.Synthetics { - i-- - if m.Synthetics { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x60 - } - if len(m.ErrorSummary) > 0 { - i -= len(m.ErrorSummary) - copy(dAtA[i:], m.ErrorSummary) - i = encodeVarint(dAtA, i, uint64(len(m.ErrorSummary))) - i-- - dAtA[i] = 0x5a - } - if len(m.OkSummary) > 0 { - i -= len(m.OkSummary) - copy(dAtA[i:], m.OkSummary) - i = encodeVarint(dAtA, i, uint64(len(m.OkSummary))) - i-- - dAtA[i] = 0x52 - } - if m.Duration != 0 { - i = encodeVarint(dAtA, i, uint64(m.Duration)) - i-- - dAtA[i] = 0x48 - } - if m.Errors != 0 { - i = encodeVarint(dAtA, i, uint64(m.Errors)) - i-- - dAtA[i] = 0x40 - } - if m.Hits != 0 { - i = encodeVarint(dAtA, i, uint64(m.Hits)) - i-- - dAtA[i] = 0x38 - } - if len(m.DBType) > 0 { - i -= len(m.DBType) - copy(dAtA[i:], m.DBType) - i = encodeVarint(dAtA, i, uint64(len(m.DBType))) - i-- - dAtA[i] = 0x32 - } - if len(m.Type) > 0 { - i -= len(m.Type) - copy(dAtA[i:], m.Type) - i = encodeVarint(dAtA, i, uint64(len(m.Type))) - i-- - dAtA[i] = 0x2a - } - if m.HTTPStatusCode != 0 { - i = encodeVarint(dAtA, i, uint64(m.HTTPStatusCode)) - i-- - dAtA[i] = 0x20 - } - if len(m.Resource) > 0 { - i -= len(m.Resource) - copy(dAtA[i:], m.Resource) - i = encodeVarint(dAtA, i, uint64(len(m.Resource))) - i-- - dAtA[i] = 0x1a - } - if len(m.Name) > 0 { - i -= len(m.Name) - copy(dAtA[i:], m.Name) - i = encodeVarint(dAtA, i, uint64(len(m.Name))) - i-- - dAtA[i] = 0x12 - } - if len(m.Service) > 0 { - i -= len(m.Service) - copy(dAtA[i:], m.Service) - i = encodeVarint(dAtA, i, uint64(len(m.Service))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *StatsPayload) SizeVT() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.AgentHostname) - if l > 0 { - n += 1 + l + sov(uint64(l)) - } - l = len(m.AgentEnv) - if l > 0 { - n += 1 + l + sov(uint64(l)) - } - if len(m.Stats) > 0 { - for _, e := range m.Stats { - l = e.SizeVT() - n += 1 + l + sov(uint64(l)) - } - } - l = len(m.AgentVersion) - if l > 0 { - n += 1 + l + sov(uint64(l)) - } - if m.ClientComputed { - n += 2 - } - if m.SplitPayload { - n += 2 - } - n += len(m.unknownFields) - return n -} - -func (m *ClientStatsPayload) SizeVT() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Hostname) - if l > 0 { - n += 1 + l + sov(uint64(l)) - } - l = len(m.Env) - if l > 0 { - n += 1 + l + sov(uint64(l)) - } - l = len(m.Version) - if l > 0 { - n += 1 + l + sov(uint64(l)) - } - if len(m.Stats) > 0 { - for _, e := range m.Stats { - l = e.SizeVT() - n += 1 + l + sov(uint64(l)) - } - } - l = len(m.Lang) - if l > 0 { - n += 1 + l + sov(uint64(l)) - } - l = len(m.TracerVersion) - if l > 0 { - n += 1 + l + sov(uint64(l)) - } - l = len(m.RuntimeID) - if l > 0 { - n += 1 + l + sov(uint64(l)) - } - if m.Sequence != 0 { - n += 1 + sov(uint64(m.Sequence)) - } - l = len(m.AgentAggregation) - if l > 0 { - n += 1 + l + sov(uint64(l)) - } - l = len(m.Service) - if l > 0 { - n += 1 + l + sov(uint64(l)) - } - l = len(m.ContainerID) - if l > 0 { - n += 1 + l + sov(uint64(l)) - } - if len(m.Tags) > 0 { - for _, s := range m.Tags { - l = len(s) - n += 1 + l + sov(uint64(l)) - } - } - l = len(m.GitCommitSha) - if l > 0 { - n += 1 + l + sov(uint64(l)) - } - l = len(m.ImageTag) - if l > 0 { - n += 1 + l + sov(uint64(l)) - } - n += len(m.unknownFields) - return n -} - -func (m *ClientStatsBucket) SizeVT() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Start != 0 { - n += 1 + sov(uint64(m.Start)) - } - if m.Duration != 0 { - n += 1 + sov(uint64(m.Duration)) - } - if len(m.Stats) > 0 { - for _, e := range m.Stats { - l = e.SizeVT() - n += 1 + l + sov(uint64(l)) - } - } - if m.AgentTimeShift != 0 { - n += 1 + sov(uint64(m.AgentTimeShift)) - } - n += len(m.unknownFields) - return n -} - -func (m *ClientGroupedStats) SizeVT() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Service) - if l > 0 { - n += 1 + l + sov(uint64(l)) - } - l = len(m.Name) - if l > 0 { - n += 1 + l + sov(uint64(l)) - } - l = len(m.Resource) - if l > 0 { - n += 1 + l + sov(uint64(l)) - } - if m.HTTPStatusCode != 0 { - n += 1 + sov(uint64(m.HTTPStatusCode)) - } - l = len(m.Type) - if l > 0 { - n += 1 + l + sov(uint64(l)) - } - l = len(m.DBType) - if l > 0 { - n += 1 + l + sov(uint64(l)) - } - if m.Hits != 0 { - n += 1 + sov(uint64(m.Hits)) - } - if m.Errors != 0 { - n += 1 + sov(uint64(m.Errors)) - } - if m.Duration != 0 { - n += 1 + sov(uint64(m.Duration)) - } - l = len(m.OkSummary) - if l > 0 { - n += 1 + l + sov(uint64(l)) - } - l = len(m.ErrorSummary) - if l > 0 { - n += 1 + l + sov(uint64(l)) - } - if m.Synthetics { - n += 2 - } - if m.TopLevelHits != 0 { - n += 1 + sov(uint64(m.TopLevelHits)) - } - l = len(m.SpanKind) - if l > 0 { - n += 1 + l + sov(uint64(l)) - } - if len(m.PeerTags) > 0 { - for _, s := range m.PeerTags { - l = len(s) - n += 2 + l + sov(uint64(l)) - } - } - if m.IsTraceRoot != 0 { - n += 2 + sov(uint64(m.IsTraceRoot)) - } - n += len(m.unknownFields) - return n -} - -func (m *StatsPayload) UnmarshalVT(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: StatsPayload: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: StatsPayload: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AgentHostname", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.AgentHostname = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AgentEnv", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.AgentEnv = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Stats", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Stats = append(m.Stats, &ClientStatsPayload{}) - if err := m.Stats[len(m.Stats)-1].UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AgentVersion", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.AgentVersion = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 5: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ClientComputed", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.ClientComputed = bool(v != 0) - case 6: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field SplitPayload", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.SplitPayload = bool(v != 0) - default: - iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ClientStatsPayload) UnmarshalVT(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ClientStatsPayload: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ClientStatsPayload: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Hostname", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Hostname = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Env", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Env = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Version = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Stats", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Stats = append(m.Stats, &ClientStatsBucket{}) - if err := m.Stats[len(m.Stats)-1].UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Lang", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Lang = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TracerVersion", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.TracerVersion = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 7: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field RuntimeID", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.RuntimeID = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 8: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Sequence", wireType) - } - m.Sequence = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Sequence |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 9: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AgentAggregation", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.AgentAggregation = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 10: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Service", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Service = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 11: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ContainerID", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ContainerID = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 12: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Tags", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Tags = append(m.Tags, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 13: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field GitCommitSha", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.GitCommitSha = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 14: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ImageTag", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ImageTag = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ClientStatsBucket) UnmarshalVT(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ClientStatsBucket: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ClientStatsBucket: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Start", wireType) - } - m.Start = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Start |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Duration", wireType) - } - m.Duration = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Duration |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Stats", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Stats = append(m.Stats, &ClientGroupedStats{}) - if err := m.Stats[len(m.Stats)-1].UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field AgentTimeShift", wireType) - } - m.AgentTimeShift = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.AgentTimeShift |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } - default: - iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ClientGroupedStats) UnmarshalVT(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ClientGroupedStats: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ClientGroupedStats: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Service", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Service = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Resource", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Resource = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field HTTPStatusCode", wireType) - } - m.HTTPStatusCode = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.HTTPStatusCode |= uint32(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Type = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DBType", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.DBType = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 7: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Hits", wireType) - } - m.Hits = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Hits |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 8: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Errors", wireType) - } - m.Errors = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Errors |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 9: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Duration", wireType) - } - m.Duration = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Duration |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 10: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field OkSummary", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.OkSummary = append(m.OkSummary[:0], dAtA[iNdEx:postIndex]...) - if m.OkSummary == nil { - m.OkSummary = []byte{} - } - iNdEx = postIndex - case 11: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ErrorSummary", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ErrorSummary = append(m.ErrorSummary[:0], dAtA[iNdEx:postIndex]...) - if m.ErrorSummary == nil { - m.ErrorSummary = []byte{} - } - iNdEx = postIndex - case 12: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Synthetics", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.Synthetics = bool(v != 0) - case 13: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field TopLevelHits", wireType) - } - m.TopLevelHits = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.TopLevelHits |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 15: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SpanKind", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.SpanKind = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 16: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PeerTags", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.PeerTags = append(m.PeerTags, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 17: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field IsTraceRoot", wireType) - } - m.IsTraceRoot = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.IsTraceRoot |= Trilean(b&0x7F) << shift - if b < 0x80 { - break - } - } - default: - iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/trace.go b/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/trace.go deleted file mode 100644 index 94fd0eda..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/trace.go +++ /dev/null @@ -1,52 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package trace - -//go:generate go run github.com/tinylib/msgp -file=span.pb.go -o span_gen.go -io=false -//go:generate go run github.com/tinylib/msgp -file=tracer_payload.pb.go -o tracer_payload_gen.go -io=false -//go:generate go run github.com/tinylib/msgp -io=false - -// Trace is a collection of spans with the same trace ID -type Trace []*Span - -// Traces is a list of traces. This model matters as this is what we unpack from msgp. -type Traces []Trace - -// RemoveChunk removes a chunk by its index. -func (p *TracerPayload) RemoveChunk(i int) { - if i < 0 || i >= len(p.Chunks) { - return - } - p.Chunks[i] = p.Chunks[len(p.Chunks)-1] - p.Chunks = p.Chunks[:len(p.Chunks)-1] -} - -// Cut cuts off a new tracer payload from the `p` with [0, i-1] chunks -// and keeps [i, n-1] chunks in the original payload `p`. -func (p *TracerPayload) Cut(i int) *TracerPayload { - if i < 0 { - i = 0 - } - if i > len(p.Chunks) { - i = len(p.Chunks) - } - newPayload := TracerPayload{ - ContainerID: p.GetContainerID(), - LanguageName: p.GetLanguageName(), - LanguageVersion: p.GetLanguageVersion(), - TracerVersion: p.GetTracerVersion(), - RuntimeID: p.GetRuntimeID(), - Env: p.GetEnv(), - Hostname: p.GetHostname(), - AppVersion: p.GetAppVersion(), - Tags: p.GetTags(), - } - - newPayload.Chunks = p.Chunks[:i] - p.Chunks = p.Chunks[i:] - - return &newPayload -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/trace_gen.go b/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/trace_gen.go deleted file mode 100644 index 2a2865f3..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/trace_gen.go +++ /dev/null @@ -1,158 +0,0 @@ -package trace - -// Code generated by github.com/tinylib/msgp DO NOT EDIT. - -import ( - "github.com/tinylib/msgp/msgp" -) - -// MarshalMsg implements msgp.Marshaler -func (z Trace) MarshalMsg(b []byte) (o []byte, err error) { - o = msgp.Require(b, z.Msgsize()) - o = msgp.AppendArrayHeader(o, uint32(len(z))) - for za0001 := range z { - if z[za0001] == nil { - o = msgp.AppendNil(o) - } else { - o, err = z[za0001].MarshalMsg(o) - if err != nil { - err = msgp.WrapError(err, za0001) - return - } - } - } - return -} - -// UnmarshalMsg implements msgp.Unmarshaler -func (z *Trace) UnmarshalMsg(bts []byte) (o []byte, err error) { - var zb0002 uint32 - zb0002, bts, err = msgp.ReadArrayHeaderBytes(bts) - if err != nil { - err = msgp.WrapError(err) - return - } - if cap((*z)) >= int(zb0002) { - (*z) = (*z)[:zb0002] - } else { - (*z) = make(Trace, zb0002) - } - for zb0001 := range *z { - if msgp.IsNil(bts) { - bts, err = msgp.ReadNilBytes(bts) - if err != nil { - return - } - (*z)[zb0001] = nil - } else { - if (*z)[zb0001] == nil { - (*z)[zb0001] = new(Span) - } - bts, err = (*z)[zb0001].UnmarshalMsg(bts) - if err != nil { - err = msgp.WrapError(err, zb0001) - return - } - } - } - o = bts - return -} - -// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message -func (z Trace) Msgsize() (s int) { - s = msgp.ArrayHeaderSize - for zb0003 := range z { - if z[zb0003] == nil { - s += msgp.NilSize - } else { - s += z[zb0003].Msgsize() - } - } - return -} - -// MarshalMsg implements msgp.Marshaler -func (z Traces) MarshalMsg(b []byte) (o []byte, err error) { - o = msgp.Require(b, z.Msgsize()) - o = msgp.AppendArrayHeader(o, uint32(len(z))) - for za0001 := range z { - o = msgp.AppendArrayHeader(o, uint32(len(z[za0001]))) - for za0002 := range z[za0001] { - if z[za0001][za0002] == nil { - o = msgp.AppendNil(o) - } else { - o, err = z[za0001][za0002].MarshalMsg(o) - if err != nil { - err = msgp.WrapError(err, za0001, za0002) - return - } - } - } - } - return -} - -// UnmarshalMsg implements msgp.Unmarshaler -func (z *Traces) UnmarshalMsg(bts []byte) (o []byte, err error) { - var zb0003 uint32 - zb0003, bts, err = msgp.ReadArrayHeaderBytes(bts) - if err != nil { - err = msgp.WrapError(err) - return - } - if cap((*z)) >= int(zb0003) { - (*z) = (*z)[:zb0003] - } else { - (*z) = make(Traces, zb0003) - } - for zb0001 := range *z { - var zb0004 uint32 - zb0004, bts, err = msgp.ReadArrayHeaderBytes(bts) - if err != nil { - err = msgp.WrapError(err, zb0001) - return - } - if cap((*z)[zb0001]) >= int(zb0004) { - (*z)[zb0001] = ((*z)[zb0001])[:zb0004] - } else { - (*z)[zb0001] = make(Trace, zb0004) - } - for zb0002 := range (*z)[zb0001] { - if msgp.IsNil(bts) { - bts, err = msgp.ReadNilBytes(bts) - if err != nil { - return - } - (*z)[zb0001][zb0002] = nil - } else { - if (*z)[zb0001][zb0002] == nil { - (*z)[zb0001][zb0002] = new(Span) - } - bts, err = (*z)[zb0001][zb0002].UnmarshalMsg(bts) - if err != nil { - err = msgp.WrapError(err, zb0001, zb0002) - return - } - } - } - } - o = bts - return -} - -// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message -func (z Traces) Msgsize() (s int) { - s = msgp.ArrayHeaderSize - for zb0005 := range z { - s += msgp.ArrayHeaderSize - for zb0006 := range z[zb0005] { - if z[zb0005][zb0006] == nil { - s += msgp.NilSize - } else { - s += z[zb0005][zb0006].Msgsize() - } - } - } - return -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/tracer_payload.pb.go b/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/tracer_payload.pb.go deleted file mode 100644 index 7e7e2b0c..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/tracer_payload.pb.go +++ /dev/null @@ -1,391 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.34.0 -// protoc v5.26.1 -// source: datadog/trace/tracer_payload.proto - -package trace - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// TraceChunk represents a list of spans with the same trace ID. In other words, a chunk of a trace. -type TraceChunk struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // priority specifies sampling priority of the trace. - // @gotags: json:"priority" msg:"priority" - Priority int32 `protobuf:"varint,1,opt,name=priority,proto3" json:"priority" msg:"priority"` - // origin specifies origin product ("lambda", "rum", etc.) of the trace. - // @gotags: json:"origin" msg:"origin" - Origin string `protobuf:"bytes,2,opt,name=origin,proto3" json:"origin" msg:"origin"` - // spans specifies list of containing spans. - // @gotags: json:"spans" msg:"spans" - Spans []*Span `protobuf:"bytes,3,rep,name=spans,proto3" json:"spans" msg:"spans"` - // tags specifies tags common in all `spans`. - // @gotags: json:"tags" msg:"tags" - Tags map[string]string `protobuf:"bytes,4,rep,name=tags,proto3" json:"tags" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3" msg:"tags"` - // droppedTrace specifies whether the trace was dropped by samplers or not. - // @gotags: json:"dropped_trace" msg:"dropped_trace" - DroppedTrace bool `protobuf:"varint,5,opt,name=droppedTrace,proto3" json:"dropped_trace" msg:"dropped_trace"` -} - -func (x *TraceChunk) Reset() { - *x = TraceChunk{} - if protoimpl.UnsafeEnabled { - mi := &file_datadog_trace_tracer_payload_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *TraceChunk) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*TraceChunk) ProtoMessage() {} - -func (x *TraceChunk) ProtoReflect() protoreflect.Message { - mi := &file_datadog_trace_tracer_payload_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use TraceChunk.ProtoReflect.Descriptor instead. -func (*TraceChunk) Descriptor() ([]byte, []int) { - return file_datadog_trace_tracer_payload_proto_rawDescGZIP(), []int{0} -} - -func (x *TraceChunk) GetPriority() int32 { - if x != nil { - return x.Priority - } - return 0 -} - -func (x *TraceChunk) GetOrigin() string { - if x != nil { - return x.Origin - } - return "" -} - -func (x *TraceChunk) GetSpans() []*Span { - if x != nil { - return x.Spans - } - return nil -} - -func (x *TraceChunk) GetTags() map[string]string { - if x != nil { - return x.Tags - } - return nil -} - -func (x *TraceChunk) GetDroppedTrace() bool { - if x != nil { - return x.DroppedTrace - } - return false -} - -// TracerPayload represents a payload the trace agent receives from tracers. -type TracerPayload struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // containerID specifies the ID of the container where the tracer is running on. - // @gotags: json:"container_id" msg:"container_id" - ContainerID string `protobuf:"bytes,1,opt,name=containerID,proto3" json:"container_id" msg:"container_id"` - // languageName specifies language of the tracer. - // @gotags: json:"language_name" msg:"language_name" - LanguageName string `protobuf:"bytes,2,opt,name=languageName,proto3" json:"language_name" msg:"language_name"` - // languageVersion specifies language version of the tracer. - // @gotags: json:"language_version" msg:"language_version" - LanguageVersion string `protobuf:"bytes,3,opt,name=languageVersion,proto3" json:"language_version" msg:"language_version"` - // tracerVersion specifies version of the tracer. - // @gotags: json:"tracer_version" msg:"tracer_version" - TracerVersion string `protobuf:"bytes,4,opt,name=tracerVersion,proto3" json:"tracer_version" msg:"tracer_version"` - // runtimeID specifies V4 UUID representation of a tracer session. - // @gotags: json:"runtime_id" msg:"runtime_id" - RuntimeID string `protobuf:"bytes,5,opt,name=runtimeID,proto3" json:"runtime_id" msg:"runtime_id"` - // chunks specifies list of containing trace chunks. - // @gotags: json:"chunks" msg:"chunks" - Chunks []*TraceChunk `protobuf:"bytes,6,rep,name=chunks,proto3" json:"chunks" msg:"chunks"` - // tags specifies tags common in all `chunks`. - // @gotags: json:"tags" msg:"tags" - Tags map[string]string `protobuf:"bytes,7,rep,name=tags,proto3" json:"tags" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3" msg:"tags"` - // env specifies `env` tag that set with the tracer. - // @gotags: json:"env" msg:"env" - Env string `protobuf:"bytes,8,opt,name=env,proto3" json:"env" msg:"env"` - // hostname specifies hostname of where the tracer is running. - // @gotags: json:"hostname" msg:"hostname" - Hostname string `protobuf:"bytes,9,opt,name=hostname,proto3" json:"hostname" msg:"hostname"` - // version specifies `version` tag that set with the tracer. - // @gotags: json:"app_version" msg:"app_version" - AppVersion string `protobuf:"bytes,10,opt,name=appVersion,proto3" json:"app_version" msg:"app_version"` -} - -func (x *TracerPayload) Reset() { - *x = TracerPayload{} - if protoimpl.UnsafeEnabled { - mi := &file_datadog_trace_tracer_payload_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *TracerPayload) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*TracerPayload) ProtoMessage() {} - -func (x *TracerPayload) ProtoReflect() protoreflect.Message { - mi := &file_datadog_trace_tracer_payload_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use TracerPayload.ProtoReflect.Descriptor instead. -func (*TracerPayload) Descriptor() ([]byte, []int) { - return file_datadog_trace_tracer_payload_proto_rawDescGZIP(), []int{1} -} - -func (x *TracerPayload) GetContainerID() string { - if x != nil { - return x.ContainerID - } - return "" -} - -func (x *TracerPayload) GetLanguageName() string { - if x != nil { - return x.LanguageName - } - return "" -} - -func (x *TracerPayload) GetLanguageVersion() string { - if x != nil { - return x.LanguageVersion - } - return "" -} - -func (x *TracerPayload) GetTracerVersion() string { - if x != nil { - return x.TracerVersion - } - return "" -} - -func (x *TracerPayload) GetRuntimeID() string { - if x != nil { - return x.RuntimeID - } - return "" -} - -func (x *TracerPayload) GetChunks() []*TraceChunk { - if x != nil { - return x.Chunks - } - return nil -} - -func (x *TracerPayload) GetTags() map[string]string { - if x != nil { - return x.Tags - } - return nil -} - -func (x *TracerPayload) GetEnv() string { - if x != nil { - return x.Env - } - return "" -} - -func (x *TracerPayload) GetHostname() string { - if x != nil { - return x.Hostname - } - return "" -} - -func (x *TracerPayload) GetAppVersion() string { - if x != nil { - return x.AppVersion - } - return "" -} - -var File_datadog_trace_tracer_payload_proto protoreflect.FileDescriptor - -var file_datadog_trace_tracer_payload_proto_rawDesc = []byte{ - 0x0a, 0x22, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2f, - 0x74, 0x72, 0x61, 0x63, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x74, 0x72, - 0x61, 0x63, 0x65, 0x1a, 0x18, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2f, 0x74, 0x72, 0x61, - 0x63, 0x65, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x81, 0x02, - 0x0a, 0x0a, 0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x12, 0x1a, 0x0a, 0x08, - 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, - 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x72, 0x69, 0x67, - 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, - 0x12, 0x29, 0x0a, 0x05, 0x73, 0x70, 0x61, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x13, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, 0x67, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, - 0x53, 0x70, 0x61, 0x6e, 0x52, 0x05, 0x73, 0x70, 0x61, 0x6e, 0x73, 0x12, 0x37, 0x0a, 0x04, 0x74, - 0x61, 0x67, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x64, 0x61, 0x74, 0x61, - 0x64, 0x6f, 0x67, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x65, 0x43, - 0x68, 0x75, 0x6e, 0x6b, 0x2e, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, - 0x74, 0x61, 0x67, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x54, - 0x72, 0x61, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x64, 0x72, 0x6f, 0x70, - 0x70, 0x65, 0x64, 0x54, 0x72, 0x61, 0x63, 0x65, 0x1a, 0x37, 0x0a, 0x09, 0x54, 0x61, 0x67, 0x73, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, - 0x01, 0x22, 0xb9, 0x03, 0x0a, 0x0d, 0x54, 0x72, 0x61, 0x63, 0x65, 0x72, 0x50, 0x61, 0x79, 0x6c, - 0x6f, 0x61, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x49, 0x44, 0x12, 0x22, 0x0a, 0x0c, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, - 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6c, 0x61, 0x6e, - 0x67, 0x75, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x6c, 0x61, 0x6e, - 0x67, 0x75, 0x61, 0x67, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0f, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x56, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x12, 0x24, 0x0a, 0x0d, 0x74, 0x72, 0x61, 0x63, 0x65, 0x72, 0x56, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x63, - 0x65, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x75, 0x6e, - 0x74, 0x69, 0x6d, 0x65, 0x49, 0x44, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x75, - 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x49, 0x44, 0x12, 0x31, 0x0a, 0x06, 0x63, 0x68, 0x75, 0x6e, 0x6b, - 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, 0x6f, - 0x67, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x68, 0x75, - 0x6e, 0x6b, 0x52, 0x06, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x73, 0x12, 0x3a, 0x0a, 0x04, 0x74, 0x61, - 0x67, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x64, - 0x6f, 0x67, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x65, 0x72, 0x50, - 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, 0x76, 0x18, 0x08, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x65, 0x6e, 0x76, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, - 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x70, 0x70, 0x56, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x70, 0x70, 0x56, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x37, 0x0a, 0x09, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, - 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x16, 0x5a, - 0x14, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x67, 0x6f, 0x2f, - 0x74, 0x72, 0x61, 0x63, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_datadog_trace_tracer_payload_proto_rawDescOnce sync.Once - file_datadog_trace_tracer_payload_proto_rawDescData = file_datadog_trace_tracer_payload_proto_rawDesc -) - -func file_datadog_trace_tracer_payload_proto_rawDescGZIP() []byte { - file_datadog_trace_tracer_payload_proto_rawDescOnce.Do(func() { - file_datadog_trace_tracer_payload_proto_rawDescData = protoimpl.X.CompressGZIP(file_datadog_trace_tracer_payload_proto_rawDescData) - }) - return file_datadog_trace_tracer_payload_proto_rawDescData -} - -var file_datadog_trace_tracer_payload_proto_msgTypes = make([]protoimpl.MessageInfo, 4) -var file_datadog_trace_tracer_payload_proto_goTypes = []interface{}{ - (*TraceChunk)(nil), // 0: datadog.trace.TraceChunk - (*TracerPayload)(nil), // 1: datadog.trace.TracerPayload - nil, // 2: datadog.trace.TraceChunk.TagsEntry - nil, // 3: datadog.trace.TracerPayload.TagsEntry - (*Span)(nil), // 4: datadog.trace.Span -} -var file_datadog_trace_tracer_payload_proto_depIdxs = []int32{ - 4, // 0: datadog.trace.TraceChunk.spans:type_name -> datadog.trace.Span - 2, // 1: datadog.trace.TraceChunk.tags:type_name -> datadog.trace.TraceChunk.TagsEntry - 0, // 2: datadog.trace.TracerPayload.chunks:type_name -> datadog.trace.TraceChunk - 3, // 3: datadog.trace.TracerPayload.tags:type_name -> datadog.trace.TracerPayload.TagsEntry - 4, // [4:4] is the sub-list for method output_type - 4, // [4:4] is the sub-list for method input_type - 4, // [4:4] is the sub-list for extension type_name - 4, // [4:4] is the sub-list for extension extendee - 0, // [0:4] is the sub-list for field type_name -} - -func init() { file_datadog_trace_tracer_payload_proto_init() } -func file_datadog_trace_tracer_payload_proto_init() { - if File_datadog_trace_tracer_payload_proto != nil { - return - } - file_datadog_trace_span_proto_init() - if !protoimpl.UnsafeEnabled { - file_datadog_trace_tracer_payload_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TraceChunk); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_datadog_trace_tracer_payload_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TracerPayload); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_datadog_trace_tracer_payload_proto_rawDesc, - NumEnums: 0, - NumMessages: 4, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_datadog_trace_tracer_payload_proto_goTypes, - DependencyIndexes: file_datadog_trace_tracer_payload_proto_depIdxs, - MessageInfos: file_datadog_trace_tracer_payload_proto_msgTypes, - }.Build() - File_datadog_trace_tracer_payload_proto = out.File - file_datadog_trace_tracer_payload_proto_rawDesc = nil - file_datadog_trace_tracer_payload_proto_goTypes = nil - file_datadog_trace_tracer_payload_proto_depIdxs = nil -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/tracer_payload_gen.go b/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/tracer_payload_gen.go deleted file mode 100644 index cd2b3925..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/tracer_payload_gen.go +++ /dev/null @@ -1,384 +0,0 @@ -package trace - -// Code generated by github.com/tinylib/msgp DO NOT EDIT. - -import ( - "github.com/tinylib/msgp/msgp" -) - -// MarshalMsg implements msgp.Marshaler -func (z *TraceChunk) MarshalMsg(b []byte) (o []byte, err error) { - o = msgp.Require(b, z.Msgsize()) - // map header, size 5 - // string "priority" - o = append(o, 0x85, 0xa8, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79) - o = msgp.AppendInt32(o, z.Priority) - // string "origin" - o = append(o, 0xa6, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e) - o = msgp.AppendString(o, z.Origin) - // string "spans" - o = append(o, 0xa5, 0x73, 0x70, 0x61, 0x6e, 0x73) - o = msgp.AppendArrayHeader(o, uint32(len(z.Spans))) - for za0001 := range z.Spans { - if z.Spans[za0001] == nil { - o = msgp.AppendNil(o) - } else { - o, err = z.Spans[za0001].MarshalMsg(o) - if err != nil { - err = msgp.WrapError(err, "Spans", za0001) - return - } - } - } - // string "tags" - o = append(o, 0xa4, 0x74, 0x61, 0x67, 0x73) - o = msgp.AppendMapHeader(o, uint32(len(z.Tags))) - for za0002, za0003 := range z.Tags { - o = msgp.AppendString(o, za0002) - o = msgp.AppendString(o, za0003) - } - // string "dropped_trace" - o = append(o, 0xad, 0x64, 0x72, 0x6f, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x74, 0x72, 0x61, 0x63, 0x65) - o = msgp.AppendBool(o, z.DroppedTrace) - return -} - -// UnmarshalMsg implements msgp.Unmarshaler -func (z *TraceChunk) UnmarshalMsg(bts []byte) (o []byte, err error) { - var field []byte - _ = field - var zb0001 uint32 - zb0001, bts, err = msgp.ReadMapHeaderBytes(bts) - if err != nil { - err = msgp.WrapError(err) - return - } - for zb0001 > 0 { - zb0001-- - field, bts, err = msgp.ReadMapKeyZC(bts) - if err != nil { - err = msgp.WrapError(err) - return - } - switch msgp.UnsafeString(field) { - case "priority": - z.Priority, bts, err = msgp.ReadInt32Bytes(bts) - if err != nil { - err = msgp.WrapError(err, "Priority") - return - } - case "origin": - z.Origin, bts, err = msgp.ReadStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "Origin") - return - } - case "spans": - var zb0002 uint32 - zb0002, bts, err = msgp.ReadArrayHeaderBytes(bts) - if err != nil { - err = msgp.WrapError(err, "Spans") - return - } - if cap(z.Spans) >= int(zb0002) { - z.Spans = (z.Spans)[:zb0002] - } else { - z.Spans = make([]*Span, zb0002) - } - for za0001 := range z.Spans { - if msgp.IsNil(bts) { - bts, err = msgp.ReadNilBytes(bts) - if err != nil { - return - } - z.Spans[za0001] = nil - } else { - if z.Spans[za0001] == nil { - z.Spans[za0001] = new(Span) - } - bts, err = z.Spans[za0001].UnmarshalMsg(bts) - if err != nil { - err = msgp.WrapError(err, "Spans", za0001) - return - } - } - } - case "tags": - var zb0003 uint32 - zb0003, bts, err = msgp.ReadMapHeaderBytes(bts) - if err != nil { - err = msgp.WrapError(err, "Tags") - return - } - if z.Tags == nil { - z.Tags = make(map[string]string, zb0003) - } else if len(z.Tags) > 0 { - for key := range z.Tags { - delete(z.Tags, key) - } - } - for zb0003 > 0 { - var za0002 string - var za0003 string - zb0003-- - za0002, bts, err = msgp.ReadStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "Tags") - return - } - za0003, bts, err = msgp.ReadStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "Tags", za0002) - return - } - z.Tags[za0002] = za0003 - } - case "dropped_trace": - z.DroppedTrace, bts, err = msgp.ReadBoolBytes(bts) - if err != nil { - err = msgp.WrapError(err, "DroppedTrace") - return - } - default: - bts, err = msgp.Skip(bts) - if err != nil { - err = msgp.WrapError(err) - return - } - } - } - o = bts - return -} - -// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message -func (z *TraceChunk) Msgsize() (s int) { - s = 1 + 9 + msgp.Int32Size + 7 + msgp.StringPrefixSize + len(z.Origin) + 6 + msgp.ArrayHeaderSize - for za0001 := range z.Spans { - if z.Spans[za0001] == nil { - s += msgp.NilSize - } else { - s += z.Spans[za0001].Msgsize() - } - } - s += 5 + msgp.MapHeaderSize - if z.Tags != nil { - for za0002, za0003 := range z.Tags { - _ = za0003 - s += msgp.StringPrefixSize + len(za0002) + msgp.StringPrefixSize + len(za0003) - } - } - s += 14 + msgp.BoolSize - return -} - -// MarshalMsg implements msgp.Marshaler -func (z *TracerPayload) MarshalMsg(b []byte) (o []byte, err error) { - o = msgp.Require(b, z.Msgsize()) - // map header, size 10 - // string "container_id" - o = append(o, 0x8a, 0xac, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64) - o = msgp.AppendString(o, z.ContainerID) - // string "language_name" - o = append(o, 0xad, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65) - o = msgp.AppendString(o, z.LanguageName) - // string "language_version" - o = append(o, 0xb0, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e) - o = msgp.AppendString(o, z.LanguageVersion) - // string "tracer_version" - o = append(o, 0xae, 0x74, 0x72, 0x61, 0x63, 0x65, 0x72, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e) - o = msgp.AppendString(o, z.TracerVersion) - // string "runtime_id" - o = append(o, 0xaa, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x69, 0x64) - o = msgp.AppendString(o, z.RuntimeID) - // string "chunks" - o = append(o, 0xa6, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x73) - o = msgp.AppendArrayHeader(o, uint32(len(z.Chunks))) - for za0001 := range z.Chunks { - if z.Chunks[za0001] == nil { - o = msgp.AppendNil(o) - } else { - o, err = z.Chunks[za0001].MarshalMsg(o) - if err != nil { - err = msgp.WrapError(err, "Chunks", za0001) - return - } - } - } - // string "tags" - o = append(o, 0xa4, 0x74, 0x61, 0x67, 0x73) - o = msgp.AppendMapHeader(o, uint32(len(z.Tags))) - for za0002, za0003 := range z.Tags { - o = msgp.AppendString(o, za0002) - o = msgp.AppendString(o, za0003) - } - // string "env" - o = append(o, 0xa3, 0x65, 0x6e, 0x76) - o = msgp.AppendString(o, z.Env) - // string "hostname" - o = append(o, 0xa8, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65) - o = msgp.AppendString(o, z.Hostname) - // string "app_version" - o = append(o, 0xab, 0x61, 0x70, 0x70, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e) - o = msgp.AppendString(o, z.AppVersion) - return -} - -// UnmarshalMsg implements msgp.Unmarshaler -func (z *TracerPayload) UnmarshalMsg(bts []byte) (o []byte, err error) { - var field []byte - _ = field - var zb0001 uint32 - zb0001, bts, err = msgp.ReadMapHeaderBytes(bts) - if err != nil { - err = msgp.WrapError(err) - return - } - for zb0001 > 0 { - zb0001-- - field, bts, err = msgp.ReadMapKeyZC(bts) - if err != nil { - err = msgp.WrapError(err) - return - } - switch msgp.UnsafeString(field) { - case "container_id": - z.ContainerID, bts, err = msgp.ReadStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "ContainerID") - return - } - case "language_name": - z.LanguageName, bts, err = msgp.ReadStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "LanguageName") - return - } - case "language_version": - z.LanguageVersion, bts, err = msgp.ReadStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "LanguageVersion") - return - } - case "tracer_version": - z.TracerVersion, bts, err = msgp.ReadStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "TracerVersion") - return - } - case "runtime_id": - z.RuntimeID, bts, err = msgp.ReadStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "RuntimeID") - return - } - case "chunks": - var zb0002 uint32 - zb0002, bts, err = msgp.ReadArrayHeaderBytes(bts) - if err != nil { - err = msgp.WrapError(err, "Chunks") - return - } - if cap(z.Chunks) >= int(zb0002) { - z.Chunks = (z.Chunks)[:zb0002] - } else { - z.Chunks = make([]*TraceChunk, zb0002) - } - for za0001 := range z.Chunks { - if msgp.IsNil(bts) { - bts, err = msgp.ReadNilBytes(bts) - if err != nil { - return - } - z.Chunks[za0001] = nil - } else { - if z.Chunks[za0001] == nil { - z.Chunks[za0001] = new(TraceChunk) - } - bts, err = z.Chunks[za0001].UnmarshalMsg(bts) - if err != nil { - err = msgp.WrapError(err, "Chunks", za0001) - return - } - } - } - case "tags": - var zb0003 uint32 - zb0003, bts, err = msgp.ReadMapHeaderBytes(bts) - if err != nil { - err = msgp.WrapError(err, "Tags") - return - } - if z.Tags == nil { - z.Tags = make(map[string]string, zb0003) - } else if len(z.Tags) > 0 { - for key := range z.Tags { - delete(z.Tags, key) - } - } - for zb0003 > 0 { - var za0002 string - var za0003 string - zb0003-- - za0002, bts, err = msgp.ReadStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "Tags") - return - } - za0003, bts, err = msgp.ReadStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "Tags", za0002) - return - } - z.Tags[za0002] = za0003 - } - case "env": - z.Env, bts, err = msgp.ReadStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "Env") - return - } - case "hostname": - z.Hostname, bts, err = msgp.ReadStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "Hostname") - return - } - case "app_version": - z.AppVersion, bts, err = msgp.ReadStringBytes(bts) - if err != nil { - err = msgp.WrapError(err, "AppVersion") - return - } - default: - bts, err = msgp.Skip(bts) - if err != nil { - err = msgp.WrapError(err) - return - } - } - } - o = bts - return -} - -// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message -func (z *TracerPayload) Msgsize() (s int) { - s = 1 + 13 + msgp.StringPrefixSize + len(z.ContainerID) + 14 + msgp.StringPrefixSize + len(z.LanguageName) + 17 + msgp.StringPrefixSize + len(z.LanguageVersion) + 15 + msgp.StringPrefixSize + len(z.TracerVersion) + 11 + msgp.StringPrefixSize + len(z.RuntimeID) + 7 + msgp.ArrayHeaderSize - for za0001 := range z.Chunks { - if z.Chunks[za0001] == nil { - s += msgp.NilSize - } else { - s += z.Chunks[za0001].Msgsize() - } - } - s += 5 + msgp.MapHeaderSize - if z.Tags != nil { - for za0002, za0003 := range z.Tags { - _ = za0003 - s += msgp.StringPrefixSize + len(za0002) + msgp.StringPrefixSize + len(za0003) - } - } - s += 4 + msgp.StringPrefixSize + len(z.Env) + 9 + msgp.StringPrefixSize + len(z.Hostname) + 12 + msgp.StringPrefixSize + len(z.AppVersion) - return -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/tracer_payload_utils.go b/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/tracer_payload_utils.go deleted file mode 100644 index 9f7fabba..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/tracer_payload_utils.go +++ /dev/null @@ -1,35 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package trace - -// traceChunkCopiedFields records the fields that are copied in ShallowCopy. -// This should match exactly the fields set in (*TraceChunk).ShallowCopy. -// This is used by tests to enforce the correctness of ShallowCopy. -var traceChunkCopiedFields = map[string]struct{}{ - "Priority": {}, - "Origin": {}, - "Spans": {}, - "Tags": {}, - "DroppedTrace": {}, -} - -// ShallowCopy returns a shallow copy of the copy-able portion of a TraceChunk. These are the -// public fields which will have a Get* method for them. The completeness of this -// method is enforced by the init function above. Instead of using pkg/proto/utils.ProtoCopier, -// which incurs heavy reflection cost for every copy at runtime, we use reflection once at -// startup to ensure our method is complete. -func (t *TraceChunk) ShallowCopy() *TraceChunk { - if t == nil { - return nil - } - return &TraceChunk{ - Priority: t.Priority, - Origin: t.Origin, - Spans: t.Spans, - Tags: t.Tags, - DroppedTrace: t.DroppedTrace, - } -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/tracer_payload_vtproto.pb.go b/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/tracer_payload_vtproto.pb.go deleted file mode 100644 index b1544fa2..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace/tracer_payload_vtproto.pb.go +++ /dev/null @@ -1,1066 +0,0 @@ -// Code generated by protoc-gen-go-vtproto. DO NOT EDIT. -// protoc-gen-go-vtproto version: v0.4.0 -// source: datadog/trace/tracer_payload.proto - -package trace - -import ( - fmt "fmt" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - io "io" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -func (m *TraceChunk) MarshalVT() (dAtA []byte, err error) { - if m == nil { - return nil, nil - } - size := m.SizeVT() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBufferVT(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *TraceChunk) MarshalToVT(dAtA []byte) (int, error) { - size := m.SizeVT() - return m.MarshalToSizedBufferVT(dAtA[:size]) -} - -func (m *TraceChunk) MarshalToSizedBufferVT(dAtA []byte) (int, error) { - if m == nil { - return 0, nil - } - i := len(dAtA) - _ = i - var l int - _ = l - if m.unknownFields != nil { - i -= len(m.unknownFields) - copy(dAtA[i:], m.unknownFields) - } - if m.DroppedTrace { - i-- - if m.DroppedTrace { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x28 - } - if len(m.Tags) > 0 { - for k := range m.Tags { - v := m.Tags[k] - baseI := i - i -= len(v) - copy(dAtA[i:], v) - i = encodeVarint(dAtA, i, uint64(len(v))) - i-- - dAtA[i] = 0x12 - i -= len(k) - copy(dAtA[i:], k) - i = encodeVarint(dAtA, i, uint64(len(k))) - i-- - dAtA[i] = 0xa - i = encodeVarint(dAtA, i, uint64(baseI-i)) - i-- - dAtA[i] = 0x22 - } - } - if len(m.Spans) > 0 { - for iNdEx := len(m.Spans) - 1; iNdEx >= 0; iNdEx-- { - size, err := m.Spans[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarint(dAtA, i, uint64(size)) - i-- - dAtA[i] = 0x1a - } - } - if len(m.Origin) > 0 { - i -= len(m.Origin) - copy(dAtA[i:], m.Origin) - i = encodeVarint(dAtA, i, uint64(len(m.Origin))) - i-- - dAtA[i] = 0x12 - } - if m.Priority != 0 { - i = encodeVarint(dAtA, i, uint64(m.Priority)) - i-- - dAtA[i] = 0x8 - } - return len(dAtA) - i, nil -} - -func (m *TracerPayload) MarshalVT() (dAtA []byte, err error) { - if m == nil { - return nil, nil - } - size := m.SizeVT() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBufferVT(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *TracerPayload) MarshalToVT(dAtA []byte) (int, error) { - size := m.SizeVT() - return m.MarshalToSizedBufferVT(dAtA[:size]) -} - -func (m *TracerPayload) MarshalToSizedBufferVT(dAtA []byte) (int, error) { - if m == nil { - return 0, nil - } - i := len(dAtA) - _ = i - var l int - _ = l - if m.unknownFields != nil { - i -= len(m.unknownFields) - copy(dAtA[i:], m.unknownFields) - } - if len(m.AppVersion) > 0 { - i -= len(m.AppVersion) - copy(dAtA[i:], m.AppVersion) - i = encodeVarint(dAtA, i, uint64(len(m.AppVersion))) - i-- - dAtA[i] = 0x52 - } - if len(m.Hostname) > 0 { - i -= len(m.Hostname) - copy(dAtA[i:], m.Hostname) - i = encodeVarint(dAtA, i, uint64(len(m.Hostname))) - i-- - dAtA[i] = 0x4a - } - if len(m.Env) > 0 { - i -= len(m.Env) - copy(dAtA[i:], m.Env) - i = encodeVarint(dAtA, i, uint64(len(m.Env))) - i-- - dAtA[i] = 0x42 - } - if len(m.Tags) > 0 { - for k := range m.Tags { - v := m.Tags[k] - baseI := i - i -= len(v) - copy(dAtA[i:], v) - i = encodeVarint(dAtA, i, uint64(len(v))) - i-- - dAtA[i] = 0x12 - i -= len(k) - copy(dAtA[i:], k) - i = encodeVarint(dAtA, i, uint64(len(k))) - i-- - dAtA[i] = 0xa - i = encodeVarint(dAtA, i, uint64(baseI-i)) - i-- - dAtA[i] = 0x3a - } - } - if len(m.Chunks) > 0 { - for iNdEx := len(m.Chunks) - 1; iNdEx >= 0; iNdEx-- { - size, err := m.Chunks[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarint(dAtA, i, uint64(size)) - i-- - dAtA[i] = 0x32 - } - } - if len(m.RuntimeID) > 0 { - i -= len(m.RuntimeID) - copy(dAtA[i:], m.RuntimeID) - i = encodeVarint(dAtA, i, uint64(len(m.RuntimeID))) - i-- - dAtA[i] = 0x2a - } - if len(m.TracerVersion) > 0 { - i -= len(m.TracerVersion) - copy(dAtA[i:], m.TracerVersion) - i = encodeVarint(dAtA, i, uint64(len(m.TracerVersion))) - i-- - dAtA[i] = 0x22 - } - if len(m.LanguageVersion) > 0 { - i -= len(m.LanguageVersion) - copy(dAtA[i:], m.LanguageVersion) - i = encodeVarint(dAtA, i, uint64(len(m.LanguageVersion))) - i-- - dAtA[i] = 0x1a - } - if len(m.LanguageName) > 0 { - i -= len(m.LanguageName) - copy(dAtA[i:], m.LanguageName) - i = encodeVarint(dAtA, i, uint64(len(m.LanguageName))) - i-- - dAtA[i] = 0x12 - } - if len(m.ContainerID) > 0 { - i -= len(m.ContainerID) - copy(dAtA[i:], m.ContainerID) - i = encodeVarint(dAtA, i, uint64(len(m.ContainerID))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *TraceChunk) SizeVT() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Priority != 0 { - n += 1 + sov(uint64(m.Priority)) - } - l = len(m.Origin) - if l > 0 { - n += 1 + l + sov(uint64(l)) - } - if len(m.Spans) > 0 { - for _, e := range m.Spans { - l = e.SizeVT() - n += 1 + l + sov(uint64(l)) - } - } - if len(m.Tags) > 0 { - for k, v := range m.Tags { - _ = k - _ = v - mapEntrySize := 1 + len(k) + sov(uint64(len(k))) + 1 + len(v) + sov(uint64(len(v))) - n += mapEntrySize + 1 + sov(uint64(mapEntrySize)) - } - } - if m.DroppedTrace { - n += 2 - } - n += len(m.unknownFields) - return n -} - -func (m *TracerPayload) SizeVT() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.ContainerID) - if l > 0 { - n += 1 + l + sov(uint64(l)) - } - l = len(m.LanguageName) - if l > 0 { - n += 1 + l + sov(uint64(l)) - } - l = len(m.LanguageVersion) - if l > 0 { - n += 1 + l + sov(uint64(l)) - } - l = len(m.TracerVersion) - if l > 0 { - n += 1 + l + sov(uint64(l)) - } - l = len(m.RuntimeID) - if l > 0 { - n += 1 + l + sov(uint64(l)) - } - if len(m.Chunks) > 0 { - for _, e := range m.Chunks { - l = e.SizeVT() - n += 1 + l + sov(uint64(l)) - } - } - if len(m.Tags) > 0 { - for k, v := range m.Tags { - _ = k - _ = v - mapEntrySize := 1 + len(k) + sov(uint64(len(k))) + 1 + len(v) + sov(uint64(len(v))) - n += mapEntrySize + 1 + sov(uint64(mapEntrySize)) - } - } - l = len(m.Env) - if l > 0 { - n += 1 + l + sov(uint64(l)) - } - l = len(m.Hostname) - if l > 0 { - n += 1 + l + sov(uint64(l)) - } - l = len(m.AppVersion) - if l > 0 { - n += 1 + l + sov(uint64(l)) - } - n += len(m.unknownFields) - return n -} - -func (m *TraceChunk) UnmarshalVT(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: TraceChunk: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: TraceChunk: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Priority", wireType) - } - m.Priority = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Priority |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Origin", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Origin = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Spans", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Spans = append(m.Spans, &Span{}) - if err := m.Spans[len(m.Spans)-1].UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Tags", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Tags == nil { - m.Tags = make(map[string]string) - } - var mapkey string - var mapvalue string - for iNdEx < postIndex { - entryPreIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - if fieldNum == 1 { - var stringLenmapkey uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapkey |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapkey := int(stringLenmapkey) - if intStringLenmapkey < 0 { - return ErrInvalidLength - } - postStringIndexmapkey := iNdEx + intStringLenmapkey - if postStringIndexmapkey < 0 { - return ErrInvalidLength - } - if postStringIndexmapkey > l { - return io.ErrUnexpectedEOF - } - mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) - iNdEx = postStringIndexmapkey - } else if fieldNum == 2 { - var stringLenmapvalue uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapvalue |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapvalue := int(stringLenmapvalue) - if intStringLenmapvalue < 0 { - return ErrInvalidLength - } - postStringIndexmapvalue := iNdEx + intStringLenmapvalue - if postStringIndexmapvalue < 0 { - return ErrInvalidLength - } - if postStringIndexmapvalue > l { - return io.ErrUnexpectedEOF - } - mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue]) - iNdEx = postStringIndexmapvalue - } else { - iNdEx = entryPreIndex - skippy, err := skip(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength - } - if (iNdEx + skippy) > postIndex { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - m.Tags[mapkey] = mapvalue - iNdEx = postIndex - case 5: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field DroppedTrace", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.DroppedTrace = bool(v != 0) - default: - iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *TracerPayload) UnmarshalVT(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: TracerPayload: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: TracerPayload: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ContainerID", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ContainerID = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field LanguageName", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.LanguageName = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field LanguageVersion", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.LanguageVersion = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TracerVersion", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.TracerVersion = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field RuntimeID", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.RuntimeID = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Chunks", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Chunks = append(m.Chunks, &TraceChunk{}) - if err := m.Chunks[len(m.Chunks)-1].UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 7: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Tags", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Tags == nil { - m.Tags = make(map[string]string) - } - var mapkey string - var mapvalue string - for iNdEx < postIndex { - entryPreIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - if fieldNum == 1 { - var stringLenmapkey uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapkey |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapkey := int(stringLenmapkey) - if intStringLenmapkey < 0 { - return ErrInvalidLength - } - postStringIndexmapkey := iNdEx + intStringLenmapkey - if postStringIndexmapkey < 0 { - return ErrInvalidLength - } - if postStringIndexmapkey > l { - return io.ErrUnexpectedEOF - } - mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) - iNdEx = postStringIndexmapkey - } else if fieldNum == 2 { - var stringLenmapvalue uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLenmapvalue |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLenmapvalue := int(stringLenmapvalue) - if intStringLenmapvalue < 0 { - return ErrInvalidLength - } - postStringIndexmapvalue := iNdEx + intStringLenmapvalue - if postStringIndexmapvalue < 0 { - return ErrInvalidLength - } - if postStringIndexmapvalue > l { - return io.ErrUnexpectedEOF - } - mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue]) - iNdEx = postStringIndexmapvalue - } else { - iNdEx = entryPreIndex - skippy, err := skip(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength - } - if (iNdEx + skippy) > postIndex { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - m.Tags[mapkey] = mapvalue - iNdEx = postIndex - case 8: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Env", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Env = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 9: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Hostname", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Hostname = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 10: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AppVersion", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflow - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLength - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.AppVersion = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skip(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLength - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/LICENSE b/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/LICENSE deleted file mode 100644 index b370545b..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/LICENSE +++ /dev/null @@ -1,200 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2016-present Datadog, Inc. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/README.md b/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/README.md deleted file mode 100644 index a42ffb54..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Remote Config Go client - -This package powers the Remote Config client shipped in the Go tracer and in all the agent processes (core-agent, trace-agent, system-probe, ...). - -To add a new product simply add it to `products.go` as a constant and in the `validProducts` set. diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/agent_config.go b/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/agent_config.go deleted file mode 100644 index f6df6a93..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/agent_config.go +++ /dev/null @@ -1,159 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2023-present Datadog, Inc. - -package state - -import ( - "encoding/json" - "fmt" - "regexp" - - "github.com/pkg/errors" -) - -const agentConfigOrderID = "configuration_order" - -var datadogConfigIDRegexp = regexp.MustCompile(`^datadog/\d+/AGENT_CONFIG/([^/]+)/[^/]+$`) - -// AgentConfig is a deserialized agent configuration file -// along with the associated metadata -type AgentConfig struct { - Config agentConfigData - Metadata Metadata -} - -// ConfigContent contains the configurations set by remote-config -type ConfigContent struct { - LogLevel string `json:"log_level"` -} - -type agentConfigData struct { - Name string `json:"name"` - Config ConfigContent `json:"config"` -} - -// AgentConfigOrder is a deserialized agent configuration file -// along with the associated metadata -type AgentConfigOrder struct { - Config agentConfigOrderData - Metadata Metadata -} - -type agentConfigOrderData struct { - Order []string `json:"order"` - InternalOrder []string `json:"internal_order"` -} - -// AgentConfigState contains the state of the config in case of fallback or override -type AgentConfigState struct { - FallbackLogLevel string - LatestLogLevel string -} - -// parseConfigAgentConfig parses an agent task config -func parseConfigAgentConfig(data []byte, metadata Metadata) (AgentConfig, error) { - var d agentConfigData - - err := json.Unmarshal(data, &d) - if err != nil { - return AgentConfig{}, fmt.Errorf("Unexpected AGENT_CONFIG received through remote-config: %s", err) - } - - return AgentConfig{ - Config: d, - Metadata: metadata, - }, nil -} - -// parseConfigAgentConfig parses an agent task config -func parseConfigAgentConfigOrder(data []byte, metadata Metadata) (AgentConfigOrder, error) { - var d agentConfigOrderData - - err := json.Unmarshal(data, &d) - if err != nil { - return AgentConfigOrder{}, fmt.Errorf("Unexpected AGENT_CONFIG received through remote-config: %s", err) - } - - return AgentConfigOrder{ - Config: d, - Metadata: metadata, - }, nil -} - -// MergeRCAgentConfig is the callback function called when there is an AGENT_CONFIG config update -// The RCClient can directly call back listeners, because there would be no way to send back -// RCTE2 configuration applied state to RC backend. -func MergeRCAgentConfig(applyStatus func(cfgPath string, status ApplyStatus), updates map[string]RawConfig) (ConfigContent, error) { - var orderFile AgentConfigOrder - var hasError bool - var fullErr error - parsedLayers := map[string]AgentConfig{} - - for configPath, c := range updates { - var err error - matched := datadogConfigIDRegexp.FindStringSubmatch(configPath) - if len(matched) != 2 { - err = fmt.Errorf("config file path '%s' has wrong format", configPath) - hasError = true - fullErr = errors.Wrap(fullErr, err.Error()) - applyStatus(configPath, ApplyStatus{ - State: ApplyStateError, - Error: err.Error(), - }) - // If a layer is wrong, fail later to parse the rest and check them all - continue - } - - parsedConfigID := matched[1] - - // Ignore the configuration order file - if parsedConfigID == agentConfigOrderID { - orderFile, err = parseConfigAgentConfigOrder(c.Config, c.Metadata) - if err != nil { - hasError = true - fullErr = errors.Wrap(fullErr, err.Error()) - applyStatus(configPath, ApplyStatus{ - State: ApplyStateError, - Error: err.Error(), - }) - // If a layer is wrong, fail later to parse the rest and check them all - continue - } - } else { - cfg, err := parseConfigAgentConfig(c.Config, c.Metadata) - if err != nil { - hasError = true - applyStatus(configPath, ApplyStatus{ - State: ApplyStateError, - Error: err.Error(), - }) - // If a layer is wrong, fail later to parse the rest and check them all - continue - } - parsedLayers[parsedConfigID] = cfg - } - } - - // If there was at least one error, don't apply any config - if hasError || (len(orderFile.Config.Order) == 0 && len(orderFile.Config.InternalOrder) == 0) { - return ConfigContent{}, fullErr - } - - // Go through all the layers that were sent, and apply them one by one to the merged structure - mergedConfig := ConfigContent{} - for i := len(orderFile.Config.Order) - 1; i >= 0; i-- { - if layer, found := parsedLayers[orderFile.Config.Order[i]]; found { - mergedConfig.LogLevel = layer.Config.Config.LogLevel - } - } - // Same for internal config - for i := len(orderFile.Config.InternalOrder) - 1; i >= 0; i-- { - if layer, found := parsedLayers[orderFile.Config.InternalOrder[i]]; found { - mergedConfig.LogLevel = layer.Config.Config.LogLevel - } - } - - return mergedConfig, nil -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/configs.go b/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/configs.go deleted file mode 100644 index 06fdb273..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/configs.go +++ /dev/null @@ -1,123 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2022-present Datadog, Inc. - -package state - -import ( - "encoding/json" - "errors" - "fmt" - - "github.com/DataDog/go-tuf/data" -) - -// ErrNoConfigVersion occurs when a target file's custom meta is missing the config version -var ErrNoConfigVersion = errors.New("version missing in custom file meta") - -func parseConfig(product string, raw []byte, metadata Metadata) (interface{}, error) { - if _, validProduct := validProducts[product]; !validProduct { - return nil, fmt.Errorf("unknown product: %s", product) - } - - switch product { - // ASM products are parsed directly in this client - case ProductASMFeatures: - return parseASMFeaturesConfig(raw, metadata) - case ProductASMDD: - return parseConfigASMDD(raw, metadata) - case ProductASMData: - return parseConfigASMData(raw, metadata) - // case ProductAgentTask: - // return ParseConfigAgentTask(raw, metadata) - // Other products are parsed separately - default: - return RawConfig{ - Config: raw, - Metadata: metadata, - }, nil - } -} - -// RawConfig holds a config that will be parsed separately -type RawConfig struct { - Config []byte - Metadata Metadata -} - -// GetConfigs returns the current configs of a given product -func (r *Repository) GetConfigs(product string) map[string]RawConfig { - typedConfigs := make(map[string]RawConfig) - configs := r.getConfigs(product) - - for path, conf := range configs { - // We control this, so if this has gone wrong something has gone horribly wrong - typed, ok := conf.(RawConfig) - if !ok { - panic("unexpected config stored as RawConfig") - } - - typedConfigs[path] = typed - } - - return typedConfigs -} - -// Metadata stores remote config metadata for a given configuration -type Metadata struct { - Product string - ID string - Name string - Version uint64 - RawLength uint64 - Hashes map[string][]byte - ApplyStatus ApplyStatus -} - -func newConfigMetadata(parsedPath configPath, tfm data.TargetFileMeta) (Metadata, error) { - var m Metadata - m.ID = parsedPath.ConfigID - m.Product = parsedPath.Product - m.Name = parsedPath.Name - m.RawLength = uint64(tfm.Length) - m.Hashes = make(map[string][]byte) - for k, v := range tfm.Hashes { - m.Hashes[k] = []byte(v) - } - v, err := fileMetaVersion(tfm) - if err != nil { - return Metadata{}, err - } - m.Version = v - - return m, nil -} - -type fileMetaCustom struct { - Version *uint64 `json:"v"` -} - -func fileMetaVersion(fm data.TargetFileMeta) (uint64, error) { - if fm.Custom == nil { - return 0, ErrNoConfigVersion - } - fmc, err := parseFileMetaCustom(*fm.Custom) - if err != nil { - return 0, err - } - - return *fmc.Version, nil -} - -func parseFileMetaCustom(rawCustom []byte) (fileMetaCustom, error) { - var custom fileMetaCustom - err := json.Unmarshal(rawCustom, &custom) - if err != nil { - return fileMetaCustom{}, err - } - if custom.Version == nil { - return fileMetaCustom{}, ErrNoConfigVersion - } - return custom, nil -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/configs_agent_task.go b/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/configs_agent_task.go deleted file mode 100644 index 618bf733..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/configs_agent_task.go +++ /dev/null @@ -1,59 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2023-present Datadog, Inc. - -package state - -import ( - "encoding/json" - "fmt" -) - -// AgentTaskConfig is a deserialized agent task configuration file -// along with the associated metadata -type AgentTaskConfig struct { - Config AgentTaskData - Metadata Metadata -} - -// AgentTaskData is the content of a agent task configuration file -type AgentTaskData struct { - TaskType string `json:"task_type"` - UUID string `json:"uuid"` - TaskArgs map[string]string `json:"args"` -} - -// ParseConfigAgentTask parses an agent task config -func ParseConfigAgentTask(data []byte, metadata Metadata) (AgentTaskConfig, error) { - var d AgentTaskData - - err := json.Unmarshal(data, &d) - if err != nil { - return AgentTaskConfig{}, fmt.Errorf("Unexpected AGENT_TASK received through remote-config: %s", err) - } - - return AgentTaskConfig{ - Config: d, - Metadata: metadata, - }, nil -} - -// AgentTaskConfigs returns the currently active AGENT_TASK configs -func (r *Repository) AgentTaskConfigs() map[string]AgentTaskConfig { - typedConfigs := make(map[string]AgentTaskConfig) - - configs := r.getConfigs(ProductAgentTask) - - for path, conf := range configs { - // We control this, so if this has gone wrong something has gone horribly wrong - typed, ok := conf.(AgentTaskConfig) - if !ok { - panic("unexpected config stored as AgentTaskConfigs") - } - - typedConfigs[path] = typed - } - - return typedConfigs -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/configs_asm.go b/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/configs_asm.go deleted file mode 100644 index 00b377db..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/configs_asm.go +++ /dev/null @@ -1,166 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2022-present Datadog, Inc. - -package state - -import ( - "encoding/json" -) - -// ConfigASMDD is a deserialized ASM DD configuration file along with its -// associated remote config metadata -type ConfigASMDD struct { - Config []byte - Metadata Metadata -} - -func parseConfigASMDD(data []byte, metadata Metadata) (ConfigASMDD, error) { - return ConfigASMDD{ - Config: data, - Metadata: metadata, - }, nil -} - -// ASMDDConfigs returns the currently active ASMDD configs -func (r *Repository) ASMDDConfigs() map[string]ConfigASMDD { - typedConfigs := make(map[string]ConfigASMDD) - - configs := r.getConfigs(ProductASMDD) - - for path, conf := range configs { - // We control this, so if this has gone wrong something has gone horribly wrong - typed, ok := conf.(ConfigASMDD) - if !ok { - panic("unexpected config stored as ASMDD Config") - } - - typedConfigs[path] = typed - } - - return typedConfigs -} - -// ASMFeaturesConfig is a deserialized configuration file that indicates whether ASM should be enabled -// within a tracer, along with its associated remote config metadata. -type ASMFeaturesConfig struct { - Config ASMFeaturesData - Metadata Metadata -} - -// ASMFeaturesData describes the state of ASM and some of its features -type ASMFeaturesData struct { - ASM struct { - Enabled bool `json:"enabled"` - } `json:"asm"` - APISecurity struct { - RequestSampleRate float64 `json:"request_sample_rate"` - } `json:"api_security"` -} - -func parseASMFeaturesConfig(data []byte, metadata Metadata) (ASMFeaturesConfig, error) { - var f ASMFeaturesData - - err := json.Unmarshal(data, &f) - if err != nil { - return ASMFeaturesConfig{}, nil - } - - return ASMFeaturesConfig{ - Config: f, - Metadata: metadata, - }, nil -} - -// ASMFeaturesConfigs returns the currently active ASMFeatures configs -func (r *Repository) ASMFeaturesConfigs() map[string]ASMFeaturesConfig { - typedConfigs := make(map[string]ASMFeaturesConfig) - - configs := r.getConfigs(ProductASMFeatures) - - for path, conf := range configs { - // We control this, so if this has gone wrong something has gone horribly wrong - typed, ok := conf.(ASMFeaturesConfig) - if !ok { - panic("unexpected config stored as ASMFeaturesConfig") - } - - typedConfigs[path] = typed - } - - return typedConfigs -} - -// ApplyState represents the status of a configuration application by a remote configuration client -// Clients need to either ack the correct application of received configurations, or communicate that -// they haven't applied it yet, or communicate any error that may have happened while doing so -type ApplyState uint64 - -const ( - //ApplyStateUnknown indicates that a client does not support the ApplyState feature - ApplyStateUnknown ApplyState = iota - // ApplyStateUnacknowledged indicates a client has received the config but has not specified success or failure - ApplyStateUnacknowledged - // ApplyStateAcknowledged indicates a client has successfully applied the config - ApplyStateAcknowledged - // ApplyStateError indicates that a client has failed to apply the config - ApplyStateError -) - -// ApplyStatus is the processing status for a given configuration. -// It basically represents whether a config was successfully processed and apply, or if an error occurred -type ApplyStatus struct { - State ApplyState - Error string -} - -// ASMDataConfig is a deserialized configuration file that holds rules data that can be used -// by the ASM WAF for specific features (example: ip blocking). -type ASMDataConfig struct { - Config ASMDataRulesData - Metadata Metadata -} - -// ASMDataRulesData is a serializable array of rules data entries -type ASMDataRulesData struct { - RulesData []ASMDataRuleData `json:"rules_data"` -} - -// ASMDataRuleData is an entry in the rules data list held by an ASMData configuration -type ASMDataRuleData struct { - ID string `json:"id"` - Type string `json:"type"` - Data []ASMDataRuleDataEntry `json:"data"` -} - -// ASMDataRuleDataEntry represents a data entry in a rule data file -type ASMDataRuleDataEntry struct { - Expiration int64 `json:"expiration,omitempty"` - Value string `json:"value"` -} - -func parseConfigASMData(data []byte, metadata Metadata) (ASMDataConfig, error) { - cfg := ASMDataConfig{ - Metadata: metadata, - } - err := json.Unmarshal(data, &cfg.Config) - return cfg, err -} - -// ASMDataConfigs returns the currently active ASMData configs -func (r *Repository) ASMDataConfigs() map[string]ASMDataConfig { - typedConfigs := make(map[string]ASMDataConfig) - configs := r.getConfigs(ProductASMData) - - for path, cfg := range configs { - // We control this, so if this has gone wrong something has gone horribly wrong - typed, ok := cfg.(ASMDataConfig) - if !ok { - panic("unexpected config stored as ASMDataConfig") - } - typedConfigs[path] = typed - } - - return typedConfigs -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/path.go b/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/path.go deleted file mode 100644 index d1a4d69e..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/path.go +++ /dev/null @@ -1,100 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2022-present Datadog, Inc. - -package state - -import ( - "fmt" - "regexp" - "strconv" - "strings" -) - -var ( - // matches datadog//// for datadog//// - datadogPathRegexp = regexp.MustCompile(`^datadog/(\d+)/([^/]+)/([^/]+)/([^/]+)$`) - datadogPathRegexpGroups = 4 - - // matches employee/// for employee//// - employeePathRegexp = regexp.MustCompile(`^employee/([^/]+)/([^/]+)/([^/]+)$`) - employeePathRegexpGroups = 3 -) - -type source uint - -const ( - sourceUnknown source = iota - sourceDatadog - sourceEmployee -) - -type configPath struct { - Source source - OrgID int64 - Product string - ConfigID string - Name string -} - -func parseConfigPath(path string) (configPath, error) { - configType := parseConfigPathSource(path) - switch configType { - case sourceDatadog: - return parseDatadogConfigPath(path) - case sourceEmployee: - return parseEmployeeConfigPath(path) - } - return configPath{}, fmt.Errorf("config path '%s' has unknown source", path) -} - -func parseDatadogConfigPath(path string) (configPath, error) { - matchedGroups := datadogPathRegexp.FindStringSubmatch(path) - if len(matchedGroups) != datadogPathRegexpGroups+1 { - return configPath{}, fmt.Errorf("config file path '%s' has wrong format", path) - } - rawOrgID := matchedGroups[1] - orgID, err := strconv.ParseInt(rawOrgID, 10, 64) - if err != nil { - return configPath{}, fmt.Errorf("could not parse orgID '%s' in config file path: %v", rawOrgID, err) - } - rawProduct := matchedGroups[2] - if len(rawProduct) == 0 { - return configPath{}, fmt.Errorf("product is empty") - } - return configPath{ - Source: sourceDatadog, - OrgID: orgID, - Product: rawProduct, - ConfigID: matchedGroups[3], - Name: matchedGroups[4], - }, nil -} - -func parseEmployeeConfigPath(path string) (configPath, error) { - matchedGroups := employeePathRegexp.FindStringSubmatch(path) - if len(matchedGroups) != employeePathRegexpGroups+1 { - return configPath{}, fmt.Errorf("config file path '%s' has wrong format", path) - } - rawProduct := matchedGroups[1] - if len(rawProduct) == 0 { - return configPath{}, fmt.Errorf("product is empty") - } - return configPath{ - Source: sourceEmployee, - Product: rawProduct, - ConfigID: matchedGroups[2], - Name: matchedGroups[3], - }, nil -} - -func parseConfigPathSource(path string) source { - switch { - case strings.HasPrefix(path, "datadog/"): - return sourceDatadog - case strings.HasPrefix(path, "employee/"): - return sourceEmployee - } - return sourceUnknown -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/products.go b/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/products.go deleted file mode 100644 index 35974c5e..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/products.go +++ /dev/null @@ -1,84 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2022-present Datadog, Inc. - -package state - -var validProducts = map[string]struct{}{ - ProductUpdaterCatalogDD: {}, - ProductUpdaterAgent: {}, - ProductUpdaterTask: {}, - ProductAgentConfig: {}, - ProductAgentFailover: {}, - ProductAgentTask: {}, - ProductAgentIntegrations: {}, - ProductAPMSampling: {}, - ProductCWSDD: {}, - ProductCWSCustom: {}, - ProductCWSProfiles: {}, - ProductCSMSideScanning: {}, - ProductASM: {}, - ProductASMFeatures: {}, - ProductASMDD: {}, - ProductASMData: {}, - ProductAPMTracing: {}, - ProductSDSRules: {}, - ProductSDSAgentConfig: {}, - ProductLiveDebugging: {}, - ProductContainerAutoscalingSettings: {}, - ProductContainerAutoscalingValues: {}, - ProductTesting1: {}, - ProductTesting2: {}, -} - -const ( - // ProductUpdaterCatalogDD is the product used to receive the package catalog from datadog - ProductUpdaterCatalogDD = "UPDATER_CATALOG_DD" - // ProductUpdaterAgent is the product used to receive defaults versions to install - ProductUpdaterAgent = "UPDATER_AGENT" - // ProductUpdaterTask is the product used to receive tasks to execute - ProductUpdaterTask = "UPDATER_TASK" - // ProductAgentConfig is to receive agent configurations, like the log level - ProductAgentConfig = "AGENT_CONFIG" - // ProductAgentFailover is to receive the multi-region failover configuration - ProductAgentFailover = "AGENT_FAILOVER" - // ProductAgentIntegrations is to receive integrations to schedule - ProductAgentIntegrations = "AGENT_INTEGRATIONS" - // ProductAgentTask is to receive agent task instruction, like a flare - ProductAgentTask = "AGENT_TASK" - // ProductAPMSampling is the apm sampling product - ProductAPMSampling = "APM_SAMPLING" - // ProductCWSDD is the cloud workload security product managed by datadog employees - ProductCWSDD = "CWS_DD" - // ProductCWSCustom is the cloud workload security product managed by datadog customers - ProductCWSCustom = "CWS_CUSTOM" - // ProductCWSProfiles is the cloud workload security profile product - ProductCWSProfiles = "CWS_SECURITY_PROFILES" - // ProductCSMSideScanning is the side scanning product - ProductCSMSideScanning = "CSM_SIDE_SCANNING" - // ProductASM is the ASM product used by customers to issue rules configurations - ProductASM = "ASM" - // ProductASMFeatures is the ASM product used form ASM activation through remote config - ProductASMFeatures = "ASM_FEATURES" - // ProductASMDD is the application security monitoring product managed by datadog employees - ProductASMDD = "ASM_DD" - // ProductASMData is the ASM product used to configure WAF rules data - ProductASMData = "ASM_DATA" - // ProductAPMTracing is the apm tracing product - ProductAPMTracing = "APM_TRACING" - // ProductSDSRules is the SDS definitions product - ProductSDSRules = "SDS_RULES_DD" - // ProductSDSAgentConfig is the user SDS configurations product. - ProductSDSAgentConfig = "SDS_AGENT_CONFIG" - // ProductLiveDebugging is the dynamic instrumentation product - ProductLiveDebugging = "LIVE_DEBUGGING" - // ProductContainerAutoscalingSettings receives definition of container autoscaling - ProductContainerAutoscalingSettings = "CONTAINER_AUTOSCALING_SETTINGS" - // ProductContainerAutoscalingValues receives values for container autoscaling - ProductContainerAutoscalingValues = "CONTAINER_AUTOSCALING_VALUES" - // ProductTesting1 is a product used for testing remote config - ProductTesting1 = "TESTING1" - // ProductTesting2 is a product used for testing remote config - ProductTesting2 = "TESTING2" -) diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/repository.go b/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/repository.go deleted file mode 100644 index 031d20f2..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/repository.go +++ /dev/null @@ -1,444 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2022-present Datadog, Inc. - -// Package state provides the types and logic needed to track the current TUF repository -// state for a client. -package state - -import ( - "bytes" - "encoding/json" - "errors" - "fmt" - "log" - "strings" - - "github.com/DataDog/go-tuf/data" -) - -var ( - // ErrMalformedEmbeddedRoot occurs when the TUF root provided is invalid - ErrMalformedEmbeddedRoot = errors.New("malformed embedded TUF root file provided") -) - -// RepositoryState contains all of the information about the current config files -// stored by the client to be able to make an update request to an Agent -type RepositoryState struct { - Configs []ConfigState - CachedFiles []CachedFile - TargetsVersion int64 - RootsVersion int64 - OpaqueBackendState []byte -} - -// ConfigState describes an applied config by the agent client. -type ConfigState struct { - Product string - ID string - Version uint64 - ApplyStatus ApplyStatus -} - -// CachedFile describes a cached file stored by the agent client -// -// Note: You may be wondering why this exists when `ConfigState` exists -// as well. The API for requesting updates does not mandate that a client -// cache config files. This implementation just happens to do so. -type CachedFile struct { - Path string - Length uint64 - Hashes map[string][]byte -} - -// An Update contains all the data needed to update a client's remote config repository state -type Update struct { - // TUFRoots contains, in order, updated roots that this repository needs to keep up with TUF validation - TUFRoots [][]byte - // TUFTargets is the latest TUF Targets file and is used to validate raw config files - TUFTargets []byte - // TargetFiles stores the raw config files by their full TUF path - TargetFiles map[string][]byte - // ClientcConfigs is a list of TUF path's corresponding to config files designated for this repository - ClientConfigs []string -} - -// isEmpty returns whether or not all the fields of `Update` are empty -func (u *Update) isEmpty() bool { - return len(u.TUFRoots) == 0 && len(u.TUFTargets) == 0 && (u.TargetFiles == nil || len(u.TargetFiles) == 0) && len(u.ClientConfigs) == 0 -} - -// Repository is a remote config client used in a downstream process to retrieve -// remote config updates from an Agent. -type Repository struct { - // TUF related data - latestTargets *data.Targets - tufRootsClient *tufRootsClient - opaqueBackendState []byte - - // Unverified mode - tufVerificationEnabled bool - latestRootVersion int64 - - // Config file storage - metadata map[string]Metadata - configs map[string]map[string]interface{} -} - -// NewRepository creates a new remote config repository that will track -// both TUF metadata and raw config files for a client. -func NewRepository(embeddedRoot []byte) (*Repository, error) { - if embeddedRoot == nil { - return nil, ErrMalformedEmbeddedRoot - } - - configs := make(map[string]map[string]interface{}) - for product := range validProducts { - configs[product] = make(map[string]interface{}) - } - - tufRootsClient, err := newTufRootsClient(embeddedRoot) - if err != nil { - return nil, err - } - - return &Repository{ - latestTargets: data.NewTargets(), - tufRootsClient: tufRootsClient, - metadata: make(map[string]Metadata), - configs: configs, - tufVerificationEnabled: true, - }, nil -} - -// NewUnverifiedRepository creates a new remote config repository that will -// track config files for a client WITHOUT verifying any TUF related metadata. -// -// When creating this we pretend we have a root version of 1, as the backend expects -// to not have to send the initial "embedded" root. -func NewUnverifiedRepository() (*Repository, error) { - configs := make(map[string]map[string]interface{}) - for product := range validProducts { - configs[product] = make(map[string]interface{}) - } - - return &Repository{ - latestTargets: data.NewTargets(), - metadata: make(map[string]Metadata), - configs: configs, - tufVerificationEnabled: false, - latestRootVersion: 1, // The backend expects us to start with a root version of 1. - }, nil -} - -// Update processes the ClientGetConfigsResponse from the Agent and updates the -// configuration state -func (r *Repository) Update(update Update) ([]string, error) { - var err error - var updatedTargets *data.Targets - var tmpRootClient *tufRootsClient - - // If there's literally nothing in the update, it's not an error. - if update.isEmpty() { - return []string{}, nil - } - - // TUF: Update the roots and verify the TUF Targets file (optional) - // - // We don't want to partially update the state, so we need a temporary client to hold the new root - // data until we know it's valid. Since verification is optional, if the repository was configured - // to not do TUF verification we only deserialize the TUF targets file. - if r.tufVerificationEnabled { - tmpRootClient, err = r.tufRootsClient.clone() - if err != nil { - return nil, err - } - err = tmpRootClient.updateRoots(update.TUFRoots) - if err != nil { - return nil, err - } - - updatedTargets, err = tmpRootClient.validateTargets(update.TUFTargets) - if err != nil { - return nil, err - } - } else { - updatedTargets, err = unsafeUnmarshalTargets(update.TUFTargets) - if err != nil { - return nil, err - } - } - - clientConfigsMap := make(map[string]struct{}) - for _, f := range update.ClientConfigs { - clientConfigsMap[f] = struct{}{} - } - - result := newUpdateResult() - - // 2: Check the config list and mark any missing configs as "to be removed" - for _, configs := range r.configs { - for path := range configs { - if _, ok := clientConfigsMap[path]; !ok { - result.removed = append(result.removed, path) - parsedPath, err := parseConfigPath(path) - if err != nil { - return nil, err - } - result.productsUpdated[parsedPath.Product] = true - } - } - } - - // 3: For all the files referenced in this update - for _, path := range update.ClientConfigs { - targetFileMetadata, ok := updatedTargets.Targets[path] - if !ok { - return nil, fmt.Errorf("missing config file in TUF targets - %s", path) - } - - // 3.a: Extract the product and ID from the path - parsedPath, err := parseConfigPath(path) - if err != nil { - return nil, err - } - - // 3.b and 3.c: Check if this configuration is either new or has been modified - storedMetadata, exists := r.metadata[path] - if exists && hashesEqual(targetFileMetadata.Hashes, storedMetadata.Hashes) { - continue - } - - // 3.d: Ensure that the raw configuration file is present in the - // update payload. - raw, ok := update.TargetFiles[path] - if !ok { - return nil, fmt.Errorf("missing update file - %s", path) - } - - // TUF: Validate the hash of the raw target file and ensure that it matches - // the TUF metadata - err = validateTargetFileHash(targetFileMetadata, raw) - if err != nil { - return nil, fmt.Errorf("error validating %s hash with TUF metadata - %v", path, err) - } - - // 3.e: Deserialize the configuration. - // 3.f: Store the update details for application later - // - // Note: We don't have to worry about extra fields as mentioned - // in the RFC because the encoding/json library handles that for us. - m, err := newConfigMetadata(parsedPath, targetFileMetadata) - if err != nil { - return nil, err - } - config, err := parseConfig(parsedPath.Product, raw, m) - if err != nil { - return nil, err - } - result.metadata[path] = m - result.changed[parsedPath.Product][path] = config - result.productsUpdated[parsedPath.Product] = true - } - - // 4.a: Store the new targets.signed.custom.opaque_client_state - // TUF: Store the updated roots now that everything has validated - if r.tufVerificationEnabled { - r.tufRootsClient = tmpRootClient - } else if update.TUFRoots != nil && len(update.TUFRoots) > 0 { - v, err := extractRootVersion(update.TUFRoots[len(update.TUFRoots)-1]) - if err != nil { - return nil, err - } - r.latestRootVersion = v - } - r.latestTargets = updatedTargets - if r.latestTargets.Custom != nil { - r.opaqueBackendState = extractOpaqueBackendState(*r.latestTargets.Custom) - } - - // Upstream may not want to take any actions if the update result doesn't - // change any configs. - if result.isEmpty() { - return nil, nil - } - - changedProducts := make([]string, 0) - for product, updated := range result.productsUpdated { - if updated { - changedProducts = append(changedProducts, product) - } - } - - // 4.b/4.rave the new state and apply cleanups - r.applyUpdateResult(update, result) - - return changedProducts, nil -} - -// UpdateApplyStatus updates the config's metadata to reflect its processing state -// Can be used after a call to Update() in order to tell the repository which config was acked, which -// wasn't and which errors occurred while processing. -// Note: it is the responsibility of the caller to ensure that no new Update() call was made between -// the first Update() call and the call to UpdateApplyStatus() so as to keep the repository state accurate. -func (r *Repository) UpdateApplyStatus(cfgPath string, status ApplyStatus) { - if m, ok := r.metadata[cfgPath]; ok { - m.ApplyStatus = status - r.metadata[cfgPath] = m - } -} - -func (r *Repository) getConfigs(product string) map[string]interface{} { - configs, ok := r.configs[product] - if !ok { - return nil - } - - return configs -} - -// applyUpdateResult changes the state of the client based on the given update. -// -// The update is guaranteed to succeed at this point, having been vetted and the details -// needed to apply the update stored in the `updateResult`. -func (r *Repository) applyUpdateResult(_ Update, result updateResult) { - // 4.b Save all the updated and new config files - for product, configs := range result.changed { - for path, config := range configs { - m := r.configs[product] - m[path] = config - } - } - for path, metadata := range result.metadata { - r.metadata[path] = metadata - } - - // 5.b Clean up the cache of any removed configs - for _, path := range result.removed { - delete(r.metadata, path) - for _, configs := range r.configs { - delete(configs, path) - } - } -} - -// CurrentState returns all of the information needed to -// make an update for new configurations. -func (r *Repository) CurrentState() (RepositoryState, error) { - var configs []ConfigState - var cached []CachedFile - - for path, metadata := range r.metadata { - configs = append(configs, configStateFromMetadata(metadata)) - cached = append(cached, cachedFileFromMetadata(path, metadata)) - } - - var latestRootVersion int64 - if r.tufVerificationEnabled { - root, err := r.tufRootsClient.latestRoot() - if err != nil { - return RepositoryState{}, err - } - latestRootVersion = root.Version - } else { - latestRootVersion = r.latestRootVersion - } - - return RepositoryState{ - Configs: configs, - CachedFiles: cached, - TargetsVersion: r.latestTargets.Version, - RootsVersion: latestRootVersion, - OpaqueBackendState: r.opaqueBackendState, - }, nil -} - -// An updateResult allows the client to apply the update as a transaction -// after validating all required preconditions -type updateResult struct { - removed []string - metadata map[string]Metadata - changed map[string]map[string]interface{} - productsUpdated map[string]bool -} - -func newUpdateResult() updateResult { - changed := make(map[string]map[string]interface{}) - - for product := range validProducts { - changed[product] = make(map[string]interface{}) - } - - return updateResult{ - removed: make([]string, 0), - metadata: make(map[string]Metadata), - changed: changed, - productsUpdated: map[string]bool{}, - } -} - -func (ur updateResult) Log() { - log.Printf("Removed Configs: %v", ur.removed) - - var b strings.Builder - b.WriteString("Changed configs: [") - for path := range ur.metadata { - b.WriteString(path) - b.WriteString(" ") - } - b.WriteString("]") - - log.Println(b.String()) -} - -func (ur updateResult) isEmpty() bool { - return len(ur.removed) == 0 && len(ur.metadata) == 0 -} - -func configStateFromMetadata(m Metadata) ConfigState { - return ConfigState{ - Product: m.Product, - ID: m.ID, - Version: m.Version, - ApplyStatus: m.ApplyStatus, - } -} - -func cachedFileFromMetadata(path string, m Metadata) CachedFile { - return CachedFile{ - Path: path, - Length: m.RawLength, - Hashes: m.Hashes, - } -} - -// hashesEqual checks if the hash values in the TUF metadata file match the stored -// hash values for a given config -func hashesEqual(tufHashes data.Hashes, storedHashes map[string][]byte) bool { - for algorithm, value := range tufHashes { - v, ok := storedHashes[algorithm] - if !ok { - continue - } - - if !bytes.Equal(value, v) { - return false - } - } - - return true -} - -func extractOpaqueBackendState(targetsCustom []byte) []byte { - state := struct { - State []byte `json:"opaque_backend_state"` - }{nil} - - err := json.Unmarshal(targetsCustom, &state) - if err != nil { - return []byte{} - } - - return state.State -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/tuf.go b/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/tuf.go deleted file mode 100644 index f67ab9c1..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/remoteconfig/state/tuf.go +++ /dev/null @@ -1,233 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2022-present Datadog, Inc. - -package state - -import ( - "bytes" - "encoding/json" - "fmt" - "io" - "strconv" - "strings" - - "github.com/DataDog/go-tuf/client" - "github.com/DataDog/go-tuf/data" - "github.com/DataDog/go-tuf/util" - "github.com/DataDog/go-tuf/verify" -) - -type tufRootsClient struct { - rootClient *client.Client - rootLocalStore client.LocalStore - rootRemoteStore *rootClientRemoteStore -} - -func newTufRootsClient(root []byte) (*tufRootsClient, error) { - rootLocalStore := client.MemoryLocalStore() - rootRemoteStore := &rootClientRemoteStore{} - rootClient := client.NewClient(rootLocalStore, rootRemoteStore) - - err := rootClient.Init(root) - if err != nil { - return nil, err - } - - return &tufRootsClient{ - rootClient: rootClient, - rootLocalStore: rootLocalStore, - rootRemoteStore: rootRemoteStore, - }, nil -} - -func (trc *tufRootsClient) clone() (*tufRootsClient, error) { - root, err := trc.latestRootRaw() - if err != nil { - return nil, err - } - - return newTufRootsClient(root) -} - -func (trc *tufRootsClient) updateRoots(newRoots [][]byte) error { - if len(newRoots) == 0 { - return nil - } - - trc.rootRemoteStore.roots = append(trc.rootRemoteStore.roots, newRoots...) - - return trc.rootClient.UpdateRoots() -} - -func (trc *tufRootsClient) latestRoot() (*data.Root, error) { - raw, err := trc.latestRootRaw() - if err != nil { - return nil, err - } - - return unsafeUnmarshalRoot(raw) -} - -func (trc *tufRootsClient) latestRootRaw() ([]byte, error) { - metas, err := trc.rootLocalStore.GetMeta() - if err != nil { - return nil, err - } - rawRoot := metas["root.json"] - - return rawRoot, nil -} - -func (trc *tufRootsClient) validateTargets(rawTargets []byte) (*data.Targets, error) { - root, err := trc.latestRoot() - if err != nil { - return nil, err - } - - db := verify.NewDB() - for _, key := range root.Keys { - for _, id := range key.IDs() { - if err := db.AddKey(id, key); err != nil { - return nil, err - } - } - } - targetsRole, hasRoleTargets := root.Roles["targets"] - if !hasRoleTargets { - return nil, fmt.Errorf("root is missing a targets role") - } - role := &data.Role{Threshold: targetsRole.Threshold, KeyIDs: targetsRole.KeyIDs} - if err := db.AddRole("targets", role); err != nil { - return nil, fmt.Errorf("could not add targets role to db: %v", err) - } - var targets data.Targets - err = db.Unmarshal(rawTargets, &targets, "targets", 0) - if err != nil { - return nil, err - } - - return &targets, nil -} - -type rootClientRemoteStore struct { - roots [][]byte -} - -func (s *rootClientRemoteStore) GetMeta(name string) (stream io.ReadCloser, size int64, err error) { - metaPath, err := parseMetaPath(name) - if err != nil { - return nil, 0, err - } - if metaPath.role != roleRoot || !metaPath.versionSet { - return nil, 0, client.ErrNotFound{File: name} - } - for _, root := range s.roots { - parsedRoot, err := unsafeUnmarshalRoot(root) - if err != nil { - return nil, 0, err - } - if parsedRoot.Version == metaPath.version { - return io.NopCloser(bytes.NewReader(root)), int64(len(root)), nil - } - } - return nil, 0, client.ErrNotFound{File: name} -} - -func (s *rootClientRemoteStore) GetTarget(path string) (stream io.ReadCloser, size int64, err error) { - return nil, 0, client.ErrNotFound{File: path} -} - -type role string - -const ( - roleRoot role = "root" -) - -type metaPath struct { - role role - version int64 - versionSet bool -} - -func parseMetaPath(rawMetaPath string) (metaPath, error) { - splitRawMetaPath := strings.SplitN(rawMetaPath, ".", 3) - if len(splitRawMetaPath) != 2 && len(splitRawMetaPath) != 3 { - return metaPath{}, fmt.Errorf("invalid metadata path '%s'", rawMetaPath) - } - suffix := splitRawMetaPath[len(splitRawMetaPath)-1] - if suffix != "json" { - return metaPath{}, fmt.Errorf("invalid metadata path (suffix) '%s'", rawMetaPath) - } - rawRole := splitRawMetaPath[len(splitRawMetaPath)-2] - if rawRole == "" { - return metaPath{}, fmt.Errorf("invalid metadata path (role) '%s'", rawMetaPath) - } - if len(splitRawMetaPath) == 2 { - return metaPath{ - role: role(rawRole), - }, nil - } - rawVersion, err := strconv.ParseInt(splitRawMetaPath[0], 10, 64) - if err != nil { - return metaPath{}, fmt.Errorf("invalid metadata path (version) '%s': %w", rawMetaPath, err) - } - return metaPath{ - role: role(rawRole), - version: rawVersion, - versionSet: true, - }, nil -} - -func validateTargetFileHash(targetMeta data.TargetFileMeta, targetFile []byte) error { - if len(targetMeta.HashAlgorithms()) == 0 { - return fmt.Errorf("target file has no hash") - } - generatedMeta, err := util.GenerateFileMeta(bytes.NewBuffer(targetFile), targetMeta.HashAlgorithms()...) - if err != nil { - return err - } - err = util.FileMetaEqual(targetMeta.FileMeta, generatedMeta) - if err != nil { - return err - } - return nil -} - -func unsafeUnmarshalRoot(raw []byte) (*data.Root, error) { - var signedRoot data.Signed - err := json.Unmarshal(raw, &signedRoot) - if err != nil { - return nil, err - } - var root data.Root - err = json.Unmarshal(signedRoot.Signed, &root) - if err != nil { - return nil, err - } - return &root, err -} - -func unsafeUnmarshalTargets(raw []byte) (*data.Targets, error) { - var signedTargets data.Signed - err := json.Unmarshal(raw, &signedTargets) - if err != nil { - return nil, err - } - var targets data.Targets - err = json.Unmarshal(signedTargets.Signed, &targets) - if err != nil { - return nil, err - } - return &targets, err -} - -func extractRootVersion(raw []byte) (int64, error) { - root, err := unsafeUnmarshalRoot(raw) - if err != nil { - return 0, err - } - - return root.Version, nil -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/trace/LICENSE b/vendor/github.com/DataDog/datadog-agent/pkg/trace/LICENSE deleted file mode 100644 index b370545b..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/trace/LICENSE +++ /dev/null @@ -1,200 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2016-present Datadog, Inc. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/trace/config/client.go b/vendor/github.com/DataDog/datadog-agent/pkg/trace/config/client.go deleted file mode 100644 index b46de4fa..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/trace/config/client.go +++ /dev/null @@ -1,70 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -// Package config contains the configuration for the trace-agent. -package config - -import ( - "net/http" - "sync" - "time" -) - -// TODO(gbbr): Perhaps this is not the best place for this structure. - -// ResetClient wraps (http.Client).Do and resets the underlying connections at the -// configured interval -type ResetClient struct { - httpClientFactory func() *http.Client - resetInterval time.Duration - - mu sync.RWMutex - httpClient *http.Client - lastReset time.Time -} - -// NewResetClient returns an initialized Client resetting connections at the passed resetInterval ("0" -// means that no reset is performed). -// The underlying http.Client used will be created using the passed http client factory. -func NewResetClient(resetInterval time.Duration, httpClientFactory func() *http.Client) *ResetClient { - return &ResetClient{ - httpClientFactory: httpClientFactory, - resetInterval: resetInterval, - httpClient: httpClientFactory(), - lastReset: time.Now(), - } -} - -// Do wraps (http.Client).Do. Thread safe. -func (c *ResetClient) Do(req *http.Request) (*http.Response, error) { - c.checkReset() - - c.mu.RLock() - httpClient := c.httpClient - c.mu.RUnlock() - - return httpClient.Do(req) -} - -// checkReset checks whether a client reset should be performed, and performs it -// if so -func (c *ResetClient) checkReset() { - if c.resetInterval == 0 { - return - } - - c.mu.Lock() - defer c.mu.Unlock() - if time.Since(c.lastReset) < c.resetInterval { - return - } - - c.lastReset = time.Now() - // Close idle connections on underlying client. Safe to do while other goroutines use the client. - // This is a best effort: if other goroutine(s) are currently using the client, - // the related open connection(s) will remain open until the client is GC'ed - c.httpClient.CloseIdleConnections() - c.httpClient = c.httpClientFactory() -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/trace/config/config.go b/vendor/github.com/DataDog/datadog-agent/pkg/trace/config/config.go deleted file mode 100644 index 2ada0ea2..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/trace/config/config.go +++ /dev/null @@ -1,621 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package config - -import ( - "crypto/tls" - "errors" - "net" - "net/http" - "net/url" - "os" - "regexp" - "time" - - "github.com/DataDog/opentelemetry-mapping-go/pkg/otlp/attributes" - - "github.com/DataDog/datadog-agent/pkg/obfuscate" - "github.com/DataDog/datadog-agent/pkg/remoteconfig/state" - "github.com/DataDog/datadog-agent/pkg/trace/log" - "github.com/DataDog/datadog-agent/pkg/trace/traceutil" -) - -// ServiceName specifies the service name used in the operating system. -const ServiceName = "datadog-trace-agent" - -// ErrMissingAPIKey is returned when the config could not be validated due to missing API key. -var ErrMissingAPIKey = errors.New("you must specify an API Key, either via a configuration file or the DD_API_KEY env var") - -// Endpoint specifies an endpoint that the trace agent will write data (traces, stats & services) to. -type Endpoint struct { - APIKey string `json:"-"` // never marshal this - Host string - - // NoProxy will be set to true when the proxy setting for the trace API endpoint - // needs to be ignored (e.g. it is part of the "no_proxy" list in the yaml settings). - NoProxy bool -} - -// TelemetryEndpointPrefix specifies the prefix of the telemetry endpoint URL. -const TelemetryEndpointPrefix = "https://instrumentation-telemetry-intake." - -// OTLP holds the configuration for the OpenTelemetry receiver. -type OTLP struct { - // BindHost specifies the host to bind the receiver to. - BindHost string `mapstructure:"-"` - - // GRPCPort specifies the port to use for the plain HTTP receiver. - // If unset (or 0), the receiver will be off. - GRPCPort int `mapstructure:"grpc_port"` - - // SpanNameRemappings is the map of datadog span names and preferred name to map to. This can be used to - // automatically map Datadog Span Operation Names to an updated value. All entries should be key/value pairs. - SpanNameRemappings map[string]string `mapstructure:"span_name_remappings"` - - // SpanNameAsResourceName specifies whether the OpenTelemetry span's name should be - // used as the Datadog span's operation name. By default (when this is false), the - // operation name is deduced from a combination between the instrumentation scope - // name and the span kind. - // - // For context, the OpenTelemetry 'Span Name' is equivalent to the Datadog 'resource name'. - // The Datadog Span's Operation Name equivalent in OpenTelemetry does not exist, but the span's - // kind comes close. - SpanNameAsResourceName bool `mapstructure:"span_name_as_resource_name"` - - // MaxRequestBytes specifies the maximum number of bytes that will be read - // from an incoming HTTP request. - MaxRequestBytes int64 `mapstructure:"-"` - - // ProbabilisticSampling specifies the percentage of traces to ingest. Exceptions are made for errors - // and rare traces (outliers) if "RareSamplerEnabled" is true. Invalid values are equivalent to 100. - // If spans have the "sampling.priority" attribute set, probabilistic sampling is skipped and the user's - // decision is followed. - ProbabilisticSampling float64 - - // AttributesTranslator specifies an OTLP to Datadog attributes translator. - AttributesTranslator *attributes.Translator `mapstructure:"-"` -} - -// ObfuscationConfig holds the configuration for obfuscating sensitive data -// for various span types. -type ObfuscationConfig struct { - // ES holds the obfuscation configuration for ElasticSearch bodies. - ES obfuscate.JSONConfig `mapstructure:"elasticsearch"` - - // OpenSearch holds the obfuscation configuration for OpenSearch bodies. - OpenSearch obfuscate.JSONConfig `mapstructure:"opensearch"` - - // Mongo holds the obfuscation configuration for MongoDB queries. - Mongo obfuscate.JSONConfig `mapstructure:"mongodb"` - - // SQLExecPlan holds the obfuscation configuration for SQL Exec Plans. This is strictly for safety related obfuscation, - // not normalization. Normalization of exec plans is configured in SQLExecPlanNormalize. - SQLExecPlan obfuscate.JSONConfig `mapstructure:"sql_exec_plan"` - - // SQLExecPlanNormalize holds the normalization configuration for SQL Exec Plans. - SQLExecPlanNormalize obfuscate.JSONConfig `mapstructure:"sql_exec_plan_normalize"` - - // HTTP holds the obfuscation settings for HTTP URLs. - HTTP obfuscate.HTTPConfig `mapstructure:"http"` - - // RemoveStackTraces specifies whether stack traces should be removed. - // More specifically "error.stack" tag values will be cleared. - RemoveStackTraces bool `mapstructure:"remove_stack_traces"` - - // Redis holds the configuration for obfuscating the "redis.raw_command" tag - // for spans of type "redis". - Redis obfuscate.RedisConfig `mapstructure:"redis"` - - // Memcached holds the configuration for obfuscating the "memcached.command" tag - // for spans of type "memcached". - Memcached obfuscate.MemcachedConfig `mapstructure:"memcached"` - - // CreditCards holds the configuration for obfuscating credit cards. - CreditCards obfuscate.CreditCardsConfig `mapstructure:"credit_cards"` -} - -// Export returns an obfuscate.Config matching o. -func (o *ObfuscationConfig) Export(conf *AgentConfig) obfuscate.Config { - return obfuscate.Config{ - SQL: obfuscate.SQLConfig{ - TableNames: conf.HasFeature("table_names"), - ReplaceDigits: conf.HasFeature("quantize_sql_tables") || conf.HasFeature("replace_sql_digits"), - KeepSQLAlias: conf.HasFeature("keep_sql_alias"), - DollarQuotedFunc: conf.HasFeature("dollar_quoted_func"), - Cache: conf.HasFeature("sql_cache"), - }, - ES: o.ES, - OpenSearch: o.OpenSearch, - Mongo: o.Mongo, - SQLExecPlan: o.SQLExecPlan, - SQLExecPlanNormalize: o.SQLExecPlanNormalize, - HTTP: o.HTTP, - Redis: o.Redis, - Memcached: o.Memcached, - CreditCard: o.CreditCards, - Logger: new(debugLogger), - } -} - -type debugLogger struct{} - -func (debugLogger) Debugf(format string, params ...interface{}) { - log.Debugf(format, params...) -} - -// Enablable can represent any option that has an "enabled" boolean sub-field. -type Enablable struct { - Enabled bool `mapstructure:"enabled"` -} - -// TelemetryConfig holds Instrumentation telemetry Endpoints information -type TelemetryConfig struct { - Enabled bool `mapstructure:"enabled"` - Endpoints []*Endpoint -} - -// ReplaceRule specifies a replace rule. -type ReplaceRule struct { - // Name specifies the name of the tag that the replace rule addresses. However, - // some exceptions apply such as: - // • "resource.name" will target the resource - // • "*" will target all tags and the resource - Name string `mapstructure:"name"` - - // Pattern specifies the regexp pattern to be used when replacing. It must compile. - Pattern string `mapstructure:"pattern"` - - // Re holds the compiled Pattern and is only used internally. - Re *regexp.Regexp `mapstructure:"-"` - - // Repl specifies the replacement string to be used when Pattern matches. - Repl string `mapstructure:"repl"` -} - -// WriterConfig specifies configuration for an API writer. -type WriterConfig struct { - // ConnectionLimit specifies the maximum number of concurrent outgoing - // connections allowed for the sender. - ConnectionLimit int `mapstructure:"connection_limit"` - - // QueueSize specifies the maximum number or payloads allowed to be queued - // in the sender. - QueueSize int `mapstructure:"queue_size"` - - // FlushPeriodSeconds specifies the frequency at which the writer's buffer - // will be flushed to the sender, in seconds. Fractions are permitted. - FlushPeriodSeconds float64 `mapstructure:"flush_period_seconds"` -} - -// FargateOrchestratorName is a Fargate orchestrator name. -type FargateOrchestratorName string - -const ( - // OrchestratorECS represents AWS ECS - OrchestratorECS FargateOrchestratorName = "ECS" - // OrchestratorEKS represents AWS EKS - OrchestratorEKS FargateOrchestratorName = "EKS" - // OrchestratorUnknown is used when we cannot retrieve the orchestrator - OrchestratorUnknown FargateOrchestratorName = "Unknown" -) - -// ProfilingProxyConfig ... -type ProfilingProxyConfig struct { - // DDURL ... - DDURL string - // AdditionalEndpoints ... - AdditionalEndpoints map[string][]string -} - -// EVPProxy contains the settings for the EVPProxy proxy. -type EVPProxy struct { - // Enabled reports whether EVPProxy is enabled (true by default). - Enabled bool - // DDURL is the Datadog site to forward payloads to (defaults to the Site setting if not set). - DDURL string - // APIKey is the main API Key (defaults to the main API key). - APIKey string `json:"-"` // Never marshal this field - // ApplicationKey to be used for requests with the X-Datadog-NeedsAppKey set (defaults to the top-level Application Key). - ApplicationKey string `json:"-"` // Never marshal this field - // AdditionalEndpoints is a map of additional Datadog sites to API keys. - AdditionalEndpoints map[string][]string - // MaxPayloadSize indicates the size at which payloads will be rejected, in bytes. - MaxPayloadSize int64 - // ReceiverTimeout indicates the maximum time an EVPProxy request can take. Value in seconds. - ReceiverTimeout int -} - -// InstallSignatureConfig contains the information on how the agent was installed -// and a unique identifier that distinguishes this agent from others. -type InstallSignatureConfig struct { - Found bool `json:"-"` - InstallID string `json:"install_id"` - InstallType string `json:"install_type"` - InstallTime int64 `json:"install_time"` -} - -// DebuggerProxyConfig ... -type DebuggerProxyConfig struct { - // DDURL ... - DDURL string - // APIKey ... - APIKey string `json:"-"` // Never marshal this field - // AdditionalEndpoints is a map of additional Datadog sites to API keys. - AdditionalEndpoints map[string][]string `json:"-"` // Never marshal this field -} - -// SymDBProxyConfig ... -type SymDBProxyConfig struct { - // DDURL ... - DDURL string - // APIKey ... - APIKey string `json:"-"` // Never marshal this field - // AdditionalEndpoints is a map of additional Datadog endpoints to API keys. - AdditionalEndpoints map[string][]string `json:"-"` // Never marshal this field -} - -// AgentConfig handles the interpretation of the configuration (with default -// behaviors) in one place. It is also a simple structure to share across all -// the Agent components, with 100% safe and reliable values. -// It is exposed with expvar, so make sure to exclude any sensible field -// from JSON encoding. Use New() to create an instance. -type AgentConfig struct { - Features map[string]struct{} - - Enabled bool - AgentVersion string - GitCommit string - Site string // the intake site to use (e.g. "datadoghq.com") - - // FargateOrchestrator specifies the name of the Fargate orchestrator. e.g. "ECS", "EKS", "Unknown" - FargateOrchestrator FargateOrchestratorName - - // Global - Hostname string - DefaultEnv string // the traces will default to this environment - ConfigPath string // the source of this config, if any - - // Endpoints specifies the set of hosts and API keys where traces and stats - // will be uploaded to. The first endpoint is the main configuration endpoint; - // any following ones are read from the 'additional_endpoints' parts of the - // configuration file, if present. - Endpoints []*Endpoint - - // Concentrator - BucketInterval time.Duration // the size of our pre-aggregation per bucket - ExtraAggregators []string // DEPRECATED - PeerTagsAggregation bool // enables/disables stats aggregation for peer entity tags, used by Concentrator and ClientStatsAggregator - ComputeStatsBySpanKind bool // enables/disables the computing of stats based on a span's `span.kind` field - PeerTags []string // additional tags to use for peer entity stats aggregation - - // Sampler configuration - ExtraSampleRate float64 - TargetTPS float64 - ErrorTPS float64 - MaxEPS float64 - MaxRemoteTPS float64 - - // Rare Sampler configuration - RareSamplerEnabled bool - RareSamplerTPS int - RareSamplerCooldownPeriod time.Duration - RareSamplerCardinality int - - // Probabilistic Sampler configuration - ProbabilisticSamplerEnabled bool - ProbabilisticSamplerHashSeed uint32 - ProbabilisticSamplerSamplingPercentage float32 - - // Receiver - ReceiverEnabled bool // specifies whether Receiver listeners are enabled. Unless OTLPReceiver is used, this should always be true. - ReceiverHost string - ReceiverPort int - ReceiverSocket string // if not empty, UDS will be enabled on unix:// - ConnectionLimit int // for rate-limiting, how many unique connections to allow in a lease period (30s) - ReceiverTimeout int - MaxRequestBytes int64 // specifies the maximum allowed request size for incoming trace payloads - TraceBuffer int // specifies the number of traces to buffer before blocking. - Decoders int // specifies the number of traces that can be concurrently decoded. - MaxConnections int // specifies the maximum number of concurrent incoming connections allowed. - DecoderTimeout int // specifies the maximum time in milliseconds that the decoders will wait for a turn to accept a payload before returning 429 - - WindowsPipeName string - PipeBufferSize int - PipeSecurityDescriptor string - - GUIPort string // the port of the Datadog Agent GUI (for control access) - - // Writers - SynchronousFlushing bool // Mode where traces are only submitted when FlushAsync is called, used for Serverless Extension - StatsWriter *WriterConfig - TraceWriter *WriterConfig - ConnectionResetInterval time.Duration // frequency at which outgoing connections are reset. 0 means no reset is performed - // MaxSenderRetries is the maximum number of retries that a sender will perform - // before giving up. Note that the sender may not perform all MaxSenderRetries if - // the agent is under load and the outgoing payload queue is full. In that - // case, the sender will drop failed payloads when it is unable to enqueue - // them for another retry. - MaxSenderRetries int - // HTTP client used in writer connections. If nil, default client values will be used. - HTTPClientFunc func() *http.Client `json:"-"` - - // internal telemetry - StatsdEnabled bool - StatsdHost string - StatsdPort int - StatsdPipeName string // for Windows Pipes - StatsdSocket string // for UDS Sockets - - // logging - LogFilePath string - - // watchdog - MaxMemory float64 // MaxMemory is the threshold (bytes allocated) above which program panics and exits, to be restarted - MaxCPU float64 // MaxCPU is the max UserAvg CPU the program should consume - WatchdogInterval time.Duration // WatchdogInterval is the delay between 2 watchdog checks - - // http/s proxying - ProxyURL *url.URL - SkipSSLValidation bool - - // filtering - Ignore map[string][]string - - // ReplaceTags is used to filter out sensitive information from tag values. - // It maps tag keys to a set of replacements. Only supported in A6. - ReplaceTags []*ReplaceRule - - // GlobalTags list metadata that will be added to all spans - GlobalTags map[string]string - - // transaction analytics - AnalyzedRateByServiceLegacy map[string]float64 - AnalyzedSpansByService map[string]map[string]float64 - - // infrastructure agent binary - DDAgentBin string - - // Obfuscation holds sensitive data obufscator's configuration. - Obfuscation *ObfuscationConfig - - // MaxResourceLen the maximum length the resource can have - MaxResourceLen int - - // RequireTags specifies a list of tags which must be present on the root span in order for a trace to be accepted. - RequireTags []*Tag - - // RejectTags specifies a list of tags which must be absent on the root span in order for a trace to be accepted. - RejectTags []*Tag - - // RequireTagsRegex specifies a list of regexp for tags which must be present on the root span in order for a trace to be accepted. - RequireTagsRegex []*TagRegex - - // RejectTagsRegex specifies a list of regexp for tags which must be absent on the root span in order for a trace to be accepted. - RejectTagsRegex []*TagRegex - - // OTLPReceiver holds the configuration for OpenTelemetry receiver. - OTLPReceiver *OTLP - - // ProfilingProxy specifies settings for the profiling proxy. - ProfilingProxy ProfilingProxyConfig - - // Telemetry settings - TelemetryConfig *TelemetryConfig - - // EVPProxy contains the settings for the EVPProxy proxy. - EVPProxy EVPProxy - - // DebuggerProxy contains the settings for the Live Debugger proxy. - DebuggerProxy DebuggerProxyConfig - - // DebuggerDiagnosticsProxy contains the settings for the Live Debugger diagnostics proxy. - DebuggerDiagnosticsProxy DebuggerProxyConfig - - // SymDBProxy contains the settings for the Symbol Database proxy. - SymDBProxy SymDBProxyConfig - - // Proxy specifies a function to return a proxy for a given Request. - // See (net/http.Transport).Proxy for more details. - Proxy func(*http.Request) (*url.URL, error) `json:"-"` - - // MaxCatalogEntries specifies the maximum number of services to be added to the priority sampler's - // catalog. If not set (0) it will default to 5000. - MaxCatalogEntries int - - // RemoteConfigClient retrieves sampling updates from the remote config backend - RemoteConfigClient RemoteClient `json:"-"` - - // ContainerTags ... - ContainerTags func(cid string) ([]string, error) `json:"-"` - - // ContainerProcRoot is the root dir for `proc` info - ContainerProcRoot string - - // DebugServerPort defines the port used by the debug server - DebugServerPort int - - // Install Signature - InstallSignature InstallSignatureConfig - - // Lambda function name - LambdaFunctionName string -} - -// RemoteClient client is used to APM Sampling Updates from a remote source. -// This is an interface around the client provided by pkg/config/remote to allow for easier testing. -type RemoteClient interface { - Close() - Start() - Subscribe(string, func(update map[string]state.RawConfig, applyStateCallback func(string, state.ApplyStatus))) - UpdateApplyStatus(cfgPath string, status state.ApplyStatus) -} - -// Tag represents a key/value pair. -type Tag struct { - K, V string -} - -// TagRegex represents a key/value regex pattern pair. -type TagRegex struct { - K string - V *regexp.Regexp -} - -// New returns a configuration with the default values. -func New() *AgentConfig { - return &AgentConfig{ - Enabled: true, - DefaultEnv: "none", - Endpoints: []*Endpoint{{Host: "https://trace.agent.datadoghq.com"}}, - FargateOrchestrator: OrchestratorUnknown, - Site: "datadoghq.com", - MaxCatalogEntries: 5000, - - BucketInterval: time.Duration(10) * time.Second, - - ExtraSampleRate: 1.0, - TargetTPS: 10, - ErrorTPS: 10, - MaxEPS: 200, - MaxRemoteTPS: 100, - - RareSamplerEnabled: false, - RareSamplerTPS: 5, - RareSamplerCooldownPeriod: 5 * time.Minute, - RareSamplerCardinality: 200, - - ReceiverEnabled: true, - ReceiverHost: "localhost", - ReceiverPort: 8126, - MaxRequestBytes: 25 * 1024 * 1024, // 25MB - PipeBufferSize: 1_000_000, - PipeSecurityDescriptor: "D:AI(A;;GA;;;WD)", - GUIPort: "5002", - - StatsWriter: new(WriterConfig), - TraceWriter: new(WriterConfig), - ConnectionResetInterval: 0, // disabled - MaxSenderRetries: 4, - - StatsdHost: "localhost", - StatsdPort: 8125, - StatsdEnabled: true, - - LambdaFunctionName: os.Getenv("AWS_LAMBDA_FUNCTION_NAME"), - - MaxMemory: 5e8, // 500 Mb, should rarely go above 50 Mb - MaxCPU: 0.5, // 50%, well behaving agents keep below 5% - WatchdogInterval: 10 * time.Second, - - Ignore: make(map[string][]string), - AnalyzedRateByServiceLegacy: make(map[string]float64), - AnalyzedSpansByService: make(map[string]map[string]float64), - Obfuscation: &ObfuscationConfig{}, - MaxResourceLen: 5000, - - GlobalTags: computeGlobalTags(), - - Proxy: http.ProxyFromEnvironment, - OTLPReceiver: &OTLP{}, - ContainerTags: noopContainerTagsFunc, - TelemetryConfig: &TelemetryConfig{ - Endpoints: []*Endpoint{{Host: TelemetryEndpointPrefix + "datadoghq.com"}}, - }, - EVPProxy: EVPProxy{ - Enabled: true, - MaxPayloadSize: 5 * 1024 * 1024, - }, - - Features: make(map[string]struct{}), - } -} - -func computeGlobalTags() map[string]string { - if inAzureAppServices() { - return traceutil.GetAppServicesTags() - } - return make(map[string]string) -} - -// ErrContainerTagsFuncNotDefined is returned when the containerTags function is not defined. -var ErrContainerTagsFuncNotDefined = errors.New("containerTags function not defined") - -func noopContainerTagsFunc(_ string) ([]string, error) { - return nil, ErrContainerTagsFuncNotDefined -} - -// APIKey returns the first (main) endpoint's API key. -func (c *AgentConfig) APIKey() string { - if len(c.Endpoints) == 0 { - return "" - } - return c.Endpoints[0].APIKey -} - -// NewHTTPClient returns a new http.Client to be used for outgoing connections to the -// Datadog API. -func (c *AgentConfig) NewHTTPClient() *ResetClient { - // If a custom HTTPClientFunc been set, use it. Otherwise use default client values - if c.HTTPClientFunc != nil { - return NewResetClient(c.ConnectionResetInterval, c.HTTPClientFunc) - } - return NewResetClient(c.ConnectionResetInterval, func() *http.Client { - return &http.Client{ - Timeout: 10 * time.Second, - Transport: c.NewHTTPTransport(), - } - }) -} - -// NewHTTPTransport returns a new http.Transport to be used for outgoing connections to -// the Datadog API. -func (c *AgentConfig) NewHTTPTransport() *http.Transport { - transport := &http.Transport{ - TLSClientConfig: &tls.Config{InsecureSkipVerify: c.SkipSSLValidation}, - // below field values are from http.DefaultTransport (go1.12) - Proxy: c.Proxy, - DialContext: (&net.Dialer{ - Timeout: 30 * time.Second, - KeepAlive: 30 * time.Second, - DualStack: true, - }).DialContext, - MaxIdleConns: 100, - IdleConnTimeout: 30 * time.Second, - TLSHandshakeTimeout: 10 * time.Second, - ExpectContinueTimeout: 1 * time.Second, - } - return transport -} - -// HasFeature returns true if the agent has the given feature flag. -func (c *AgentConfig) HasFeature(feat string) bool { - _, ok := c.Features[feat] - return ok -} - -// AllFeatures returns a slice of all the feature flags the agent has. -func (c *AgentConfig) AllFeatures() []string { - feats := []string{} - for feat := range c.Features { - feats = append(feats, feat) - } - return feats -} - -// ConfiguredPeerTags returns the set of peer tags that should be used -// for aggregation based on the various config values and the base set of tags. -func (c *AgentConfig) ConfiguredPeerTags() []string { - if !c.PeerTagsAggregation { - return nil - } - return preparePeerTags(append(basePeerTags, c.PeerTags...)) -} - -func inAzureAppServices() bool { - _, existsLinux := os.LookupEnv("WEBSITE_STACK") - _, existsWin := os.LookupEnv("WEBSITE_APPSERVICEAPPLOGS_TRACE_ENABLED") - return existsLinux || existsWin -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/trace/config/peer_tags.go b/vendor/github.com/DataDog/datadog-agent/pkg/trace/config/peer_tags.go deleted file mode 100644 index 6b2a58c9..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/trace/config/peer_tags.go +++ /dev/null @@ -1,55 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package config - -import ( - _ "embed" //nolint:revive - "sort" - "strings" - - "github.com/DataDog/datadog-agent/pkg/util/log" - "gopkg.in/ini.v1" -) - -//go:embed peer_tags.ini -var peerTagFile []byte - -// basePeerTags is the base set of peer tag precursors (tags from which peer tags -// are derived) we aggregate on when peer tag aggregation is enabled. -var basePeerTags = func() []string { - var precursors []string = []string{"_dd.base_service"} - - cfg, err := ini.Load(peerTagFile) - if err != nil { - log.Error("Error loading file for peer tags: ", err) - return precursors - } - peerTags := cfg.Section("dd.apm.peer.tags").Keys() - - for _, t := range peerTags { - ps := strings.Split(t.Value(), ",") - precursors = append(precursors, ps...) - } - sort.Strings(precursors) - - return precursors -}() - -func preparePeerTags(tags []string) []string { - if len(tags) == 0 { - return nil - } - var deduped []string - seen := make(map[string]struct{}) - for _, t := range tags { - if _, ok := seen[t]; !ok { - seen[t] = struct{}{} - deduped = append(deduped, t) - } - } - sort.Strings(deduped) - return deduped -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/trace/config/peer_tags.ini b/vendor/github.com/DataDog/datadog-agent/pkg/trace/config/peer_tags.ini deleted file mode 100644 index 34badd12..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/trace/config/peer_tags.ini +++ /dev/null @@ -1,18 +0,0 @@ -# Generated - DO NOT EDIT -# Source: https://github.com/DataDog/semantic-core/ -[dd.apm.peer.tags] -peer.aws.dynamodb.table = "tablename" -peer.aws.kinesis.stream = "streamname" -peer.aws.s3.bucket = "bucketname,aws.s3.bucket" -peer.aws.sqs.queue = "queuename" -peer.cassandra.contact.points = "db.cassandra.contact.points" -peer.couchbase.seed.nodes = "db.couchbase.seed.nodes" -peer.db.name = "db.name,mongodb.db,db.instance,cassandra.keyspace,db.namespace" -peer.db.system = "db.system" -peer.hostname = "peer.hostname,hostname,net.peer.name,db.hostname,network.destination.name,grpc.host,http.host,server.address,http.server_name,out.host,dns.hostname" -peer.kafka.bootstrap.servers = "messaging.kafka.bootstrap.servers" -peer.messaging.destination = "topicname,messaging.destination,messaging.destination.name,messaging.rabbitmq.exchange,amqp.destination,amqp.queue,amqp.exchange,msmq.queue.path,aws.queue.name" -peer.messaging.system = "messaging.system" -peer.rpc.service = "rpc.service" -peer.rpc.system = "rpc.system" -peer.service = "peer.service" diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/trace/log/buflogger.go b/vendor/github.com/DataDog/datadog-agent/pkg/trace/log/buflogger.go deleted file mode 100644 index 90672147..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/trace/log/buflogger.go +++ /dev/null @@ -1,97 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -//go:build test - -package log - -import ( - "bytes" - "fmt" - "sync" -) - -var _ Logger = (*buflogger)(nil) - -// NewBufferLogger creates a new Logger which outputs everything to the given buffer. -// It is synchronised for concurrent use; as such, it is not optimal for use outside -// testing environments. -func NewBufferLogger(out *bytes.Buffer) Logger { - return &buflogger{buf: out} -} - -type buflogger struct { - mu sync.Mutex - buf *bytes.Buffer -} - -func (b *buflogger) logWithLevel(lvl string, msg string) { - b.mu.Lock() - defer b.mu.Unlock() - b.buf.WriteString(fmt.Sprintf("[%s] %s", lvl, msg)) -} - -// Trace implements Logger. -func (b *buflogger) Trace(v ...interface{}) { b.logWithLevel("TRACE", fmt.Sprint(v...)) } - -// Tracef implements Logger. -func (b *buflogger) Tracef(format string, params ...interface{}) { - b.logWithLevel("TRACE", fmt.Sprintf(format, params...)) -} - -// Debug implements Logger. -func (b *buflogger) Debug(v ...interface{}) { b.logWithLevel("DEBUG", fmt.Sprint(v...)) } - -// Debugf implements Logger. -func (b *buflogger) Debugf(format string, params ...interface{}) { - b.logWithLevel("DEBUG", fmt.Sprintf(format, params...)) -} - -// Info implements Logger. -func (b *buflogger) Info(v ...interface{}) { b.logWithLevel("INFO", fmt.Sprint(v...)) } - -// Infof implements Logger. -func (b *buflogger) Infof(format string, params ...interface{}) { - b.logWithLevel("INFO", fmt.Sprintf(format, params...)) -} - -// Warn implements Logger. -func (b *buflogger) Warn(v ...interface{}) error { - b.logWithLevel("WARN", fmt.Sprint(v...)) - return nil -} - -// Warnf implements Logger. -func (b *buflogger) Warnf(format string, params ...interface{}) error { - b.logWithLevel("WARN", fmt.Sprintf(format, params...)) - return nil -} - -// Error implements Logger. -func (b *buflogger) Error(v ...interface{}) error { - b.logWithLevel("ERROR", fmt.Sprint(v...)) - return nil -} - -// Errorf implements Logger. -func (b *buflogger) Errorf(format string, params ...interface{}) error { - b.logWithLevel("ERROR", fmt.Sprintf(format, params...)) - return nil -} - -// Critical implements Logger. -func (b *buflogger) Critical(v ...interface{}) error { - b.logWithLevel("CRITICAL", fmt.Sprint(v...)) - return nil -} - -// Criticalf implements Logger. -func (b *buflogger) Criticalf(format string, params ...interface{}) error { - b.logWithLevel("CRITICAL", fmt.Sprintf(format, params...)) - return nil -} - -// Flush implements Logger. -func (b *buflogger) Flush() {} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/trace/log/logger.go b/vendor/github.com/DataDog/datadog-agent/pkg/trace/log/logger.go deleted file mode 100644 index 552eeaa0..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/trace/log/logger.go +++ /dev/null @@ -1,196 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -// Package log implements the trace-agent logger. -package log - -import ( - "sync" -) - -var ( - mu sync.RWMutex - logger Logger = NoopLogger -) - -// SetLogger sets l as the default Logger and returns the old logger. -func SetLogger(l Logger) Logger { - mu.Lock() - oldlogger := logger - logger = l - mu.Unlock() - return oldlogger -} - -// IsSet returns whether the logger has been set up. -func IsSet() bool { - mu.Lock() - defer mu.Unlock() - return logger != NoopLogger -} - -// Logger implements the core logger interface. -type Logger interface { - Trace(v ...interface{}) - Tracef(format string, params ...interface{}) - Debug(v ...interface{}) - Debugf(format string, params ...interface{}) - Info(v ...interface{}) - Infof(format string, params ...interface{}) - Warn(v ...interface{}) error - Warnf(format string, params ...interface{}) error - Error(v ...interface{}) error - Errorf(format string, params ...interface{}) error - Critical(v ...interface{}) error - Criticalf(format string, params ...interface{}) error - Flush() -} - -// Trace formats message using the default formats for its operands -// and writes to log with level = Trace -func Trace(v ...interface{}) { - mu.RLock() - logger.Trace(v...) - mu.RUnlock() -} - -// Tracef formats message according to format specifier -// and writes to log with level = Trace. -func Tracef(format string, params ...interface{}) { - mu.RLock() - logger.Tracef(format, params...) - mu.RUnlock() -} - -// Debug formats message using the default formats for its operands -// and writes to log with level = Debug -func Debug(v ...interface{}) { - mu.RLock() - logger.Debug(v...) - mu.RUnlock() -} - -// Debugf formats message according to format specifier -// and writes to log with level = Debug. -func Debugf(format string, params ...interface{}) { - mu.RLock() - logger.Debugf(format, params...) - mu.RUnlock() -} - -// Info formats message using the default formats for its operands -// and writes to log with level = Info -func Info(v ...interface{}) { - mu.RLock() - logger.Info(v...) - mu.RUnlock() -} - -// Infof formats message according to format specifier -// and writes to log with level = Info. -func Infof(format string, params ...interface{}) { - mu.RLock() - logger.Infof(format, params...) - mu.RUnlock() -} - -// Warn formats message using the default formats for its operands -// and writes to log with level = Warn -func Warn(v ...interface{}) { - mu.RLock() - logger.Warn(v...) //nolint:errcheck - mu.RUnlock() -} - -// Warnf formats message according to format specifier -// and writes to log with level = Warn. -func Warnf(format string, params ...interface{}) { - mu.RLock() - logger.Warnf(format, params...) //nolint:errcheck - mu.RUnlock() -} - -// Error formats message using the default formats for its operands -// and writes to log with level = Error -func Error(v ...interface{}) { - mu.RLock() - logger.Error(v...) //nolint:errcheck - mu.RUnlock() -} - -// Errorf formats message according to format specifier -// and writes to log with level = Error. -func Errorf(format string, params ...interface{}) { - mu.RLock() - logger.Errorf(format, params...) //nolint:errcheck - mu.RUnlock() -} - -// Critical formats message using the default formats for its operands -// and writes to log with level = Critical -func Critical(v ...interface{}) { - mu.RLock() - logger.Critical(v...) //nolint:errcheck - mu.RUnlock() -} - -// Criticalf formats message according to format specifier -// and writes to log with level = Critical. -func Criticalf(format string, params ...interface{}) { - mu.RLock() - logger.Criticalf(format, params...) //nolint:errcheck - mu.RUnlock() -} - -// Flush flushes all the messages in the logger. -func Flush() { - mu.RLock() - logger.Flush() - mu.RUnlock() -} - -// NoopLogger is a logger which has no effect upon calling. -var NoopLogger = noopLogger{} - -type noopLogger struct{} - -// Trace implements Logger. -func (noopLogger) Trace(_ ...interface{}) {} - -// Tracef implements Logger. -func (noopLogger) Tracef(_ string, _ ...interface{}) {} - -// Debug implements Logger. -func (noopLogger) Debug(_ ...interface{}) {} - -// Debugf implements Logger. -func (noopLogger) Debugf(_ string, _ ...interface{}) {} - -// Info implements Logger. -func (noopLogger) Info(_ ...interface{}) {} - -// Infof implements Logger. -func (noopLogger) Infof(_ string, _ ...interface{}) {} - -// Warn implements Logger. -func (noopLogger) Warn(_ ...interface{}) error { return nil } - -// Warnf implements Logger. -func (noopLogger) Warnf(_ string, _ ...interface{}) error { return nil } - -// Error implements Logger. -func (noopLogger) Error(_ ...interface{}) error { return nil } - -// Errorf implements Logger. -func (noopLogger) Errorf(_ string, _ ...interface{}) error { return nil } - -// Critical implements Logger. -func (noopLogger) Critical(_ ...interface{}) error { return nil } - -// Criticalf implements Logger. -func (noopLogger) Criticalf(_ string, _ ...interface{}) error { return nil } - -// Flush implements Logger. -func (noopLogger) Flush() {} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/trace/log/throttled.go b/vendor/github.com/DataDog/datadog-agent/pkg/trace/log/throttled.go deleted file mode 100644 index 3b81cee4..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/trace/log/throttled.go +++ /dev/null @@ -1,63 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package log - -import ( - "time" - - "go.uber.org/atomic" -) - -// NewThrottled returns a new throttled logger. The returned logger will allow up to n calls in -// a time period of length d. -func NewThrottled(n int, d time.Duration) *ThrottledLogger { - return &ThrottledLogger{ - n: uint64(n), - c: atomic.NewUint64(0), - d: d, - } -} - -// ThrottledLogger limits the number of log calls during a time window. To create a new logger -// use NewThrottled. -type ThrottledLogger struct { - n uint64 // number of log calls allowed during interval d - c *atomic.Uint64 // number of log calls performed during an interval d - d time.Duration -} - -type loggerFunc func(format string, params ...interface{}) - -func (tl *ThrottledLogger) log(logFunc loggerFunc, format string, params ...interface{}) { - c := tl.c.Inc() - 1 - if c == 0 { - // first call, trigger the reset - time.AfterFunc(tl.d, func() { tl.c.Store(0) }) - } - if c >= tl.n { - if c == tl.n { - logFunc("Too many similar messages, pausing up to %s...", tl.d) - } - return - } - logFunc(format, params...) -} - -// Error logs the message at the error level. -func (tl *ThrottledLogger) Error(format string, params ...interface{}) { - tl.log(Errorf, format, params...) -} - -// Warn logs the message at the warning level. -func (tl *ThrottledLogger) Warn(format string, params ...interface{}) { - tl.log(Warnf, format, params...) -} - -// Write implements io.Writer. -func (tl *ThrottledLogger) Write(p []byte) (n int, err error) { - tl.Error(string(p)) - return len(p), nil -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/trace/stats/aggregation.go b/vendor/github.com/DataDog/datadog-agent/pkg/trace/stats/aggregation.go deleted file mode 100644 index fcaf5017..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/trace/stats/aggregation.go +++ /dev/null @@ -1,130 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -// Package stats contains the logic to process APM stats. -package stats - -import ( - "hash/fnv" - "sort" - "strconv" - "strings" - - pb "github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace" - "github.com/DataDog/datadog-agent/pkg/trace/log" -) - -const ( - tagStatusCode = "http.status_code" - tagSynthetics = "synthetics" - tagSpanKind = "span.kind" - tagBaseService = "_dd.base_service" -) - -// Aggregation contains all the dimension on which we aggregate statistics. -type Aggregation struct { - BucketsAggregationKey - PayloadAggregationKey -} - -// BucketsAggregationKey specifies the key by which a bucket is aggregated. -type BucketsAggregationKey struct { - Service string - Name string - Resource string - Type string - SpanKind string - StatusCode uint32 - Synthetics bool - PeerTagsHash uint64 - IsTraceRoot pb.Trilean -} - -// PayloadAggregationKey specifies the key by which a payload is aggregated. -type PayloadAggregationKey struct { - Env string - Hostname string - Version string - ContainerID string - GitCommitSha string - ImageTag string -} - -func getStatusCode(meta map[string]string, metrics map[string]float64) uint32 { - code, ok := metrics[tagStatusCode] - if ok { - // only 7.39.0+, for lesser versions, always use Meta - return uint32(code) - } - strC := meta[tagStatusCode] - if strC == "" { - return 0 - } - c, err := strconv.ParseUint(strC, 10, 32) - if err != nil { - log.Debugf("Invalid status code %s. Using 0.", strC) - return 0 - } - return uint32(c) -} - -// NewAggregationFromSpan creates a new aggregation from the provided span and env -func NewAggregationFromSpan(s *StatSpan, origin string, aggKey PayloadAggregationKey) Aggregation { - synthetics := strings.HasPrefix(origin, tagSynthetics) - var isTraceRoot pb.Trilean - if s.parentID == 0 { - isTraceRoot = pb.Trilean_TRUE - } else { - isTraceRoot = pb.Trilean_FALSE - } - agg := Aggregation{ - PayloadAggregationKey: aggKey, - BucketsAggregationKey: BucketsAggregationKey{ - Resource: s.resource, - Service: s.service, - Name: s.name, - SpanKind: s.spanKind, - Type: s.typ, - StatusCode: s.statusCode, - Synthetics: synthetics, - IsTraceRoot: isTraceRoot, - PeerTagsHash: peerTagsHash(s.matchingPeerTags), - }, - } - return agg -} - -func peerTagsHash(tags []string) uint64 { - if len(tags) == 0 { - return 0 - } - if !sort.StringsAreSorted(tags) { - sort.Strings(tags) - } - h := fnv.New64a() - for i, t := range tags { - if i > 0 { - h.Write([]byte{0}) - } - h.Write([]byte(t)) - } - return h.Sum64() -} - -// NewAggregationFromGroup gets the Aggregation key of grouped stats. -func NewAggregationFromGroup(g *pb.ClientGroupedStats) Aggregation { - return Aggregation{ - BucketsAggregationKey: BucketsAggregationKey{ - Resource: g.Resource, - Service: g.Service, - Name: g.Name, - SpanKind: g.SpanKind, - StatusCode: g.HTTPStatusCode, - Synthetics: g.Synthetics, - PeerTagsHash: peerTagsHash(g.PeerTags), - IsTraceRoot: g.IsTraceRoot, - }, - } -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/trace/stats/client_stats_aggregator.go b/vendor/github.com/DataDog/datadog-agent/pkg/trace/stats/client_stats_aggregator.go deleted file mode 100644 index 0c3e8fef..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/trace/stats/client_stats_aggregator.go +++ /dev/null @@ -1,438 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package stats - -import ( - "time" - - "github.com/DataDog/datadog-agent/pkg/trace/version" - "github.com/DataDog/sketches-go/ddsketch" - "github.com/DataDog/sketches-go/ddsketch/mapping" - "github.com/DataDog/sketches-go/ddsketch/pb/sketchpb" - "github.com/DataDog/sketches-go/ddsketch/store" - - pb "github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace" - "github.com/DataDog/datadog-agent/pkg/trace/config" - "github.com/DataDog/datadog-agent/pkg/trace/log" - "github.com/DataDog/datadog-agent/pkg/trace/watchdog" - - "github.com/DataDog/datadog-go/v5/statsd" - - "google.golang.org/protobuf/proto" -) - -const ( - bucketDuration = 2 * time.Second - clientBucketDuration = 10 * time.Second - oldestBucketStart = 20 * time.Second -) - -var ( - ddsketchMapping, _ = mapping.NewLogarithmicMapping(relativeAccuracy) -) - -// ClientStatsAggregator aggregates client stats payloads on buckets of bucketDuration -// If a single payload is received on a bucket, this Aggregator is a passthrough. -// If two or more payloads collide, their counts will be aggregated into one bucket. -// Multiple payloads will be sent: -// - Original payloads with their distributions will be sent with counts zeroed. -// - A single payload with the bucket aggregated counts will be sent. -// This and the aggregator timestamp alignment ensure that all counts will have at most one point per second per agent for a specific granularity. -// While distributions are not tied to the agent. -type ClientStatsAggregator struct { - In chan *pb.ClientStatsPayload - writer Writer - buckets map[int64]*bucket // buckets used to aggregate client stats - conf *config.AgentConfig - - flushTicker *time.Ticker - oldestTs time.Time - agentEnv string - agentHostname string - agentVersion string - - exit chan struct{} - done chan struct{} - - statsd statsd.ClientInterface -} - -// NewClientStatsAggregator initializes a new aggregator ready to be started -func NewClientStatsAggregator(conf *config.AgentConfig, writer Writer, statsd statsd.ClientInterface) *ClientStatsAggregator { - c := &ClientStatsAggregator{ - flushTicker: time.NewTicker(time.Second), - In: make(chan *pb.ClientStatsPayload, 10), - buckets: make(map[int64]*bucket, 20), - conf: conf, - writer: writer, - agentEnv: conf.DefaultEnv, - agentHostname: conf.Hostname, - agentVersion: conf.AgentVersion, - oldestTs: alignAggTs(time.Now().Add(bucketDuration - oldestBucketStart)), - exit: make(chan struct{}), - done: make(chan struct{}), - statsd: statsd, - } - return c -} - -// Start starts the aggregator. -func (a *ClientStatsAggregator) Start() { - go func() { - defer watchdog.LogOnPanic(a.statsd) - for { - select { - case t := <-a.flushTicker.C: - a.flushOnTime(t) - case input := <-a.In: - a.add(time.Now(), input) - case <-a.exit: - a.flushAll() - close(a.done) - return - } - } - }() -} - -// Stop stops the aggregator. Calling Stop twice will panic. -func (a *ClientStatsAggregator) Stop() { - close(a.exit) - a.flushTicker.Stop() - <-a.done -} - -// flushOnTime flushes all buckets up to flushTs, except the last one. -func (a *ClientStatsAggregator) flushOnTime(now time.Time) { - flushTs := alignAggTs(now.Add(bucketDuration - oldestBucketStart)) - for t := a.oldestTs; t.Before(flushTs); t = t.Add(bucketDuration) { - if b, ok := a.buckets[t.Unix()]; ok { - a.flush(b.aggregationToPayloads()) - delete(a.buckets, t.Unix()) - } - } - a.oldestTs = flushTs -} - -func (a *ClientStatsAggregator) flushAll() { - for _, b := range a.buckets { - a.flush(b.aggregationToPayloads()) - } -} - -// getAggregationBucketTime returns unix time at which we aggregate the bucket. -// We timeshift payloads older than a.oldestTs to a.oldestTs. -// Payloads in the future are timeshifted to the latest bucket. -func (a *ClientStatsAggregator) getAggregationBucketTime(now, bs time.Time) time.Time { - if bs.Before(a.oldestTs) { - return a.oldestTs - } - if bs.After(now) { - return alignAggTs(now) - } - return alignAggTs(bs) -} - -// add takes a new ClientStatsPayload and aggregates its stats in the internal buckets. -func (a *ClientStatsAggregator) add(now time.Time, p *pb.ClientStatsPayload) { - // populate container tags data on the payload - a.setVersionDataFromContainerTags(p) - // compute the PayloadAggregationKey, common for all buckets within the payload - payloadAggKey := newPayloadAggregationKey(p.Env, p.Hostname, p.Version, p.ContainerID, p.GitCommitSha, p.ImageTag) - - for _, clientBucket := range p.Stats { - clientBucketStart := time.Unix(0, int64(clientBucket.Start)) - ts := a.getAggregationBucketTime(now, clientBucketStart) - b, ok := a.buckets[ts.Unix()] - if !ok { - b = &bucket{ - ts: ts, - agg: make(map[PayloadAggregationKey]map[BucketsAggregationKey]*aggregatedStats), - } - a.buckets[ts.Unix()] = b - } - b.aggregateStatsBucket(clientBucket, payloadAggKey) - } -} - -func (a *ClientStatsAggregator) flush(p []*pb.ClientStatsPayload) { - if len(p) == 0 { - return - } - - a.writer.Write(&pb.StatsPayload{ - Stats: p, - AgentEnv: a.agentEnv, - AgentHostname: a.agentHostname, - AgentVersion: a.agentVersion, - ClientComputed: true, - }) -} - -func (a *ClientStatsAggregator) setVersionDataFromContainerTags(p *pb.ClientStatsPayload) { - // No need to go any further if we already have the information in the payload. - if p.ImageTag != "" && p.GitCommitSha != "" { - return - } - if p.ContainerID != "" { - gitCommitSha, imageTag, err := version.GetVersionDataFromContainerTags(p.ContainerID, a.conf) - if err != nil { - log.Error("Client stats aggregator is unable to resolve container ID (%s) to container tags: %v", p.ContainerID, err) - } else { - // Only override if the payload's original values were empty strings. - if p.ImageTag == "" { - p.ImageTag = imageTag - } - if p.GitCommitSha == "" { - p.GitCommitSha = gitCommitSha - } - } - } -} - -// alignAggTs aligns time to the aggregator timestamps. -// Timestamps from the aggregator are never aligned with concentrator timestamps. -// This ensures that all counts sent by a same agent host are never on the same second. -// aggregator timestamps: 2ks+1s (1s, 3s, 5s, 7s, 9s, 11s) -// concentrator timestamps: 10ks (0s, 10s, 20s ..) -func alignAggTs(t time.Time) time.Time { - return t.Truncate(bucketDuration).Add(time.Second) -} - -type bucket struct { - // ts is the timestamp attached to the payload - ts time.Time - // agg contains the aggregated Hits/Errors/Duration counts - agg map[PayloadAggregationKey]map[BucketsAggregationKey]*aggregatedStats -} - -// aggregateStatsBucket takes a ClientStatsBucket and a PayloadAggregationKey, and aggregates all counts -// and distributions from the ClientGroupedStats inside the bucket. -func (b *bucket) aggregateStatsBucket(sb *pb.ClientStatsBucket, payloadAggKey PayloadAggregationKey) { - payloadAgg, ok := b.agg[payloadAggKey] - if !ok { - payloadAgg = make(map[BucketsAggregationKey]*aggregatedStats, len(sb.Stats)) - b.agg[payloadAggKey] = payloadAgg - } - for _, gs := range sb.Stats { - if gs == nil { - continue - } - aggKey := newBucketAggregationKey(gs) - agg, ok := payloadAgg[aggKey] - if !ok { - agg = &aggregatedStats{ - hits: gs.Hits, - topLevelHits: gs.TopLevelHits, - errors: gs.Errors, - duration: gs.Duration, - peerTags: gs.PeerTags, - okDistributionRaw: gs.OkSummary, // store encoded version only - errDistributionRaw: gs.ErrorSummary, // store encoded version only - } - payloadAgg[aggKey] = agg - continue - } - - // aggregate counts - agg.hits += gs.Hits - agg.topLevelHits += gs.TopLevelHits - agg.errors += gs.Errors - agg.duration += gs.Duration - - // Decode, if needed, the raw ddsketches from the first payload that reached the bucket - if agg.okDistributionRaw != nil { - sketch, err := decodeSketch(agg.okDistributionRaw) - if err != nil { - log.Error("Unable to decode OK distribution ddsketch: %v", err) - } else { - agg.okDistribution = normalizeSketch(sketch) - } - agg.okDistributionRaw = nil - } - if agg.errDistributionRaw != nil { - sketch, err := decodeSketch(agg.errDistributionRaw) - if err != nil { - log.Error("Unable to decode Error distribution ddsketch: %v", err) - } else { - agg.errDistribution = normalizeSketch(sketch) - } - agg.errDistributionRaw = nil - } - - // aggregate distributions - if sketch, err := mergeSketch(agg.okDistribution, gs.OkSummary); err == nil { - agg.okDistribution = sketch - } else { - log.Error("Unable to merge OK distribution ddsketch: %v", err) - } - - if sketch, err := mergeSketch(agg.errDistribution, gs.ErrorSummary); err == nil { - agg.errDistribution = sketch - } else { - log.Error("Unable to merge Error distribution ddsketch: %v", err) - } - } -} - -// aggregationToPayloads converts the contents of the bucket into ClientStatsPayloads -func (b *bucket) aggregationToPayloads() []*pb.ClientStatsPayload { - res := make([]*pb.ClientStatsPayload, 0, len(b.agg)) - for payloadKey, aggrStats := range b.agg { - groupedStats := make([]*pb.ClientGroupedStats, 0, len(aggrStats)) - for aggrKey, stats := range aggrStats { - gs, err := exporGroupedStats(aggrKey, stats) - if err != nil { - log.Errorf("Dropping stats bucket due to encoding error: %v.", err) - continue - } - groupedStats = append(groupedStats, gs) - } - clientBuckets := []*pb.ClientStatsBucket{ - { - Start: uint64(b.ts.UnixNano()), - Duration: uint64(clientBucketDuration.Nanoseconds()), - Stats: groupedStats, - }} - res = append(res, &pb.ClientStatsPayload{ - Hostname: payloadKey.Hostname, - Env: payloadKey.Env, - Version: payloadKey.Version, - ImageTag: payloadKey.ImageTag, - GitCommitSha: payloadKey.GitCommitSha, - Stats: clientBuckets, - }) - } - return res -} - -func exporGroupedStats(aggrKey BucketsAggregationKey, stats *aggregatedStats) (*pb.ClientGroupedStats, error) { - // if the raw sketches are still present (only one payload received), we use them directly. - // Otherwise the aggregated DDSketches are serialized. - okSummary := stats.okDistributionRaw - errSummary := stats.errDistributionRaw - - var err error - if stats.okDistribution != nil { - msg := stats.okDistribution.ToProto() - okSummary, err = proto.Marshal(msg) - if err != nil { - return &pb.ClientGroupedStats{}, err - } - } - if stats.errDistribution != nil { - msg := stats.errDistribution.ToProto() - errSummary, err = proto.Marshal(msg) - if err != nil { - return &pb.ClientGroupedStats{}, err - } - } - return &pb.ClientGroupedStats{ - Service: aggrKey.Service, - Name: aggrKey.Name, - SpanKind: aggrKey.SpanKind, - Resource: aggrKey.Resource, - HTTPStatusCode: aggrKey.StatusCode, - Type: aggrKey.Type, - Synthetics: aggrKey.Synthetics, - IsTraceRoot: aggrKey.IsTraceRoot, - PeerTags: stats.peerTags, - TopLevelHits: stats.topLevelHits, - Hits: stats.hits, - Errors: stats.errors, - Duration: stats.duration, - OkSummary: okSummary, - ErrorSummary: errSummary, - }, nil -} - -func newPayloadAggregationKey(env, hostname, version, cid string, gitCommitSha string, imageTag string) PayloadAggregationKey { - return PayloadAggregationKey{ - Env: env, - Hostname: hostname, - Version: version, - ContainerID: cid, - GitCommitSha: gitCommitSha, - ImageTag: imageTag, - } -} - -func newBucketAggregationKey(b *pb.ClientGroupedStats) BucketsAggregationKey { - k := BucketsAggregationKey{ - Service: b.Service, - Name: b.Name, - SpanKind: b.SpanKind, - Resource: b.Resource, - Type: b.Type, - Synthetics: b.Synthetics, - StatusCode: b.HTTPStatusCode, - IsTraceRoot: b.IsTraceRoot, - } - if tags := b.GetPeerTags(); len(tags) > 0 { - k.PeerTagsHash = peerTagsHash(tags) - } - return k -} - -// aggregatedStats holds aggregated counts and distributions -type aggregatedStats struct { - // aggregated counts - hits, topLevelHits, errors, duration uint64 - peerTags []string - - // aggregated DDSketches - okDistribution, errDistribution *ddsketch.DDSketch - - // raw (encoded) DDSketches. Only present if a single payload is received on the active bucket, - // allowing the bucket to not decode the sketch. If a second payload matches the bucket, - // sketches will be decoded and stored in the okDistribution and errDistribution fields. - okDistributionRaw, errDistributionRaw []byte -} - -// mergeSketch take an existing DDSketch, and merges a second one, decoding its contents -func mergeSketch(s1 *ddsketch.DDSketch, raw []byte) (*ddsketch.DDSketch, error) { - if raw == nil { - return s1, nil - } - - s2, err := decodeSketch(raw) - if err != nil { - return s1, err - } - s2 = normalizeSketch(s2) - - if s1 == nil { - return s2, nil - } - - if err = s1.MergeWith(s2); err != nil { - return nil, err - } - return s1, nil -} - -func normalizeSketch(s *ddsketch.DDSketch) *ddsketch.DDSketch { - if s.IndexMapping.Equals(ddsketchMapping) { - // already normalized - return s - } - - return s.ChangeMapping(ddsketchMapping, store.NewCollapsingLowestDenseStore(maxNumBins), store.NewCollapsingLowestDenseStore(maxNumBins), 1) -} - -func decodeSketch(data []byte) (*ddsketch.DDSketch, error) { - if len(data) == 0 { - return nil, nil - } - - var sketch sketchpb.DDSketch - err := proto.Unmarshal(data, &sketch) - if err != nil { - return nil, err - } - - return ddsketch.FromProto(&sketch) -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/trace/stats/concentrator.go b/vendor/github.com/DataDog/datadog-agent/pkg/trace/stats/concentrator.go deleted file mode 100644 index 1cb5a7b3..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/trace/stats/concentrator.go +++ /dev/null @@ -1,182 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package stats - -import ( - "sync" - "time" - - pb "github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace" - "github.com/DataDog/datadog-agent/pkg/trace/config" - "github.com/DataDog/datadog-agent/pkg/trace/log" - "github.com/DataDog/datadog-agent/pkg/trace/traceutil" - "github.com/DataDog/datadog-agent/pkg/trace/watchdog" - - "github.com/DataDog/datadog-go/v5/statsd" -) - -// defaultBufferLen represents the default buffer length; the number of bucket size -// units used by the concentrator. -const defaultBufferLen = 2 - -// Writer is an interface for something that can Write Stats Payloads -type Writer interface { - // Write this payload - Write(*pb.StatsPayload) -} - -// Concentrator produces time bucketed statistics from a stream of raw traces. -// https://en.wikipedia.org/wiki/Knelson_concentrator -// Gets an imperial shitton of traces, and outputs pre-computed data structures -// allowing to find the gold (stats) amongst the traces. -type Concentrator struct { - Writer Writer - - spanConcentrator *SpanConcentrator - // bucket duration in nanoseconds - bsize int64 - exit chan struct{} - exitWG sync.WaitGroup - agentEnv string - agentHostname string - agentVersion string - statsd statsd.ClientInterface - peerTagKeys []string -} - -// NewConcentrator initializes a new concentrator ready to be started -func NewConcentrator(conf *config.AgentConfig, writer Writer, now time.Time, statsd statsd.ClientInterface) *Concentrator { - bsize := conf.BucketInterval.Nanoseconds() - sc := NewSpanConcentrator(&SpanConcentratorConfig{ - ComputeStatsBySpanKind: conf.ComputeStatsBySpanKind, - BucketInterval: bsize, - }, now) - c := Concentrator{ - spanConcentrator: sc, - Writer: writer, - exit: make(chan struct{}), - agentEnv: conf.DefaultEnv, - agentHostname: conf.Hostname, - agentVersion: conf.AgentVersion, - statsd: statsd, - bsize: bsize, - peerTagKeys: conf.ConfiguredPeerTags(), - } - return &c -} - -// Start starts the concentrator. -func (c *Concentrator) Start() { - c.exitWG.Add(1) - go func() { - defer watchdog.LogOnPanic(c.statsd) - defer c.exitWG.Done() - c.Run() - }() -} - -// Run runs the main loop of the concentrator goroutine. Traces are received -// through `Add`, this loop only deals with flushing. -func (c *Concentrator) Run() { - // flush with the same period as stats buckets - flushTicker := time.NewTicker(time.Duration(c.bsize) * time.Nanosecond) - defer flushTicker.Stop() - - log.Debug("Starting concentrator") - - for { - select { - case <-flushTicker.C: - c.Writer.Write(c.Flush(false)) - case <-c.exit: - log.Info("Exiting concentrator, computing remaining stats") - c.Writer.Write(c.Flush(true)) - return - } - } -} - -// Stop stops the main Run loop. -func (c *Concentrator) Stop() { - close(c.exit) - c.exitWG.Wait() -} - -// Input specifies a set of traces originating from a certain payload. -type Input struct { - Traces []traceutil.ProcessedTrace - ContainerID string - ContainerTags []string -} - -// NewStatsInput allocates a stats input for an incoming trace payload -func NewStatsInput(numChunks int, containerID string, clientComputedStats bool, conf *config.AgentConfig) Input { - if clientComputedStats { - return Input{} - } - in := Input{Traces: make([]traceutil.ProcessedTrace, 0, numChunks)} - _, enabledCIDStats := conf.Features["enable_cid_stats"] - _, disabledCIDStats := conf.Features["disable_cid_stats"] - enableContainers := enabledCIDStats || (conf.FargateOrchestrator != config.OrchestratorUnknown) - if enableContainers && !disabledCIDStats { - // only allow the ContainerID stats dimension if we're in a Fargate instance or it's - // been explicitly enabled and it's not prohibited by the disable_cid_stats feature flag. - in.ContainerID = containerID - } - return in -} - -// Add applies the given input to the concentrator. -func (c *Concentrator) Add(t Input) { - for _, trace := range t.Traces { - c.addNow(&trace, t.ContainerID, t.ContainerTags) - } -} - -// addNow adds the given input into the concentrator. -// Callers must guard! -func (c *Concentrator) addNow(pt *traceutil.ProcessedTrace, containerID string, containerTags []string) { - hostname := pt.TracerHostname - if hostname == "" { - hostname = c.agentHostname - } - env := pt.TracerEnv - if env == "" { - env = c.agentEnv - } - weight := weight(pt.Root) - aggKey := PayloadAggregationKey{ - Env: env, - Hostname: hostname, - Version: pt.AppVersion, - ContainerID: containerID, - GitCommitSha: pt.GitCommitSha, - ImageTag: pt.ImageTag, - } - for _, s := range pt.TraceChunk.Spans { - statSpan, ok := c.spanConcentrator.NewStatSpanFromPB(s, c.peerTagKeys) - if ok { - c.spanConcentrator.addSpan(statSpan, aggKey, containerID, containerTags, pt.TraceChunk.Origin, weight) - } - } -} - -// Flush deletes and returns complete statistic buckets. -// The force boolean guarantees flushing all buckets if set to true. -func (c *Concentrator) Flush(force bool) *pb.StatsPayload { - return c.flushNow(time.Now().UnixNano(), force) -} - -func (c *Concentrator) flushNow(now int64, force bool) *pb.StatsPayload { - sb := c.spanConcentrator.Flush(now, force) - return &pb.StatsPayload{Stats: sb, AgentHostname: c.agentHostname, AgentEnv: c.agentEnv, AgentVersion: c.agentVersion} -} - -// alignTs returns the provided timestamp truncated to the bucket size. -// It gives us the start time of the time bucket in which such timestamp falls. -func alignTs(ts int64, bsize int64) int64 { - return ts - ts%bsize -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/trace/stats/otel_util.go b/vendor/github.com/DataDog/datadog-agent/pkg/trace/stats/otel_util.go deleted file mode 100644 index 1c72b6fa..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/trace/stats/otel_util.go +++ /dev/null @@ -1,149 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package stats - -import ( - "slices" - - "go.opentelemetry.io/collector/pdata/pcommon" - "go.opentelemetry.io/collector/pdata/ptrace" - semconv "go.opentelemetry.io/collector/semconv/v1.17.0" - - pb "github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace" - "github.com/DataDog/datadog-agent/pkg/trace/config" - "github.com/DataDog/datadog-agent/pkg/trace/traceutil" -) - -// chunkKey is used to group TraceChunks -type chunkKey struct { - traceIDUInt64 uint64 - env string - version string - hostname string - cid string -} - -// OTLPTracesToConcentratorInputs converts eligible OTLP spans to Concentrator.Input. -// The converted Inputs only have the minimal number of fields for APM stats calculation and are only meant -// to be used in Concentrator.Add(). Do not use them for other purposes. -func OTLPTracesToConcentratorInputs( - traces ptrace.Traces, - conf *config.AgentConfig, - containerTagKeys []string, - peerTagKeys []string, -) []Input { - spanByID, resByID, scopeByID := traceutil.IndexOTelSpans(traces) - topLevelByKind := conf.HasFeature("enable_otlp_compute_top_level_by_span_kind") - topLevelSpans := traceutil.GetTopLevelOTelSpans(spanByID, resByID, topLevelByKind) - ignoreResNames := make(map[string]struct{}) - for _, resName := range conf.Ignore["resource"] { - ignoreResNames[resName] = struct{}{} - } - chunks := make(map[chunkKey]*pb.TraceChunk) - containerTagsByID := make(map[string][]string) - for spanID, otelspan := range spanByID { - otelres := resByID[spanID] - if _, exists := ignoreResNames[traceutil.GetOTelResource(otelspan, otelres)]; exists { - continue - } - // TODO(songy23): use AttributeDeploymentEnvironmentName once collector version upgrade is unblocked - env := traceutil.GetOTelAttrValInResAndSpanAttrs(otelspan, otelres, true, "deployment.environment.name", semconv.AttributeDeploymentEnvironment) - hostname := traceutil.GetOTelHostname(otelspan, otelres, conf.OTLPReceiver.AttributesTranslator, conf.Hostname) - version := traceutil.GetOTelAttrValInResAndSpanAttrs(otelspan, otelres, true, semconv.AttributeServiceVersion) - cid := traceutil.GetOTelAttrValInResAndSpanAttrs(otelspan, otelres, true, semconv.AttributeContainerID, semconv.AttributeK8SPodUID) - var ctags []string - if cid != "" { - ctags = traceutil.GetOTelContainerTags(otelres.Attributes(), containerTagKeys) - if ctags != nil { - // Make sure container tags are sorted per APM stats intake requirement - if !slices.IsSorted(ctags) { - slices.Sort(ctags) - } - containerTagsByID[cid] = ctags - } - } - ckey := chunkKey{ - traceIDUInt64: traceutil.OTelTraceIDToUint64(otelspan.TraceID()), - env: env, - version: version, - hostname: hostname, - cid: cid, - } - chunk, ok := chunks[ckey] - if !ok { - chunk = &pb.TraceChunk{} - chunks[ckey] = chunk - } - _, isTop := topLevelSpans[spanID] - chunk.Spans = append(chunk.Spans, otelSpanToDDSpan(otelspan, otelres, scopeByID[spanID], isTop, topLevelByKind, conf, peerTagKeys)) - } - - inputs := make([]Input, 0, len(chunks)) - for ckey, chunk := range chunks { - pt := traceutil.ProcessedTrace{ - TraceChunk: chunk, - Root: traceutil.GetRoot(chunk.Spans), - TracerEnv: ckey.env, - AppVersion: ckey.version, - TracerHostname: ckey.hostname, - } - inputs = append(inputs, Input{ - Traces: []traceutil.ProcessedTrace{pt}, - ContainerID: ckey.cid, - ContainerTags: containerTagsByID[ckey.cid], - }) - } - return inputs -} - -// otelSpanToDDSpan converts an OTel span to a DD span. -// The converted DD span only has the minimal number of fields for APM stats calculation and is only meant -// to be used in OTLPTracesToConcentratorInputs. Do not use them for other purposes. -// TODO(OTEL-1726): use the same function here and in pkg/trace/api/otlp.go -func otelSpanToDDSpan( - otelspan ptrace.Span, - otelres pcommon.Resource, - lib pcommon.InstrumentationScope, - isTopLevel, topLevelByKind bool, - conf *config.AgentConfig, - peerTagKeys []string, -) *pb.Span { - ddspan := &pb.Span{ - Service: traceutil.GetOTelService(otelspan, otelres, true), - Name: traceutil.GetOTelOperationName(otelspan, otelres, lib, conf.OTLPReceiver.SpanNameAsResourceName, conf.OTLPReceiver.SpanNameRemappings, true), - Resource: traceutil.GetOTelResource(otelspan, otelres), - TraceID: traceutil.OTelTraceIDToUint64(otelspan.TraceID()), - SpanID: traceutil.OTelSpanIDToUint64(otelspan.SpanID()), - ParentID: traceutil.OTelSpanIDToUint64(otelspan.ParentSpanID()), - Start: int64(otelspan.StartTimestamp()), - Duration: int64(otelspan.EndTimestamp()) - int64(otelspan.StartTimestamp()), - Type: traceutil.GetOTelSpanType(otelspan, otelres), - } - spanKind := otelspan.Kind() - traceutil.SetMeta(ddspan, "span.kind", traceutil.OTelSpanKindName(spanKind)) - code := traceutil.GetOTelStatusCode(otelspan) - if code != 0 { - traceutil.SetMetric(ddspan, tagStatusCode, float64(code)) - } - if otelspan.Status().Code() == ptrace.StatusCodeError { - ddspan.Error = 1 - } - if isTopLevel { - traceutil.SetTopLevel(ddspan, true) - } - if isMeasured := traceutil.GetOTelAttrVal(otelspan.Attributes(), false, "_dd.measured"); isMeasured == "1" { - traceutil.SetMeasured(ddspan, true) - } else if topLevelByKind && (spanKind == ptrace.SpanKindClient || spanKind == ptrace.SpanKindProducer) { - // When enable_otlp_compute_top_level_by_span_kind is true, compute stats for client-side spans - traceutil.SetMeasured(ddspan, true) - } - for _, peerTagKey := range peerTagKeys { - if peerTagVal := traceutil.GetOTelAttrValInResAndSpanAttrs(otelspan, otelres, false, peerTagKey); peerTagVal != "" { - traceutil.SetMeta(ddspan, peerTagKey, peerTagVal) - } - } - return ddspan -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/trace/stats/span_concentrator.go b/vendor/github.com/DataDog/datadog-agent/pkg/trace/stats/span_concentrator.go deleted file mode 100644 index e48f937f..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/trace/stats/span_concentrator.go +++ /dev/null @@ -1,253 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package stats - -import ( - "slices" - "strings" - "sync" - "time" - - "github.com/DataDog/datadog-agent/pkg/obfuscate" - pb "github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace" - "github.com/DataDog/datadog-agent/pkg/trace/log" - "github.com/DataDog/datadog-agent/pkg/trace/traceutil" -) - -// SpanConcentratorConfig exposes configuration options for a SpanConcentrator -type SpanConcentratorConfig struct { - // ComputeStatsBySpanKind enables/disables the computing of stats based on a span's `span.kind` field - ComputeStatsBySpanKind bool - // BucketInterval the size of our pre-aggregation per bucket - BucketInterval int64 -} - -// StatSpan holds all the required fields from a span needed to calculate stats -type StatSpan struct { - service string - resource string - name string - typ string - error int32 - parentID uint64 - start int64 - duration int64 - - //Fields below this are derived on creation - - spanKind string - statusCode uint32 - isTopLevel bool - matchingPeerTags []string -} - -func matchingPeerTags(meta map[string]string, peerTagKeys []string) []string { - if len(peerTagKeys) == 0 { - return nil - } - var pt []string - for _, t := range peerTagKeysToAggregateForSpan(meta[tagSpanKind], meta[tagBaseService], peerTagKeys) { - if v, ok := meta[t]; ok && v != "" { - v = obfuscate.QuantizePeerIPAddresses(v) - pt = append(pt, t+":"+v) - } - } - return pt -} - -// peerTagKeysToAggregateForSpan returns the set of peerTagKeys to use for stats aggregation for the given -// span.kind and _dd.base_service -func peerTagKeysToAggregateForSpan(spanKind string, baseService string, peerTagKeys []string) []string { - if len(peerTagKeys) == 0 { - return nil - } - spanKind = strings.ToLower(spanKind) - if (spanKind == "" || spanKind == "internal") && baseService != "" { - // it's a service override on an internal span so it comes from custom instrumentation and does not represent - // a client|producer|consumer span which is talking to a peer entity - // in this case only the base service tag is relevant for stats aggregation - return []string{tagBaseService} - } - if spanKind == "client" || spanKind == "producer" || spanKind == "consumer" { - return peerTagKeys - } - return nil -} - -// SpanConcentrator produces time bucketed statistics from a stream of raw spans. -type SpanConcentrator struct { - computeStatsBySpanKind bool - // bucket duration in nanoseconds - bsize int64 - // Timestamp of the oldest time bucket for which we allow data. - // Any ingested stats older than it get added to this bucket. - oldestTs int64 - // bufferLen is the number of 10s stats bucket we keep in memory before flushing them. - // It means that we can compute stats only for the last `bufferLen * bsize` and that we - // wait such time before flushing the stats. - // This only applies to past buckets. Stats buckets in the future are allowed with no restriction. - bufferLen int - - // mu protects the buckets field - mu sync.Mutex - buckets map[int64]*RawBucket -} - -// NewSpanConcentrator builds a new SpanConcentrator object -func NewSpanConcentrator(cfg *SpanConcentratorConfig, now time.Time) *SpanConcentrator { - sc := &SpanConcentrator{ - computeStatsBySpanKind: cfg.ComputeStatsBySpanKind, - bsize: cfg.BucketInterval, - oldestTs: alignTs(now.UnixNano(), cfg.BucketInterval), - bufferLen: defaultBufferLen, - mu: sync.Mutex{}, - buckets: make(map[int64]*RawBucket), - } - return sc -} - -// NewStatSpanFromPB is a helper version of NewStatSpan that builds a StatSpan from a pb.Span. -func (sc *SpanConcentrator) NewStatSpanFromPB(s *pb.Span, peerTags []string) (statSpan *StatSpan, ok bool) { - return sc.NewStatSpan(s.Service, s.Resource, s.Name, s.Type, s.ParentID, s.Start, s.Duration, s.Error, s.Meta, s.Metrics, peerTags) -} - -// NewStatSpan builds a StatSpan from the required fields for stats calculation -// peerTags is the configured list of peer tags to look for -// returns (nil,false) if the provided fields indicate a span should not have stats calculated -func (sc *SpanConcentrator) NewStatSpan( - service, resource, name string, - typ string, - parentID uint64, - start, duration int64, - error int32, - meta map[string]string, - metrics map[string]float64, - peerTags []string, -) (statSpan *StatSpan, ok bool) { - if meta == nil { - meta = make(map[string]string) - } - if metrics == nil { - metrics = make(map[string]float64) - } - eligibleSpanKind := sc.computeStatsBySpanKind && computeStatsForSpanKind(meta["span.kind"]) - isTopLevel := traceutil.HasTopLevelMetrics(metrics) - if !(isTopLevel || traceutil.IsMeasuredMetrics(metrics) || eligibleSpanKind) { - return nil, false - } - if traceutil.IsPartialSnapshotMetrics(metrics) { - return nil, false - } - return &StatSpan{ - service: service, - resource: resource, - name: name, - typ: typ, - error: error, - parentID: parentID, - start: start, - duration: duration, - spanKind: meta[tagSpanKind], - statusCode: getStatusCode(meta, metrics), - isTopLevel: isTopLevel, - matchingPeerTags: matchingPeerTags(meta, peerTags), - }, true -} - -// computeStatsForSpanKind returns true if the span.kind value makes the span eligible for stats computation. -func computeStatsForSpanKind(kind string) bool { - k := strings.ToLower(kind) - return slices.Contains(KindsComputed, k) -} - -// KindsComputed is the list of span kinds that will have stats computed on them -// when computeStatsByKind is enabled in the concentrator. -var KindsComputed = []string{ - "server", - "consumer", - "client", - "producer", -} - -func (sc *SpanConcentrator) addSpan(s *StatSpan, aggKey PayloadAggregationKey, containerID string, containerTags []string, origin string, weight float64) { - sc.mu.Lock() - defer sc.mu.Unlock() - end := s.start + s.duration - btime := end - end%sc.bsize - - // If too far in the past, count in the oldest-allowed time bucket instead. - if btime < sc.oldestTs { - btime = sc.oldestTs - } - - b, ok := sc.buckets[btime] - if !ok { - b = NewRawBucket(uint64(btime), uint64(sc.bsize)) - if containerID != "" && len(containerTags) > 0 { - b.containerTagsByID[containerID] = containerTags - } - sc.buckets[btime] = b - } - b.HandleSpan(s, weight, origin, aggKey) -} - -// AddSpan to the SpanConcentrator, appending the new data to the appropriate internal bucket. -func (sc *SpanConcentrator) AddSpan(s *StatSpan, aggKey PayloadAggregationKey, containerID string, containerTags []string, origin string) { - sc.addSpan(s, aggKey, containerID, containerTags, origin, 1) -} - -// Flush deletes and returns complete ClientStatsPayloads. -// The force boolean guarantees flushing all buckets if set to true. -func (sc *SpanConcentrator) Flush(now int64, force bool) []*pb.ClientStatsPayload { - m := make(map[PayloadAggregationKey][]*pb.ClientStatsBucket) - containerTagsByID := make(map[string][]string) - - sc.mu.Lock() - for ts, srb := range sc.buckets { - // Always keep `bufferLen` buckets (default is 2: current + previous one). - // This is a trade-off: we accept slightly late traces (clock skew and stuff) - // but we delay flushing by at most `bufferLen` buckets. - // - // This delay might result in not flushing stats payload (data loss) - // if the agent stops while the latest buckets aren't old enough to be flushed. - // The "force" boolean skips the delay and flushes all buckets, typically on agent shutdown. - if !force && ts > now-int64(sc.bufferLen)*sc.bsize { - log.Tracef("Bucket %d is not old enough to be flushed, keeping it", ts) - continue - } - log.Debugf("Flushing bucket %d", ts) - for k, b := range srb.Export() { - m[k] = append(m[k], b) - if ctags, ok := srb.containerTagsByID[k.ContainerID]; ok { - containerTagsByID[k.ContainerID] = ctags - } - } - delete(sc.buckets, ts) - } - // After flushing, update the oldest timestamp allowed to prevent having stats for - // an already-flushed bucket. - newOldestTs := alignTs(now, sc.bsize) - int64(sc.bufferLen-1)*sc.bsize - if newOldestTs > sc.oldestTs { - log.Debugf("Update oldestTs to %d", newOldestTs) - sc.oldestTs = newOldestTs - } - sc.mu.Unlock() - sb := make([]*pb.ClientStatsPayload, 0, len(m)) - for k, s := range m { - p := &pb.ClientStatsPayload{ - Env: k.Env, - Hostname: k.Hostname, - ContainerID: k.ContainerID, - Version: k.Version, - GitCommitSha: k.GitCommitSha, - ImageTag: k.ImageTag, - Stats: s, - Tags: containerTagsByID[k.ContainerID], - } - sb = append(sb, p) - } - return sb -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/trace/stats/statsraw.go b/vendor/github.com/DataDog/datadog-agent/pkg/trace/stats/statsraw.go deleted file mode 100644 index a1b97826..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/trace/stats/statsraw.go +++ /dev/null @@ -1,206 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package stats - -import ( - "math" - "math/rand" - - pb "github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace" - "github.com/DataDog/datadog-agent/pkg/trace/log" - - "github.com/golang/protobuf/proto" - - "github.com/DataDog/sketches-go/ddsketch" -) - -const ( - // relativeAccuracy is the value accuracy we have on the percentiles. For example, we can - // say that p99 is 100ms +- 1ms - relativeAccuracy = 0.01 - // maxNumBins is the maximum number of bins of the ddSketch we use to store percentiles. - // It can affect relative accuracy, but in practice, 2048 bins is enough to have 1% relative accuracy from - // 80 micro second to 1 year: http://www.vldb.org/pvldb/vol12/p2195-masson.pdf - maxNumBins = 2048 -) - -// Most "algorithm" stuff here is tested with stats_test.go as what is important -// is that the final data, the one with send after a call to Export(), is correct. - -type groupedStats struct { - // using float64 here to avoid the accumulation of rounding issues. - hits float64 - topLevelHits float64 - errors float64 - duration float64 - okDistribution *ddsketch.DDSketch - errDistribution *ddsketch.DDSketch - peerTags []string -} - -// round a float to an int, uniformly choosing -// between the lower and upper approximations. -func round(f float64) uint64 { - i := uint64(f) - if rand.Float64() < f-float64(i) { - i++ - } - return i -} - -func (s *groupedStats) export(a Aggregation) (*pb.ClientGroupedStats, error) { - msg := s.okDistribution.ToProto() - okSummary, err := proto.Marshal(msg) - if err != nil { - return &pb.ClientGroupedStats{}, err - } - msg = s.errDistribution.ToProto() - errSummary, err := proto.Marshal(msg) - if err != nil { - return &pb.ClientGroupedStats{}, err - } - return &pb.ClientGroupedStats{ - Service: a.Service, - Name: a.Name, - Resource: a.Resource, - HTTPStatusCode: a.StatusCode, - Type: a.Type, - Hits: round(s.hits), - Errors: round(s.errors), - Duration: round(s.duration), - TopLevelHits: round(s.topLevelHits), - OkSummary: okSummary, - ErrorSummary: errSummary, - Synthetics: a.Synthetics, - SpanKind: a.SpanKind, - PeerTags: s.peerTags, - IsTraceRoot: a.IsTraceRoot, - }, nil -} - -func newGroupedStats() *groupedStats { - okSketch, err := ddsketch.LogCollapsingLowestDenseDDSketch(relativeAccuracy, maxNumBins) - if err != nil { - log.Errorf("Error when creating ddsketch: %v", err) - } - errSketch, err := ddsketch.LogCollapsingLowestDenseDDSketch(relativeAccuracy, maxNumBins) - if err != nil { - log.Errorf("Error when creating ddsketch: %v", err) - } - return &groupedStats{ - okDistribution: okSketch, - errDistribution: errSketch, - } -} - -// RawBucket is used to compute span data and aggregate it -// within a time-framed bucket. This should not be used outside -// the agent, use ClientStatsBucket for this. -type RawBucket struct { - // This should really have no public fields. At all. - - start uint64 // timestamp of start in our format - duration uint64 // duration of a bucket in nanoseconds - - // this should really remain private as it's subject to refactoring - data map[Aggregation]*groupedStats - - containerTagsByID map[string][]string // a map from container ID to container tags -} - -// NewRawBucket opens a new calculation bucket for time ts and initializes it properly -func NewRawBucket(ts, d uint64) *RawBucket { - // The only non-initialized value is the Duration which should be set by whoever closes that bucket - return &RawBucket{ - start: ts, - duration: d, - data: make(map[Aggregation]*groupedStats), - containerTagsByID: make(map[string][]string), - } -} - -// Export transforms a RawBucket into a ClientStatsBucket, typically used -// before communicating data to the API, as RawBucket is the internal -// type while ClientStatsBucket is the public, shared one. -func (sb *RawBucket) Export() map[PayloadAggregationKey]*pb.ClientStatsBucket { - m := make(map[PayloadAggregationKey]*pb.ClientStatsBucket) - for k, v := range sb.data { - b, err := v.export(k) - if err != nil { - log.Errorf("Dropping stats bucket due to encoding error: %v.", err) - continue - } - key := PayloadAggregationKey{ - Hostname: k.Hostname, - Version: k.Version, - Env: k.Env, - ContainerID: k.ContainerID, - GitCommitSha: k.GitCommitSha, - ImageTag: k.ImageTag, - } - s, ok := m[key] - if !ok { - s = &pb.ClientStatsBucket{ - Start: sb.start, - Duration: sb.duration, - } - } - s.Stats = append(s.Stats, b) - m[key] = s - } - return m -} - -// HandleSpan adds the span to this bucket stats, aggregated with the finest grain matching given aggregators -func (sb *RawBucket) HandleSpan(s *StatSpan, weight float64, origin string, aggKey PayloadAggregationKey) { - if aggKey.Env == "" { - panic("env should never be empty") - } - aggr := NewAggregationFromSpan(s, origin, aggKey) - sb.add(s, weight, aggr) -} - -func (sb *RawBucket) add(s *StatSpan, weight float64, aggr Aggregation) { - var gs *groupedStats - var ok bool - - if gs, ok = sb.data[aggr]; !ok { - gs = newGroupedStats() - gs.peerTags = s.matchingPeerTags - sb.data[aggr] = gs - } - if s.isTopLevel { - gs.topLevelHits += weight - } - gs.hits += weight - if s.error != 0 { - gs.errors += weight - } - gs.duration += float64(s.duration) * weight - // alter resolution of duration distro - trundur := nsTimestampToFloat(s.duration) - if s.error != 0 { - if err := gs.errDistribution.Add(trundur); err != nil { - log.Debugf("Error adding error distribution stats: %v", err) - } - } else { - if err := gs.okDistribution.Add(trundur); err != nil { - log.Debugf("Error adding distribution stats: %v", err) - } - } -} - -// nsTimestampToFloat converts a nanosec timestamp into a float nanosecond timestamp truncated to a fixed precision -func nsTimestampToFloat(ns int64) float64 { - b := math.Float64bits(float64(ns)) - // IEEE-754 - // the mask include 1 bit sign 11 bits exponent (0xfff) - // then we filter the mantissa to 10bits (0xff8) (9 bits as it has implicit value of 1) - // 10 bits precision (any value will be +/- 1/1024) - // https://en.wikipedia.org/wiki/Double-precision_floating-point_format - b &= 0xfffff80000000000 - return math.Float64frombits(b) -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/trace/stats/weight.go b/vendor/github.com/DataDog/datadog-agent/pkg/trace/stats/weight.go deleted file mode 100644 index d28ca5e4..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/trace/stats/weight.go +++ /dev/null @@ -1,24 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package stats - -import pb "github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace" - -// keySamplingRateGlobal is a metric key holding the global sampling rate. -const keySamplingRateGlobal = "_sample_rate" - -// weight returns the weight of the span as defined for sampling, i.e. the -// inverse of the sampling rate. -func weight(s *pb.Span) float64 { - if s == nil { - return 1 - } - sampleRate, ok := s.Metrics[keySamplingRateGlobal] - if !ok || sampleRate <= 0.0 || sampleRate > 1.0 { - return 1 - } - return 1.0 / sampleRate -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/trace/traceutil/azure.go b/vendor/github.com/DataDog/datadog-agent/pkg/trace/traceutil/azure.go deleted file mode 100644 index 111ecc66..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/trace/traceutil/azure.go +++ /dev/null @@ -1,166 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package traceutil - -import ( - "fmt" - "os" - "runtime" - "strings" -) - -const ( - aasInstanceID = "aas.environment.instance_id" - aasInstanceName = "aas.environment.instance_name" - aasOperatingSystem = "aas.environment.os" - aasRuntime = "aas.environment.runtime" - aasExtensionVersion = "aas.environment.extension_version" - aasFunctionRuntime = "aas.environment.function_runtime" - aasResourceGroup = "aas.resource.group" - aasResourceID = "aas.resource.id" - aasSiteKind = "aas.site.kind" - aasSiteName = "aas.site.name" - aasSiteType = "aas.site.type" - aasSubscriptionID = "aas.subscription.id" - - dotnetFramework = ".NET" - nodeFramework = "Node.js" - javaFramework = "Java" - pythonFramework = "Python" - phpFramework = "PHP" - goFramework = "Go" - containerFramework = "Container" - unknown = "unknown" - - appService = "app" -) - -// GetAppServicesTags returns the env vars pulled from the Azure App Service instance. -// In some cases we will need to add extra tags for function apps. -func GetAppServicesTags() map[string]string { - siteName := os.Getenv("WEBSITE_SITE_NAME") - ownerName := os.Getenv("WEBSITE_OWNER_NAME") - resourceGroup := os.Getenv("WEBSITE_RESOURCE_GROUP") - instanceID := getEnvOrUnknown("WEBSITE_INSTANCE_ID") - computerName := getEnvOrUnknown("COMPUTERNAME") - extensionVersion := os.Getenv("DD_AAS_EXTENSION_VERSION") - - // Windows and linux environments provide the OS differently - // We should grab it from GO's builtin runtime pkg - websiteOS := runtime.GOOS - - currentRuntime := getRuntime(websiteOS) - subscriptionID := parseAzureSubscriptionID(ownerName) - resourceID := compileAzureResourceID(subscriptionID, resourceGroup, siteName) - - tags := map[string]string{ - aasInstanceID: instanceID, - aasInstanceName: computerName, - aasOperatingSystem: websiteOS, - aasRuntime: currentRuntime, - aasResourceGroup: resourceGroup, - aasResourceID: resourceID, - aasSiteKind: appService, - aasSiteName: siteName, - aasSiteType: appService, - aasSubscriptionID: subscriptionID, - } - - // Remove the Java and .NET logic once non-universal extensions are deprecated - if websiteOS == "windows" { - if extensionVersion != "" { - tags[aasExtensionVersion] = extensionVersion - } else if val := os.Getenv("DD_AAS_JAVA_EXTENSION_VERSION"); val != "" { - tags[aasExtensionVersion] = val - } else if val := os.Getenv("DD_AAS_DOTNET_EXTENSION_VERSION"); val != "" { - tags[aasExtensionVersion] = val - } - } - - // Function Apps require a different runtime and kind - if rt, ok := os.LookupEnv("FUNCTIONS_WORKER_RUNTIME"); ok { - tags[aasRuntime] = rt - tags[aasFunctionRuntime] = os.Getenv("FUNCTIONS_EXTENSION_VERSION") - tags[aasSiteKind] = "functionapp" - } - - return tags -} - -func getEnvOrUnknown(env string) string { - if val, ok := os.LookupEnv(env); ok { - return val - } - return unknown -} - -func getRuntime(websiteOS string) (rt string) { - switch websiteOS { - case "windows": - rt = getWindowsRuntime() - case "linux", "darwin": - rt = getLinuxRuntime() - default: - rt = unknown - } - - return rt -} - -func getWindowsRuntime() (rt string) { - if os.Getenv("WEBSITE_STACK") == "JAVA" { - rt = javaFramework - } else if val := os.Getenv("WEBSITE_NODE_DEFAULT_VERSION"); val != "" { - rt = nodeFramework - } else { - // FIXME: Windows AAS only supports Java, Node, and .NET so we can infer this - // Needs to be inferred because no other env vars give us context on the runtime - rt = dotnetFramework - } - - return rt -} - -func getLinuxRuntime() (rt string) { - rt = unknown - - switch os.Getenv("WEBSITE_STACK") { - case "DOCKER": - rt = containerFramework - case "": - if val := os.Getenv("DOCKER_SERVER_VERSION"); val != "" { - rt = containerFramework - } - case "NODE": - rt = nodeFramework - case "PYTHON": - rt = pythonFramework - case "JAVA", "TOMCAT": - rt = javaFramework - case "DOTNETCORE": - rt = dotnetFramework - case "PHP": - rt = phpFramework - } - - return rt -} - -func parseAzureSubscriptionID(subID string) (id string) { - parsedSubID := strings.SplitN(subID, "+", 2) - if len(parsedSubID) > 1 { - id = parsedSubID[0] - } - return -} - -func compileAzureResourceID(subID, resourceGroup, siteName string) (id string) { - if len(subID) > 0 && len(resourceGroup) > 0 && len(siteName) > 0 { - id = fmt.Sprintf("/subscriptions/%s/resourcegroups/%s/providers/microsoft.web/sites/%s", - subID, resourceGroup, siteName) - } - return -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/trace/traceutil/doc.go b/vendor/github.com/DataDog/datadog-agent/pkg/trace/traceutil/doc.go deleted file mode 100644 index ac2de89f..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/trace/traceutil/doc.go +++ /dev/null @@ -1,8 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -// Package traceutil contains functions for extracting and processing traces. It should -// only import payload and nothing else. -package traceutil diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/trace/traceutil/normalize.go b/vendor/github.com/DataDog/datadog-agent/pkg/trace/traceutil/normalize.go deleted file mode 100644 index 78636cbc..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/trace/traceutil/normalize.go +++ /dev/null @@ -1,356 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package traceutil - -import ( - "errors" - "strings" - "sync" - "unicode" - "unicode/utf8" -) - -const ( - // DefaultSpanName is the default name we assign a span if it's missing and we have no reasonable fallback - DefaultSpanName = "unnamed_operation" - // DefaultServiceName is the default name we assign a service if it's missing and we have no reasonable fallback - DefaultServiceName = "unnamed-service" -) - -const ( - // MaxNameLen the maximum length a name can have - MaxNameLen = 100 - // MaxServiceLen the maximum length a service can have - MaxServiceLen = 100 - // MaxResourceLen the maximum length a resource can have - MaxResourceLen = 5000 -) - -var ( - // ErrEmpty specifies that the passed input was empty. - ErrEmpty = errors.New("empty") - // ErrTooLong signifies that the input was too long. - ErrTooLong = errors.New("too long") - // ErrInvalid signifies that the input was invalid. - ErrInvalid = errors.New("invalid") -) - -// NormalizeName normalizes a span name and returns an error describing the reason -// (if any) why the name was modified. -func NormalizeName(name string) (string, error) { - if name == "" { - return DefaultSpanName, ErrEmpty - } - var err error - if len(name) > MaxNameLen { - name = TruncateUTF8(name, MaxNameLen) - err = ErrTooLong - } - name, ok := normMetricNameParse(name) - if !ok { - return DefaultSpanName, ErrInvalid - } - return name, err -} - -// NormalizeService normalizes a span service and returns an error describing the reason -// (if any) why the name was modified. -func NormalizeService(svc string, lang string) (string, error) { - if svc == "" { - return fallbackService(lang), ErrEmpty - } - var err error - if len(svc) > MaxServiceLen { - svc = TruncateUTF8(svc, MaxServiceLen) - err = ErrTooLong - } - // We are normalizing just the tag value. - s := NormalizeTagValue(svc) - if s == "" { - return fallbackService(lang), ErrInvalid - } - return s, err -} - -// NormalizePeerService normalizes a span's peer.service and returns an error describing the reason -// (if any) why the name was modified. -func NormalizePeerService(svc string) (string, error) { - if svc == "" { - return "", nil - } - var err error - if len(svc) > MaxServiceLen { - svc = TruncateUTF8(svc, MaxServiceLen) - err = ErrTooLong - } - // We are normalizing just the tag value. - s := NormalizeTagValue(svc) - if s == "" { - return "", ErrInvalid - } - return s, err -} - -// fallbackServiceNames is a cache of default service names to use -// when the span's service is unset or invalid. -var fallbackServiceNames sync.Map - -// fallbackService returns the fallback service name for a service -// belonging to language lang. -func fallbackService(lang string) string { - if lang == "" { - return DefaultServiceName - } - if v, ok := fallbackServiceNames.Load(lang); ok { - return v.(string) - } - var str strings.Builder - str.WriteString("unnamed-") - str.WriteString(lang) - str.WriteString("-service") - fallbackServiceNames.Store(lang, str.String()) - return str.String() -} - -const maxTagLength = 200 - -// NormalizeTag applies some normalization to ensure the full tag_key:tag_value string matches the backend requirements. -func NormalizeTag(v string) string { - return normalize(v, true) -} - -// NormalizeTagValue applies some normalization to ensure the tag value matches the backend requirements. -// It should be used for cases where we have just the tag_value as the input (instead of tag_key:tag_value). -func NormalizeTagValue(v string) string { - return normalize(v, false) -} - -func normalize(v string, allowDigitStartChar bool) string { - // Fast path: Check if the tag is valid and only contains ASCII characters, - // if yes return it as-is right away. For most use-cases this reduces CPU usage. - if isNormalizedASCIITag(v, allowDigitStartChar) { - return v - } - // the algorithm works by creating a set of cuts marking start and end offsets in v - // that have to be replaced with underscore (_) - if len(v) == 0 { - return "" - } - var ( - trim int // start character (if trimming) - cuts [][2]int // sections to discard: (start, end) pairs - chars int // number of characters processed - ) - var ( - i int // current byte - r rune // current rune - jump int // tracks how many bytes the for range advances on its next iteration - ) - tag := []byte(v) - for i, r = range v { - jump = utf8.RuneLen(r) // next i will be i+jump - if r == utf8.RuneError { - // On invalid UTF-8, the for range advances only 1 byte (see: https://golang.org/ref/spec#For_range (point 2)). - // However, utf8.RuneError is equivalent to unicode.ReplacementChar so we should rely on utf8.DecodeRune to tell - // us whether this is an actual error or just a unicode.ReplacementChar that was present in the string. - _, width := utf8.DecodeRune(tag[i:]) - jump = width - } - // fast path; all letters (and colons) are ok - switch { - case r >= 'a' && r <= 'z' || r == ':': - chars++ - goto end - case r >= 'A' && r <= 'Z': - // lower-case - tag[i] += 'a' - 'A' - chars++ - goto end - } - if unicode.IsUpper(r) { - // lowercase this character - if low := unicode.ToLower(r); utf8.RuneLen(r) == utf8.RuneLen(low) { - // but only if the width of the lowercased character is the same; - // there are some rare edge-cases where this is not the case, such - // as \u017F (ſ) - utf8.EncodeRune(tag[i:], low) - r = low - } - } - switch { - case unicode.IsLetter(r): - chars++ - // If it's not a unicode letter, and it's the first char, and digits are allowed for the start char, - // we should goto end because the remaining cases are not valid for a start char. - case allowDigitStartChar && chars == 0: - trim = i + jump - goto end - case unicode.IsDigit(r) || r == '.' || r == '/' || r == '-': - chars++ - default: - // illegal character - chars++ - if n := len(cuts); n > 0 && cuts[n-1][1] >= i { - // merge intersecting cuts - cuts[n-1][1] += jump - } else { - // start a new cut - cuts = append(cuts, [2]int{i, i + jump}) - } - } - end: - if i+jump >= 2*maxTagLength { - // bail early if the tag contains a lot of non-letter/digit characters. - // If a tag is test🍣🍣[...]🍣, then it's unlikely to be a properly formatted tag - break - } - if chars >= maxTagLength { - // we've reached the maximum - break - } - } - - tag = tag[trim : i+jump] // trim start and end - if len(cuts) == 0 { - // tag was ok, return it as it is - return string(tag) - } - delta := trim // cut offsets delta - for _, cut := range cuts { - // start and end of cut, including delta from previous cuts: - start, end := cut[0]-delta, cut[1]-delta - - if end >= len(tag) { - // this cut includes the end of the string; discard it - // completely and finish the loop. - tag = tag[:start] - break - } - // replace the beginning of the cut with '_' - tag[start] = '_' - if end-start == 1 { - // nothing to discard - continue - } - // discard remaining characters in the cut - copy(tag[start+1:], tag[end:]) - - // shorten the slice - tag = tag[:len(tag)-(end-start)+1] - - // count the new delta for future cuts - delta += cut[1] - cut[0] - 1 - } - return string(tag) -} - -// This code is borrowed from dd-go metric normalization - -// fast isAlpha for ascii -func isAlpha(b byte) bool { - return (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') -} - -// fast isAlphaNumeric for ascii -func isAlphaNum(b byte) bool { - return isAlpha(b) || (b >= '0' && b <= '9') -} - -// normMetricNameParse normalizes metric names with a parser instead of using -// garbage-creating string replacement routines. -func normMetricNameParse(name string) (string, bool) { - if name == "" || len(name) > MaxNameLen { - return name, false - } - - var i, ptr int - var resa [MaxNameLen]byte - res := resa[:0] - - // skip non-alphabetic characters - for ; i < len(name) && !isAlpha(name[i]); i++ { - continue - } - - // if there were no alphabetic characters it wasn't valid - if i == len(name) { - return "", false - } - - for ; i < len(name); i++ { - switch { - case isAlphaNum(name[i]): - res = append(res, name[i]) - ptr++ - case name[i] == '.': - // we skipped all non-alpha chars up front so we have seen at least one - switch res[ptr-1] { - // overwrite underscores that happen before periods - case '_': - res[ptr-1] = '.' - default: - res = append(res, '.') - ptr++ - } - default: - // we skipped all non-alpha chars up front so we have seen at least one - switch res[ptr-1] { - // no double underscores, no underscores after periods - case '.', '_': - default: - res = append(res, '_') - ptr++ - } - } - } - - if res[ptr-1] == '_' { - res = res[:ptr-1] - } - - return string(res), true -} - -func isNormalizedASCIITag(tag string, checkValidStartChar bool) bool { - if len(tag) == 0 { - return true - } - if len(tag) > maxTagLength { - return false - } - i := 0 - if checkValidStartChar { - if !isValidASCIIStartChar(tag[0]) { - return false - } - i++ - } - for ; i < len(tag); i++ { - b := tag[i] - // TODO: Attempt to optimize this check using SIMD/vectorization. - if isValidASCIITagChar(b) { - continue - } - if b == '_' { - // an underscore is only okay if followed by a valid non-underscore character - i++ - if i == len(tag) || !isValidASCIITagChar(tag[i]) { - return false - } - } else { - return false - } - } - return true -} - -func isValidASCIIStartChar(c byte) bool { - return ('a' <= c && c <= 'z') || c == ':' -} - -func isValidASCIITagChar(c byte) bool { - return isValidASCIIStartChar(c) || ('0' <= c && c <= '9') || c == '.' || c == '/' || c == '-' -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/trace/traceutil/otel_util.go b/vendor/github.com/DataDog/datadog-agent/pkg/trace/traceutil/otel_util.go deleted file mode 100644 index 1be778af..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/trace/traceutil/otel_util.go +++ /dev/null @@ -1,329 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package traceutil - -import ( - "context" - "encoding/binary" - "strings" - - "github.com/DataDog/datadog-agent/pkg/trace/log" - "github.com/DataDog/opentelemetry-mapping-go/pkg/otlp/attributes" - "github.com/DataDog/opentelemetry-mapping-go/pkg/otlp/attributes/source" - "go.opentelemetry.io/collector/pdata/pcommon" - "go.opentelemetry.io/collector/pdata/ptrace" - semconv117 "go.opentelemetry.io/collector/semconv/v1.17.0" - semconv "go.opentelemetry.io/collector/semconv/v1.6.1" - "go.opentelemetry.io/otel/attribute" -) - -// Util functions for converting OTel semantics to DD semantics. -// TODO(OTEL-1726): reuse the same mapping code for ReceiveResourceSpans and Concentrator - -var ( - // SignalTypeSet is the OTel attribute set for traces. - SignalTypeSet = attribute.NewSet(attribute.String("signal", "traces")) -) - -// IndexOTelSpans iterates over the input OTel spans and returns 3 maps: -// OTel spans indexed by span ID, OTel resources indexed by span ID, OTel instrumentation scopes indexed by span ID. -// Skips spans with invalid trace ID or span ID. If there are multiple spans with the same (non-zero) span ID, the last one wins. -func IndexOTelSpans(traces ptrace.Traces) (map[pcommon.SpanID]ptrace.Span, map[pcommon.SpanID]pcommon.Resource, map[pcommon.SpanID]pcommon.InstrumentationScope) { - spanByID := make(map[pcommon.SpanID]ptrace.Span) - resByID := make(map[pcommon.SpanID]pcommon.Resource) - scopeByID := make(map[pcommon.SpanID]pcommon.InstrumentationScope) - rspanss := traces.ResourceSpans() - for i := 0; i < rspanss.Len(); i++ { - rspans := rspanss.At(i) - res := rspans.Resource() - for j := 0; j < rspans.ScopeSpans().Len(); j++ { - libspans := rspans.ScopeSpans().At(j) - for k := 0; k < libspans.Spans().Len(); k++ { - span := libspans.Spans().At(k) - if span.TraceID().IsEmpty() || span.SpanID().IsEmpty() { - continue - } - spanByID[span.SpanID()] = span - resByID[span.SpanID()] = res - scopeByID[span.SpanID()] = libspans.Scope() - } - } - } - return spanByID, resByID, scopeByID -} - -// GetTopLevelOTelSpans returns the span IDs of the top level OTel spans. -func GetTopLevelOTelSpans(spanByID map[pcommon.SpanID]ptrace.Span, resByID map[pcommon.SpanID]pcommon.Resource, topLevelByKind bool) map[pcommon.SpanID]struct{} { - topLevelSpans := make(map[pcommon.SpanID]struct{}) - for spanID, span := range spanByID { - if span.ParentSpanID().IsEmpty() { - // case 1: root span - topLevelSpans[spanID] = struct{}{} - continue - } - - if topLevelByKind { - // New behavior for computing top level OTel spans, see computeTopLevelAndMeasured in pkg/trace/api/otlp.go - spanKind := span.Kind() - if spanKind == ptrace.SpanKindServer || spanKind == ptrace.SpanKindConsumer { - // span is a server-side span, mark as top level - topLevelSpans[spanID] = struct{}{} - } - continue - } - - // Otherwise, fall back to old behavior in ComputeTopLevel - parentSpan, ok := spanByID[span.ParentSpanID()] - if !ok { - // case 2: parent span not in the same chunk, presumably it belongs to another service - topLevelSpans[spanID] = struct{}{} - continue - } - - svc := GetOTelService(span, resByID[spanID], true) - parentSvc := GetOTelService(parentSpan, resByID[parentSpan.SpanID()], true) - if svc != parentSvc { - // case 3: parent is not in the same service - topLevelSpans[spanID] = struct{}{} - } - } - return topLevelSpans -} - -// GetOTelAttrVal returns the matched value as a string in the input map with the given keys. -// If there are multiple keys present, the first matched one is returned. -// If normalize is true, normalize the return value with NormalizeTagValue. -func GetOTelAttrVal(attrs pcommon.Map, normalize bool, keys ...string) string { - val := "" - for _, key := range keys { - attrval, exists := attrs.Get(key) - if exists { - val = attrval.AsString() - } - } - - if normalize { - val = NormalizeTagValue(val) - } - - return val -} - -// GetOTelAttrValInResAndSpanAttrs returns the matched value as a string in the OTel resource attributes and span attributes with the given keys. -// If there are multiple keys present, the first matched one is returned. -// If the key is present in both resource attributes and span attributes, resource attributes take precedence. -// If normalize is true, normalize the return value with NormalizeTagValue. -func GetOTelAttrValInResAndSpanAttrs(span ptrace.Span, res pcommon.Resource, normalize bool, keys ...string) string { - if val := GetOTelAttrVal(res.Attributes(), normalize, keys...); val != "" { - return val - } - return GetOTelAttrVal(span.Attributes(), normalize, keys...) -} - -// GetOTelSpanType returns the DD span type based on OTel span kind and attributes. -func GetOTelSpanType(span ptrace.Span, res pcommon.Resource) string { - typ := GetOTelAttrValInResAndSpanAttrs(span, res, false, "span.type") - if typ != "" { - return typ - } - switch span.Kind() { - case ptrace.SpanKindServer: - typ = "web" - case ptrace.SpanKindClient: - db := GetOTelAttrValInResAndSpanAttrs(span, res, true, semconv.AttributeDBSystem) - if db == "redis" || db == "memcached" { - typ = "cache" - } else if db != "" { - typ = "db" - } else { - typ = "http" - } - default: - typ = "custom" - } - return typ -} - -// GetOTelService returns the DD service name based on OTel span and resource attributes. -func GetOTelService(span ptrace.Span, res pcommon.Resource, normalize bool) string { - // No need to normalize with NormalizeTagValue since we will do NormalizeService later - svc := GetOTelAttrValInResAndSpanAttrs(span, res, false, semconv.AttributeServiceName) - if svc == "" { - svc = "otlpresourcenoservicename" - } - if normalize { - newsvc, err := NormalizeService(svc, "") - switch err { - case ErrTooLong: - log.Debugf("Fixing malformed trace. Service is too long (reason:service_truncate), truncating span.service to length=%d: %s", MaxServiceLen, svc) - case ErrInvalid: - log.Debugf("Fixing malformed trace. Service is invalid (reason:service_invalid), replacing invalid span.service=%s with fallback span.service=%s", svc, newsvc) - } - svc = newsvc - } - return svc -} - -// GetOTelResource returns the DD resource name based on OTel span and resource attributes. -func GetOTelResource(span ptrace.Span, res pcommon.Resource) (resName string) { - resName = GetOTelAttrValInResAndSpanAttrs(span, res, false, "resource.name") - if resName == "" { - if m := GetOTelAttrValInResAndSpanAttrs(span, res, false, "http.request.method", semconv.AttributeHTTPMethod); m != "" { - // use the HTTP method + route (if available) - resName = m - if route := GetOTelAttrValInResAndSpanAttrs(span, res, false, semconv.AttributeHTTPRoute); route != "" { - resName = resName + " " + route - } - } else if m := GetOTelAttrValInResAndSpanAttrs(span, res, false, semconv.AttributeMessagingOperation); m != "" { - resName = m - // use the messaging operation - if dest := GetOTelAttrValInResAndSpanAttrs(span, res, false, semconv.AttributeMessagingDestination, semconv117.AttributeMessagingDestinationName); dest != "" { - resName = resName + " " + dest - } - } else if m := GetOTelAttrValInResAndSpanAttrs(span, res, false, semconv.AttributeRPCMethod); m != "" { - resName = m - // use the RPC method - if svc := GetOTelAttrValInResAndSpanAttrs(span, res, false, semconv.AttributeRPCService); m != "" { - // ...and service if available - resName = resName + " " + svc - } - } else { - resName = span.Name() - } - } - if len(resName) > MaxResourceLen { - resName = resName[:MaxResourceLen] - } - return -} - -// GetOTelOperationName returns the DD operation name based on OTel span and resource attributes and given configs. -func GetOTelOperationName( - span ptrace.Span, - res pcommon.Resource, - lib pcommon.InstrumentationScope, - spanNameAsResourceName bool, - spanNameRemappings map[string]string, - normalize bool) string { - // No need to normalize with NormalizeTagValue since we will do NormalizeName later - name := GetOTelAttrValInResAndSpanAttrs(span, res, false, "operation.name") - if name == "" { - if spanNameAsResourceName { - name = span.Name() - } else { - name = strings.ToLower(span.Kind().String()) - if lib.Name() != "" { - name = lib.Name() + "." + name - } else { - name = "opentelemetry." + name - } - } - } - if v, ok := spanNameRemappings[name]; ok { - name = v - } - - if normalize { - normalizeName, err := NormalizeName(name) - switch err { - case ErrEmpty: - log.Debugf("Fixing malformed trace. Name is empty (reason:span_name_empty), setting span.name=%s", normalizeName) - case ErrTooLong: - log.Debugf("Fixing malformed trace. Name is too long (reason:span_name_truncate), truncating span.name to length=%d", MaxServiceLen) - case ErrInvalid: - log.Debugf("Fixing malformed trace. Name is invalid (reason:span_name_invalid), setting span.name=%s", normalizeName) - } - name = normalizeName - } - - return name -} - -// GetOTelHostname returns the DD hostname based on OTel span and resource attributes. -func GetOTelHostname(span ptrace.Span, res pcommon.Resource, tr *attributes.Translator, fallbackHost string) string { - ctx := context.Background() - src, srcok := tr.ResourceToSource(ctx, res, SignalTypeSet) - if !srcok { - if v := GetOTelAttrValInResAndSpanAttrs(span, res, false, "_dd.hostname"); v != "" { - src = source.Source{Kind: source.HostnameKind, Identifier: v} - srcok = true - } - } - if srcok { - switch src.Kind { - case source.HostnameKind: - return src.Identifier - default: - // We are not on a hostname (serverless), hence the hostname is empty - return "" - } - } else { - // fallback hostname from Agent conf.Hostname - return fallbackHost - } -} - -// GetOTelStatusCode returns the DD status code of the OTel span. -func GetOTelStatusCode(span ptrace.Span) uint32 { - if code, ok := span.Attributes().Get("http.response.status_code"); ok { - return uint32(code.Int()) - } - if code, ok := span.Attributes().Get(semconv.AttributeHTTPStatusCode); ok { - return uint32(code.Int()) - } - return 0 -} - -// GetOTelContainerTags returns a list of DD container tags in the OTel resource attributes. -// Tags are always normalized. -func GetOTelContainerTags(rattrs pcommon.Map, tagKeys []string) []string { - var containerTags []string - containerTagsMap := attributes.ContainerTagsFromResourceAttributes(rattrs) - for _, key := range tagKeys { - if mappedKey, ok := attributes.ContainerMappings[key]; ok { - // If the key has a mapping in ContainerMappings, use the mapped key - if val, ok := containerTagsMap[mappedKey]; ok { - t := NormalizeTag(mappedKey + ":" + val) - containerTags = append(containerTags, t) - } - } else { - // Otherwise populate as additional container tags - if val := GetOTelAttrVal(rattrs, false, key); val != "" { - t := NormalizeTag(key + ":" + val) - containerTags = append(containerTags, t) - } - } - } - return containerTags -} - -// OTelTraceIDToUint64 converts an OTel trace ID to an uint64 -func OTelTraceIDToUint64(b [16]byte) uint64 { - return binary.BigEndian.Uint64(b[len(b)-8:]) -} - -// OTelSpanIDToUint64 converts an OTel span ID to an uint64 -func OTelSpanIDToUint64(b [8]byte) uint64 { - return binary.BigEndian.Uint64(b[:]) -} - -var spanKindNames = map[ptrace.SpanKind]string{ - ptrace.SpanKindUnspecified: "unspecified", - ptrace.SpanKindInternal: "internal", - ptrace.SpanKindServer: "server", - ptrace.SpanKindClient: "client", - ptrace.SpanKindProducer: "producer", - ptrace.SpanKindConsumer: "consumer", -} - -// OTelSpanKindName converts the given SpanKind to a valid Datadog span kind name. -func OTelSpanKindName(k ptrace.SpanKind) string { - name, ok := spanKindNames[k] - if !ok { - return "unspecified" - } - return name -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/trace/traceutil/processed_trace.go b/vendor/github.com/DataDog/datadog-agent/pkg/trace/traceutil/processed_trace.go deleted file mode 100644 index 913e4127..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/trace/traceutil/processed_trace.go +++ /dev/null @@ -1,53 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package traceutil - -import ( - pb "github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace" -) - -// ProcessedTrace represents a trace being processed in the agent. -type ProcessedTrace struct { - TraceChunk *pb.TraceChunk - Root *pb.Span - TracerEnv string - AppVersion string - TracerHostname string - ClientDroppedP0sWeight float64 - GitCommitSha string - ImageTag string -} - -// Clone creates a copy of ProcessedTrace, cloning p, p.TraceChunk, and p.Root. This means it is -// safe to modify the returned ProcessedTrace's (pt's) fields along with fields in -// pt.TraceChunk and fields in pt.Root. -// -// The most important consequence of this is that the TraceChunk's Spans field can be assigned, -// *BUT* the Spans value itself should not be modified. i.e. This is ok: -// -// pt2 := pt.Clone() -// pt2.TraceChunk.Spans = make([]*pb.Span) -// -// but this is NOT ok: -// -// pt2 := pt.Clone() -// pt2.TraceChunk.Spans[0] = &pb.Span{} // This will be visible in pt. -func (pt *ProcessedTrace) Clone() *ProcessedTrace { - if pt == nil { - return nil - } - ptClone := new(ProcessedTrace) - *ptClone = *pt - if pt.TraceChunk != nil { - c := pt.TraceChunk.ShallowCopy() - ptClone.TraceChunk = c - } - if pt.Root != nil { - r := pt.Root.ShallowCopy() - ptClone.Root = r - } - return ptClone -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/trace/traceutil/span.go b/vendor/github.com/DataDog/datadog-agent/pkg/trace/traceutil/span.go deleted file mode 100644 index 2b416531..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/trace/traceutil/span.go +++ /dev/null @@ -1,175 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package traceutil - -import ( - "bytes" - - "github.com/tinylib/msgp/msgp" - - pb "github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace" -) - -const ( - // topLevelKey is a special metric, it's 1 if the span is top-level, 0 if not, this is kept for backwards - // compatibility but will eventually be replaced with just using the preferred tracerTopLevelKey - topLevelKey = "_top_level" - // measuredKey is a special metric flag that marks a span for trace metrics calculation. - measuredKey = "_dd.measured" - // tracerTopLevelKey is a metric flag set by tracers on top_level spans - tracerTopLevelKey = "_dd.top_level" - // partialVersionKey is a metric carrying the snapshot seq number in the case the span is a partial snapshot - partialVersionKey = "_dd.partial_version" -) - -// HasTopLevel returns true if span is top-level. -func HasTopLevel(s *pb.Span) bool { - return HasTopLevelMetrics(s.Metrics) -} - -// HasTopLevelMetrics returns true if the provided metrics map indicates the span is top-level. -func HasTopLevelMetrics(metrics map[string]float64) bool { - return metrics[topLevelKey] == 1 || metrics[tracerTopLevelKey] == 1 -} - -// UpdateTracerTopLevel sets _top_level tag on spans flagged by the tracer -func UpdateTracerTopLevel(s *pb.Span) { - if s.Metrics[tracerTopLevelKey] == 1 { - SetMetric(s, topLevelKey, 1) - } -} - -// IsMeasured returns true if a span should be measured (i.e., it should get trace metrics calculated). -func IsMeasured(s *pb.Span) bool { - return IsMeasuredMetrics(s.Metrics) -} - -// IsMeasuredMetrics returns true if a span should be measured (i.e., it should get trace metrics calculated). -func IsMeasuredMetrics(metrics map[string]float64) bool { - return metrics[measuredKey] == 1 -} - -// IsPartialSnapshot returns true if the span is a partial snapshot. -// This kind of spans are partial images of long-running spans. -// When incomplete, a partial snapshot has a metric _dd.partial_version which is a positive integer. -// The metric usually increases each time a new version of the same span is sent by the tracer -func IsPartialSnapshot(s *pb.Span) bool { - return IsPartialSnapshotMetrics(s.Metrics) -} - -// IsPartialSnapshotMetrics returns true if the span is a partial snapshot. -// These kinds of spans are partial images of long-running spans. -// When incomplete, a partial snapshot has a metric _dd.partial_version which is a positive integer. -// The metric usually increases each time a new version of the same span is sent by the tracer -func IsPartialSnapshotMetrics(metrics map[string]float64) bool { - v, ok := metrics[partialVersionKey] - return ok && v >= 0 -} - -// SetTopLevel sets the top-level attribute of the span. -func SetTopLevel(s *pb.Span, topLevel bool) { - if !topLevel { - if s.Metrics == nil { - return - } - delete(s.Metrics, topLevelKey) - return - } - // Setting the metrics value, so that code downstream in the pipeline - // can identify this as top-level without recomputing everything. - SetMetric(s, topLevelKey, 1) -} - -// SetMeasured sets the measured attribute of the span. -func SetMeasured(s *pb.Span, measured bool) { - if !measured { - if s.Metrics == nil { - return - } - delete(s.Metrics, measuredKey) - return - } - // Setting the metrics value, so that code downstream in the pipeline - // can identify this as top-level without recomputing everything. - SetMetric(s, measuredKey, 1) -} - -// SetMetric sets the metric at key to the val on the span s. -func SetMetric(s *pb.Span, key string, val float64) { - if s.Metrics == nil { - s.Metrics = make(map[string]float64) - } - s.Metrics[key] = val -} - -// SetMeta sets the metadata at key to the val on the span s. -func SetMeta(s *pb.Span, key, val string) { - if s.Meta == nil { - s.Meta = make(map[string]string) - } - s.Meta[key] = val -} - -// GetMeta gets the metadata value in the span Meta map. -func GetMeta(s *pb.Span, key string) (string, bool) { - if s.Meta == nil { - return "", false - } - val, ok := s.Meta[key] - return val, ok -} - -// GetMetaDefault gets the metadata value in the span Meta map and fallbacks to fallback. -func GetMetaDefault(s *pb.Span, key, fallback string) string { - if s.Meta == nil { - return fallback - } - if val, ok := s.Meta[key]; ok { - return val - } - return fallback -} - -// SetMetaStruct sets the structured metadata at key to the val on the span s. -func SetMetaStruct(s *pb.Span, key string, val interface{}) error { - var b bytes.Buffer - - if s.MetaStruct == nil { - s.MetaStruct = make(map[string][]byte) - } - writer := msgp.NewWriter(&b) - err := writer.WriteIntf(val) - if err != nil { - return err - } - writer.Flush() - s.MetaStruct[key] = b.Bytes() - return nil -} - -// GetMetaStruct gets the structured metadata value in the span MetaStruct map. -func GetMetaStruct(s *pb.Span, key string) (interface{}, bool) { - if s.MetaStruct == nil { - return nil, false - } - if rawVal, ok := s.MetaStruct[key]; ok { - val, _, err := msgp.ReadIntfBytes(rawVal) - if err != nil { - ok = false - } - return val, ok - } - return nil, false -} - -// GetMetric gets the metadata value in the span Metrics map. -func GetMetric(s *pb.Span, key string) (float64, bool) { - if s.Metrics == nil { - return 0, false - } - val, ok := s.Metrics[key] - return val, ok -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/trace/traceutil/trace.go b/vendor/github.com/DataDog/datadog-agent/pkg/trace/traceutil/trace.go deleted file mode 100644 index ef8a0f29..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/trace/traceutil/trace.go +++ /dev/null @@ -1,119 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package traceutil - -import ( - pb "github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace" - "github.com/DataDog/datadog-agent/pkg/trace/log" -) - -const ( - envKey = "env" -) - -// GetEnv returns the first "env" tag found in trace t. -// Search starts by root -func GetEnv(root *pb.Span, t *pb.TraceChunk) string { - if v, ok := root.Meta[envKey]; ok { - return v - } - for _, s := range t.Spans { - if s.SpanID == root.SpanID { - continue - } - if v, ok := s.Meta[envKey]; ok { - return v - } - } - return "" -} - -// GetRoot extracts the root span from a trace -func GetRoot(t pb.Trace) *pb.Span { - // That should be caught beforehand - if len(t) == 0 { - return nil - } - // General case: go over all spans and check for one which matching parent - parentIDToChild := map[uint64]*pb.Span{} - - for i := range t { - // Common case optimization: check for span with ParentID == 0, starting from the end, - // since some clients report the root last - j := len(t) - 1 - i - if t[j].ParentID == 0 { - return t[j] - } - parentIDToChild[t[j].ParentID] = t[j] - } - - for i := range t { - delete(parentIDToChild, t[i].SpanID) - } - - // Here, if the trace is valid, we should have len(parentIDToChild) == 1 - if len(parentIDToChild) != 1 { - log.Debugf("Didn't reliably find the root span for traceID:%v", t[0].TraceID) - } - - // Have a safe behavior if that's not the case - // Pick the first span without its parent - for parentID := range parentIDToChild { - return parentIDToChild[parentID] - } - - // Gracefully fail with the last span of the trace - return t[len(t)-1] -} - -// ChildrenMap returns a map containing for each span id the list of its -// direct children. -func ChildrenMap(t pb.Trace) map[uint64][]*pb.Span { - childrenMap := make(map[uint64][]*pb.Span) - - for i := range t { - span := t[i] - if span.ParentID == 0 { - continue - } - childrenMap[span.ParentID] = append(childrenMap[span.ParentID], span) - } - - return childrenMap -} - -// ComputeTopLevel updates all the spans top-level attribute. -// -// A span is considered top-level if: -// - it's a root span -// - OR its parent is unknown (other part of the code, distributed trace) -// - OR its parent belongs to another service (in that case it's a "local root" -// being the highest ancestor of other spans belonging to this service and -// attached to it). -func ComputeTopLevel(trace pb.Trace) { - spanIDToIndex := make(map[uint64]int, len(trace)) - for i, span := range trace { - spanIDToIndex[span.SpanID] = i - } - for _, span := range trace { - if span.ParentID == 0 { - // span is a root span - SetTopLevel(span, true) - continue - } - parentIndex, ok := spanIDToIndex[span.ParentID] - if !ok { - // span has no parent in chunk - SetTopLevel(span, true) - continue - } - if trace[parentIndex].Service != span.Service { - // parent is not in the same service - SetTopLevel(span, true) - continue - } - } -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/trace/traceutil/truncate.go b/vendor/github.com/DataDog/datadog-agent/pkg/trace/traceutil/truncate.go deleted file mode 100644 index 88d34d93..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/trace/traceutil/truncate.go +++ /dev/null @@ -1,37 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package traceutil - -import "unicode/utf8" - -// TruncateUTF8 truncates the given string to make sure it uses less than limit bytes. -// If the last character is an utf8 character that would be splitten, it removes it -// entirely to make sure the resulting string is not broken. -func TruncateUTF8(s string, limit int) string { - if len(s) <= limit { - return s - } - s = s[:limit] - // The max length of a valid code point is 4 bytes, therefore if we see all valid - // code points in the last 4 bytes we know we have a fully valid utf-8 string - // If not we can truncate one byte at a time until the end of the string is valid utf-8 - for len(s) >= 1 { - if len(s) >= 4 && utf8.Valid([]byte(s[len(s)-4:])) { - break - } - if len(s) >= 3 && utf8.Valid([]byte(s[len(s)-3:])) { - break - } - if len(s) >= 2 && utf8.Valid([]byte(s[len(s)-2:])) { - break - } - if len(s) >= 1 && utf8.Valid([]byte(s[len(s)-1:])) { - break - } - s = s[:len(s)-1] - } - return s -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/trace/version/version.go b/vendor/github.com/DataDog/datadog-agent/pkg/trace/version/version.go deleted file mode 100644 index 4a93fd59..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/trace/version/version.go +++ /dev/null @@ -1,78 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -// Package version comprises functions that are used to retrieve *app* version data from incoming traces. -package version - -import ( - "errors" - "strings" - - "github.com/DataDog/datadog-agent/pkg/proto/pbgo/trace" - "github.com/DataDog/datadog-agent/pkg/trace/config" -) - -const ( - versionField = "version" - gitCommitShaField = "_dd.git.commit.sha" - gitCommitShaTagPrefix = "git.commit.sha:" - imageTagPrefix = "image_tag:" -) - -// GetVersionDataFromContainerTags will return the git commit sha and image tag from container tags, if present. -func GetVersionDataFromContainerTags(containerID string, conf *config.AgentConfig) (gitCommitSha, imageTag string, err error) { - if conf == nil || conf.ContainerTags == nil { - return "", "", nil - } - cTags, err := conf.ContainerTags(containerID) - if err != nil { - if errors.Is(err, config.ErrContainerTagsFuncNotDefined) { - return "", "", nil - } - return "", "", err - } - for _, t := range cTags { - if gitCommitSha == "" { - if sha, ok := strings.CutPrefix(t, gitCommitShaTagPrefix); ok { - gitCommitSha = sha - } - } - if imageTag == "" { - if image, ok := strings.CutPrefix(t, imageTagPrefix); ok { - imageTag = image - } - } - if gitCommitSha != "" && imageTag != "" { - break - } - } - return gitCommitSha, imageTag, nil -} - -// GetGitCommitShaFromTrace returns the first "git_commit_sha" tag found in trace t. -func GetGitCommitShaFromTrace(root *trace.Span, t *trace.TraceChunk) string { - return searchTraceForField(root, t, gitCommitShaField) -} - -// GetAppVersionFromTrace returns the first "version" tag found in trace t. -// Search starts by root -func GetAppVersionFromTrace(root *trace.Span, t *trace.TraceChunk) string { - return searchTraceForField(root, t, versionField) -} - -func searchTraceForField(root *trace.Span, t *trace.TraceChunk, field string) string { - if v, ok := root.Meta[field]; ok { - return v - } - for _, s := range t.Spans { - if s.SpanID == root.SpanID { - continue - } - if v, ok := s.Meta[field]; ok { - return v - } - } - return "" -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/trace/watchdog/cpu.go b/vendor/github.com/DataDog/datadog-agent/pkg/trace/watchdog/cpu.go deleted file mode 100644 index a1799701..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/trace/watchdog/cpu.go +++ /dev/null @@ -1,51 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -//go:build !windows && !aix - -// Package watchdog monitors the trace-agent resource usage. -package watchdog - -import ( - "os" - "path/filepath" - "strconv" - - "github.com/DataDog/datadog-agent/pkg/trace/log" - "github.com/shirou/gopsutil/v3/process" -) - -func getpid() int { - // Based on gopsutil's HostProc https://github.com/shirou/gopsutil/blob/672e2518f2ce365ab8504c9f1a8038dc3ad09cf6/internal/common/common.go#L343-L345 - // This PID needs to match the one in the procfs that gopsutil is going to look in. - p := os.Getenv("HOST_PROC") - if p == "" { - p = "/proc" - } - self := filepath.Join(p, "self") - pidf, err := os.Readlink(self) - if err != nil { - log.Warnf("Failed to read pid from %s: %s. Falling back to os.Getpid", self, err) - return os.Getpid() - } - pid, err := strconv.Atoi(filepath.Base(pidf)) - if err != nil { - log.Warnf("Failed to parse pid from %s: %s. Falling back to os.Getpid", pidf, err) - return os.Getpid() - } - return pid -} - -func cpuTimeUser(pid int32) (float64, error) { - p, err := process.NewProcess(pid) - if err != nil { - return 0, err - } - times, err := p.Times() - if err != nil { - return 0, err - } - return times.User, nil -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/trace/watchdog/cpu_aix.go b/vendor/github.com/DataDog/datadog-agent/pkg/trace/watchdog/cpu_aix.go deleted file mode 100644 index 318f098d..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/trace/watchdog/cpu_aix.go +++ /dev/null @@ -1,111 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-2020 Datadog, Inc. - -package watchdog - -import ( - "encoding/binary" - "fmt" - "os" - "time" -) - -// From proc(5) on AIX 7.2 -// status -// Contains state information about the process and one of its -// representative thread. The file is formatted as a struct pstatus -// type containing the following members: -// -// uint32_t pr_flag; /* process flags from proc struct p_flag */ -// uint32_t pr_flag2; /* process flags from proc struct p_flag2 */ -// uint32_t pr_flags; /* /proc flags */ -// uint32_t pr_nlwp; /* number of threads in the process */ -// char pr_stat; /* process state from proc p_stat */ -// char pr_dmodel; /* data model for the process */ -// char pr__pad1[6]; /* reserved for future use */ -// pr_sigset_t pr_sigpend; /* set of process pending signals */ -// prptr64_t pr_brkbase; /* address of the process heap */ -// uint64_t pr_brksize; /* size of the process heap, in bytes */ -// prptr64_t pr_stkbase; /* address of the process stack */ -// uint64_t pr_stksize; /* size of the process stack, in bytes */ -// pid64_t pr_pid; /* process id */ -// pid64_t pr_ppid; /* parent process id */ -// pid64_t pr_pgid; /* process group id */ -// pid64_t pr_sid; /* session id */ -// struct pr_timestruc64_t pr_utime; /* process user cpu time */ -// struct pr_timestruc64_t pr_stime; /* process system cpu time */ -// struct pr_timestruc64_t pr_cutime; /* sum of children's user times */ -// struct pr_timestruc64_t pr_cstime; /* sum of children's system times */ -// pr_sigset_t pr_sigtrace; /* mask of traced signals */ -// fltset_t pr_flttrace; /* mask of traced hardware faults */ -// uint32_t pr_sysentry_offset; /* offset into pstatus file of sysset_t -// * identifying system calls traced on -// -// * entry. If 0, then no entry syscalls -// * are being traced. */ -// uint32_t pr_sysexit_offset; /* offset into pstatus file of sysset_t -// * identifying system calls traced on -// * exit. If 0, then no exit syscalls -// * are being traced. */ -// uint64_t pr__pad[8]; /* reserved for future use */ -// lwpstatus_t pr_lwp; /* "representative" thread status */ -// -// From /usr/include/sys/procfs.h -// typedef struct pr_sigset -// { -// uint64_t ss_set[4]; /* signal set */ -// } pr_sigset_t; -// -// typedef struct pr_timestruc64 -// { -// int64_t tv_sec; /* 64 bit time_t value */ -// int32_t tv_nsec; /* 32 bit suseconds_t value */ -// uint32_t __pad; /* reserved for future use */ -// } pr_timestruc64_t; -// -// typedef void * prptr64_t; -// -// The fields before the user cpu time (pr_utime) are: -// uint32_t pr_flag; 4 4 -// uint32_t pr_flag2; 4 8 -// uint32_t pr_flags; 4 12 -// uint32_t pr_nlwp; 4 16 -// char pr_stat; 1 17 -// char pr_dmodel; 1 18 -// char pr__pad1[6]; 6 24 -// pr_sigset_t pr_sigpend; (4 * 8) = 32 56 -// prptr64_t pr_brkbase; 8 64 -// uint64_t pr_brksize; 8 72 -// prptr64_t pr_stkbase; 8 80 -// uint64_t pr_stksize; 8 88 -// pid64_t pr_pid; 8 96 -// pid64_t pr_ppid; 8 104 -// pid64_t pr_pgid; 8 112 -// pid64_t pr_sid; 8 120 -// total: 120 -// followed by: -// struct pr_timestruc64_t pr_utime; /* process user cpu time */ - -func cpuTimeUser(pid int32) (float64, error) { - f, err := os.Open(fmt.Sprintf("/proc/%d/status", pid)) - if err != nil { - return 0, err - } - defer f.Close() - // As explained above, we will skip 120 bytes into the status file to locate the user CPU time. - f.Seek(120, os.SEEK_SET) - var ( - userSecs int64 - userNsecs int32 - ) - binary.Read(f, binary.BigEndian, &userSecs) - binary.Read(f, binary.BigEndian, &userNsecs) - time := float64(userSecs) + (float64(userNsecs) / float64(time.Second)) - return time, nil -} - -func getpid() int { - return os.Getpid() -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/trace/watchdog/cpu_windows.go b/vendor/github.com/DataDog/datadog-agent/pkg/trace/watchdog/cpu_windows.go deleted file mode 100644 index 6613e30c..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/trace/watchdog/cpu_windows.go +++ /dev/null @@ -1,56 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -// Package watchdog monitors the trace-agent resource usage. -package watchdog - -import ( - "os" - - "golang.org/x/sys/windows" -) - -func getpid() int { - return os.Getpid() -} - -// this code was copied over from shirou/gopsutil/process because we can't import this package on Windows, -// due to its "wmi" dependency. - -func cpuTimeUser(pid int32) (float64, error) { - t, err := getProcessCPUTimes(pid) - if err != nil { - return 0, err - } - return float64(t.UserTime.HighDateTime)*429.4967296 + float64(t.UserTime.LowDateTime)*1e-7, nil -} - -type systemTimes struct { - CreateTime windows.Filetime - ExitTime windows.Filetime - KernelTime windows.Filetime - UserTime windows.Filetime -} - -func getProcessCPUTimes(pid int32) (systemTimes, error) { - var times systemTimes - - // PROCESS_QUERY_LIMITED_INFORMATION is 0x1000 - h, err := windows.OpenProcess(0x1000, false, uint32(pid)) - if err != nil { - return times, err - } - defer windows.CloseHandle(h) - - err = windows.GetProcessTimes( - windows.Handle(h), - ×.CreateTime, - ×.ExitTime, - ×.KernelTime, - ×.UserTime, - ) - - return times, err -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/trace/watchdog/info.go b/vendor/github.com/DataDog/datadog-agent/pkg/trace/watchdog/info.go deleted file mode 100644 index 5522df7f..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/trace/watchdog/info.go +++ /dev/null @@ -1,99 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package watchdog - -import ( - "runtime" - "sync" - "time" -) - -const ( - // cacheDelay should be long enough so that we don't poll the info - // too often and waste resources doing it, and also long enough - // so that it's not jittering (CPU can be volatile). - // OTOH it should be short enough to get up-to-date recent info. - cacheDelay = 20 * time.Second -) - -// CPUInfo contains basic CPU info -type CPUInfo struct { - // UserAvg is the average of the user CPU usage since last time - // it was polled. 0 means "not used at all" and 1 means "1 CPU was - // totally full for that period". So it might be greater than 1 if - // the process is monopolizing several cores. - UserAvg float64 -} - -// MemInfo contains basic memory info -type MemInfo struct { - // Alloc is the number of bytes allocated and not yet freed - // as described in runtime.MemStats.Alloc - Alloc uint64 -} - -// Info contains all the watchdog infos, to be published by expvar -type Info struct { - // CPU contains basic CPU info - CPU CPUInfo - // Mem contains basic Mem info - Mem MemInfo -} - -// CurrentInfo is used to query CPU and Mem info, it keeps data from -// the previous calls to calculate averages. It is not thread safe. -type CurrentInfo struct { - pid int32 - mu sync.Mutex - cacheDelay time.Duration - - lastCPUTime time.Time - lastCPUUser float64 - lastCPU CPUInfo -} - -// NewCurrentInfo creates a new CurrentInfo referring to the current running program. -func NewCurrentInfo() *CurrentInfo { - return &CurrentInfo{ - pid: int32(getpid()), - cacheDelay: cacheDelay, - } -} - -// CPU returns basic CPU info, or the previous valid CPU info and an error. -func (pi *CurrentInfo) CPU(now time.Time) (CPUInfo, error) { - pi.mu.Lock() - defer pi.mu.Unlock() - - dt := now.Sub(pi.lastCPUTime) - if dt <= pi.cacheDelay { - return pi.lastCPU, nil // don't query too often, cache a little bit - } - pi.lastCPUTime = now - - userTime, err := cpuTimeUser(pi.pid) - if err != nil { - return pi.lastCPU, err - } - - dua := userTime - pi.lastCPUUser - pi.lastCPUUser = userTime - if dua <= 0 { - pi.lastCPU.UserAvg = 0 // shouldn't happen, but make sure result is always > 0 - } else { - pi.lastCPU.UserAvg = float64(time.Second) * dua / float64(dt) - pi.lastCPUUser = userTime - } - - return pi.lastCPU, nil -} - -// Mem returns basic memory info. -func (pi *CurrentInfo) Mem() MemInfo { - var ms runtime.MemStats - runtime.ReadMemStats(&ms) - return MemInfo{Alloc: ms.Alloc} -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/trace/watchdog/logonpanic.go b/vendor/github.com/DataDog/datadog-agent/pkg/trace/watchdog/logonpanic.go deleted file mode 100644 index a69934a5..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/trace/watchdog/logonpanic.go +++ /dev/null @@ -1,49 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package watchdog - -import ( - "fmt" - "runtime" - - "github.com/DataDog/datadog-agent/pkg/trace/log" - - "github.com/DataDog/datadog-go/v5/statsd" -) - -const shortErrMsgLen = 17 // 20 char max with tailing "..." - -// shortMsg shortens the length of error message to avoid having high -// cardinality on "err:" tags -func shortErrMsg(msg string) string { - if len(msg) <= shortErrMsgLen { - return msg - } - return msg[:shortErrMsgLen] + "..." -} - -// LogOnPanic catches panics and logs them on the fly. It also flushes -// the log file, ensuring the message appears. Then it propagates the panic -// so that the program flow remains unchanged. -func LogOnPanic(statsd statsd.ClientInterface) { - if err := recover(); err != nil { - // Full print of the trace in the logs - buf := make([]byte, 4096) - length := runtime.Stack(buf, false) - stacktrace := string(buf[:length]) - errMsg := fmt.Sprintf("%v", err) - logMsg := "Unexpected panic: " + errMsg + "\n" + stacktrace - - _ = statsd.Gauge("datadog.trace_agent.panic", 1, []string{ - "err:" + shortErrMsg(errMsg), - }, 1) - - log.Error(logMsg) - log.Flush() - - panic(err) - } -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/util/log/LICENSE b/vendor/github.com/DataDog/datadog-agent/pkg/util/log/LICENSE deleted file mode 100644 index b370545b..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/util/log/LICENSE +++ /dev/null @@ -1,200 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2016-present Datadog, Inc. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/util/log/klog_redirect.go b/vendor/github.com/DataDog/datadog-agent/pkg/util/log/klog_redirect.go deleted file mode 100644 index fad01af4..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/util/log/klog_redirect.go +++ /dev/null @@ -1,59 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package log - -import "strings" - -// KlogRedirectLogger is used to redirect klog logs to datadog logs. klog is -// client-go's logger, logging to STDERR by default, which makes all severities -// into ERROR, along with the formatting just being off. To make the -// conversion, we set a KlogRedirectLogger as klog's output, and parse the severity -// and log message out of every log line. -// NOTE: on klog v2 this parsing is no longer necessary, as it allows us to use -// kSetLogger() instead of kSetOutputBySeverity(). unfortunately we -// still have some dependencies stuck on v1, so we keep the parsing. -type KlogRedirectLogger struct { - stackDepth int -} - -// NewKlogRedirectLogger creates a new KlogRedirectLogger with provided stack depth -func NewKlogRedirectLogger(stackDepth int) KlogRedirectLogger { - return KlogRedirectLogger{ - stackDepth: stackDepth, - } -} - -func (l KlogRedirectLogger) Write(b []byte) (int, error) { - // klog log lines have the following format: - // Lmmdd hh:mm:ss.uuuuuu threadid file:line] msg... - // so we parse L to decide in which level to log, and we try to find - // the ']' character, to ignore anything up to that point, as we don't - // care about the header outside of the log level. - - msg := string(b) - - i := strings.IndexByte(msg, ']') - if i >= 0 { - // if we find a ']', we ignore anything 2 positions from it - // (itself, plus a blank space) - msg = msg[i+2:] - } - - switch b[0] { - case 'I': - InfoStackDepth(l.stackDepth, msg) - case 'W': - _ = WarnStackDepth(l.stackDepth, msg) - case 'E': - _ = ErrorStackDepth(l.stackDepth, msg) - case 'F': - _ = CriticalStackDepth(l.stackDepth, msg) - default: - InfoStackDepth(l.stackDepth, msg) - } - - return 0, nil -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/util/log/log.go b/vendor/github.com/DataDog/datadog-agent/pkg/util/log/log.go deleted file mode 100644 index 0e1ecaa2..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/util/log/log.go +++ /dev/null @@ -1,1046 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -// Package log implements logging for the datadog agent. It wraps seelog, and -// supports logging to multiple destinations, buffering messages logged before -// setup, and scrubbing secrets from log messages. -// -// # Compatibility -// -// This module is exported and can be used outside of the datadog-agent -// repository, but is not designed as a general-purpose logging system. Its -// API may change incompatibly. -package log - -import ( - "bytes" - "errors" - "fmt" - "os" - "strings" - "sync" - - "github.com/cihub/seelog" - "go.uber.org/atomic" - - "github.com/DataDog/datadog-agent/pkg/util/scrubber" -) - -type loggerPointer struct { - atomic.Pointer[DatadogLogger] -} - -var ( - // Logger is the main DatadogLogger - logger loggerPointer - jmxLogger loggerPointer - - // This buffer holds log lines sent to the logger before its - // initialization. Even if initializing the logger is one of the first - // things the agent does, we still: load the conf, resolve secrets inside, - // compute the final proxy settings, ... - // - // This buffer should be very short lived. - logsBuffer = []func(){} - bufferMutex sync.Mutex - defaultStackDepth = 3 - - // for testing purposes - scrubBytesFunc = scrubber.ScrubBytes -) - -// DatadogLogger wrapper structure for seelog -type DatadogLogger struct { - inner seelog.LoggerInterface - level seelog.LogLevel - extra map[string]seelog.LoggerInterface - l sync.RWMutex -} - -/* -* Setup and initialization of the logger - */ - -// SetupLogger setup agent wide logger -func SetupLogger(i seelog.LoggerInterface, level string) { - logger.Store(setupCommonLogger(i, level)) - - // Flush the log entries logged before initialization now that the logger is initialized - bufferMutex.Lock() - defer bufferMutex.Unlock() - for _, logLine := range logsBuffer { - logLine() - } - logsBuffer = []func(){} -} - -func setupCommonLogger(i seelog.LoggerInterface, level string) *DatadogLogger { - l := &DatadogLogger{ - inner: i, - extra: make(map[string]seelog.LoggerInterface), - } - - lvl, ok := seelog.LogLevelFromString(level) - if !ok { - lvl = seelog.InfoLvl - } - l.level = lvl - - // We're not going to call DatadogLogger directly, but using the - // exported functions, that will give us two frames in the stack - // trace that should be skipped to get to the original caller. - // - // The fact we need a constant "additional depth" means some - // theoretical refactor to avoid duplication in the functions - // below cannot be performed. - l.inner.SetAdditionalStackDepth(defaultStackDepth) //nolint:errcheck - - return l -} - -func addLogToBuffer(logHandle func()) { - bufferMutex.Lock() - defer bufferMutex.Unlock() - - logsBuffer = append(logsBuffer, logHandle) -} - -func (sw *DatadogLogger) scrub(s string) string { - if scrubbed, err := scrubBytesFunc([]byte(s)); err == nil { - return string(scrubbed) - } - return s -} - -/* -* Operation on the **logger level** - */ - -// ChangeLogLevel changes the current log level, valid levels are trace, debug, -// info, warn, error, critical and off, it requires a new seelog logger because -// an existing one cannot be updated -func ChangeLogLevel(li seelog.LoggerInterface, level string) error { - if err := logger.changeLogLevel(level); err != nil { - return err - } - - // See detailed explanation in SetupLogger(...) - if err := li.SetAdditionalStackDepth(defaultStackDepth); err != nil { - return err - } - - logger.replaceInnerLogger(li) - return nil - - // need to return something, just set to Info (expected default) -} -func (sw *loggerPointer) changeLogLevel(level string) error { - l := sw.Load() - if l == nil { - return errors.New("cannot change loglevel: logger not initialized") - } - - l.l.Lock() - defer l.l.Unlock() - - if l.inner == nil { - return errors.New("cannot change loglevel: logger is initialized however logger.inner is nil") - } - - lvl, ok := seelog.LogLevelFromString(strings.ToLower(level)) - if !ok { - return errors.New("bad log level") - } - l.level = lvl - return nil -} - -// GetLogLevel returns a seelog native representation of the current log level -func GetLogLevel() (seelog.LogLevel, error) { - return logger.getLogLevel() -} -func (sw *loggerPointer) getLogLevel() (seelog.LogLevel, error) { - l := sw.Load() - if l == nil { - return seelog.InfoLvl, errors.New("cannot get loglevel: logger not initialized") - } - - l.l.RLock() - defer l.l.RUnlock() - - if l.inner == nil { - return seelog.InfoLvl, errors.New("cannot get loglevel: logger not initialized") - } - - return l.level, nil -} - -// ShouldLog returns whether a given log level should be logged by the default logger -func ShouldLog(lvl seelog.LogLevel) bool { - // The lock stay in the exported function due to the use of `shouldLog` in function that already hold the lock - l := logger.Load() - if l != nil { - l.l.RLock() - defer l.l.RUnlock() - return l.shouldLog(lvl) - } - return false -} - -// This function should be called with `sw.l` held -func (sw *DatadogLogger) shouldLog(level seelog.LogLevel) bool { - return level >= sw.level -} - -// ValidateLogLevel validates the given log level and returns the corresponding Seelog log level. -// If the log level is "warning", it is converted to "warn" to handle a common gotcha when used with agent5. -// If the log level is not recognized, an error is returned. -func ValidateLogLevel(logLevel string) (string, error) { - seelogLogLevel := strings.ToLower(logLevel) - if seelogLogLevel == "warning" { // Common gotcha when used to agent5 - seelogLogLevel = "warn" - } - - if _, found := seelog.LogLevelFromString(seelogLogLevel); !found { - return "", fmt.Errorf("unknown log level: %s", seelogLogLevel) - } - return seelogLogLevel, nil -} - -/* -* Operation on the **logger** - */ - -// RegisterAdditionalLogger registers an additional logger for logging -func RegisterAdditionalLogger(n string, li seelog.LoggerInterface) error { - return logger.registerAdditionalLogger(n, li) -} -func (sw *loggerPointer) registerAdditionalLogger(n string, li seelog.LoggerInterface) error { - l := sw.Load() - if l == nil { - return errors.New("cannot register: logger not initialized") - } - - l.l.Lock() - defer l.l.Unlock() - - if l.inner == nil { - return errors.New("cannot register: logger not initialized") - } - - if l.extra == nil { - - return errors.New("logger not fully initialized, additional logging unavailable") - } - - if _, ok := l.extra[n]; ok { - return errors.New("logger already registered with that name") - } - l.extra[n] = li - - return nil -} - -// ReplaceLogger allows replacing the internal logger, returns old logger -func ReplaceLogger(li seelog.LoggerInterface) seelog.LoggerInterface { - return logger.replaceInnerLogger(li) -} -func (sw *loggerPointer) replaceInnerLogger(li seelog.LoggerInterface) seelog.LoggerInterface { - l := sw.Load() - if l == nil { - return nil // Return nil if logger is not initialized - } - - l.l.Lock() - defer l.l.Unlock() - - if l.inner == nil { - return nil // Return nil if logger.inner is not initialized - } - - old := l.inner - l.inner = li - - return old -} - -// Flush flushes the underlying inner log -func Flush() { - logger.flush() - jmxLogger.flush() -} -func (sw *loggerPointer) flush() { - l := sw.Load() - if l == nil { - return - } - - l.l.Lock() - defer l.l.Unlock() - - if l.inner != nil { - l.inner.Flush() - } -} - -/* -* log functions - */ - -// log logs a message at the given level, using either bufferFunc (if logging is not yet set up) or -// scrubAndLogFunc, and treating the variadic args as the message. -func log(logLevel seelog.LogLevel, bufferFunc func(), scrubAndLogFunc func(string), v ...interface{}) { - l := logger.Load() - - if l == nil { - addLogToBuffer(bufferFunc) - return - } - - l.l.Lock() - defer l.l.Unlock() - - if l.inner == nil { - addLogToBuffer(bufferFunc) - } else if l.shouldLog(logLevel) { - s := BuildLogEntry(v...) - scrubAndLogFunc(s) - } - -} -func logWithError(logLevel seelog.LogLevel, bufferFunc func(), scrubAndLogFunc func(string) error, fallbackStderr bool, v ...interface{}) error { - l := logger.Load() - - if l == nil { - addLogToBuffer(bufferFunc) - err := formatError(v...) - if fallbackStderr { - fmt.Fprintf(os.Stderr, "%s: %s\n", logLevel.String(), err.Error()) - } - return err - } - - l.l.Lock() - - isInnerNil := l.inner == nil - - if isInnerNil { - if !fallbackStderr { - addLogToBuffer(bufferFunc) - } - } else if l.shouldLog(logLevel) { - defer l.l.Unlock() - s := BuildLogEntry(v...) - return scrubAndLogFunc(s) - } - - l.l.Unlock() - - err := formatError(v...) - // Originally (PR 6436) fallbackStderr check had been added to handle a small window - // where error messages had been lost before Logger had been initialized. Adjusting - // just for that case because if the error log should not be logged - because it has - // been suppressed then it should be taken into account. - if fallbackStderr && isInnerNil { - fmt.Fprintf(os.Stderr, "%s: %s\n", logLevel.String(), err.Error()) - } - return err -} - -/* -* logFormat functions - */ - -func logFormat(logLevel seelog.LogLevel, bufferFunc func(), scrubAndLogFunc func(string, ...interface{}), format string, params ...interface{}) { - l := logger.Load() - - if l == nil { - addLogToBuffer(bufferFunc) - return - } - - l.l.Lock() - defer l.l.Unlock() - - if l.inner == nil { - addLogToBuffer(bufferFunc) - } else if l.shouldLog(logLevel) { - scrubAndLogFunc(format, params...) - } -} -func logFormatWithError(logLevel seelog.LogLevel, bufferFunc func(), scrubAndLogFunc func(string, ...interface{}) error, format string, fallbackStderr bool, params ...interface{}) error { - l := logger.Load() - - if l == nil { - addLogToBuffer(bufferFunc) - err := formatErrorf(format, params...) - if fallbackStderr { - fmt.Fprintf(os.Stderr, "%s: %s\n", logLevel.String(), err.Error()) - } - return err - } - - l.l.Lock() - - isInnerNil := l.inner == nil - - if isInnerNil { - if !fallbackStderr { - addLogToBuffer(bufferFunc) - } - } else if l.shouldLog(logLevel) { - defer l.l.Unlock() - return scrubAndLogFunc(format, params...) - } - - l.l.Unlock() - - err := formatErrorf(format, params...) - // Originally (PR 6436) fallbackStderr check had been added to handle a small window - // where error messages had been lost before Logger had been initialized. Adjusting - // just for that case because if the error log should not be logged - because it has - // been suppressed then it should be taken into account. - if fallbackStderr && isInnerNil { - fmt.Fprintf(os.Stderr, "%s: %s\n", logLevel.String(), err.Error()) - } - return err -} - -/* -* logContext functions - */ - -func logContext(logLevel seelog.LogLevel, bufferFunc func(), scrubAndLogFunc func(string), message string, depth int, context ...interface{}) { - l := logger.Load() - - if l == nil { - addLogToBuffer(bufferFunc) - return - } - - l.l.Lock() - defer l.l.Unlock() - - if l.inner == nil { - addLogToBuffer(bufferFunc) - } else if l.shouldLog(logLevel) { - l.inner.SetContext(context) - l.inner.SetAdditionalStackDepth(defaultStackDepth + depth) //nolint:errcheck - scrubAndLogFunc(message) - l.inner.SetContext(nil) - l.inner.SetAdditionalStackDepth(defaultStackDepth) //nolint:errcheck - } -} -func logContextWithError(logLevel seelog.LogLevel, bufferFunc func(), scrubAndLogFunc func(string) error, message string, fallbackStderr bool, depth int, context ...interface{}) error { - l := logger.Load() - - if l == nil { - addLogToBuffer(bufferFunc) - err := formatErrorc(message, context...) - if fallbackStderr { - fmt.Fprintf(os.Stderr, "%s: %s\n", logLevel.String(), err.Error()) - } - return err - } - - l.l.Lock() - - isInnerNil := l.inner == nil - - if isInnerNil { - if !fallbackStderr { - addLogToBuffer(bufferFunc) - } - } else if l.shouldLog(logLevel) { - l.inner.SetContext(context) - l.inner.SetAdditionalStackDepth(defaultStackDepth + depth) //nolint:errcheck - err := scrubAndLogFunc(message) - l.inner.SetContext(nil) - l.inner.SetAdditionalStackDepth(defaultStackDepth) //nolint:errcheck - defer l.l.Unlock() - return err - } - - l.l.Unlock() - - err := formatErrorc(message, context...) - if fallbackStderr && isInnerNil { - fmt.Fprintf(os.Stderr, "%s: %s\n", logLevel.String(), err.Error()) - } - return err -} - -// trace logs at the trace level, called with sw.l held -func (sw *loggerPointer) trace(s string) { - l := sw.Load() - - if l == nil { - return - } - - scrubbed := l.scrub(s) - l.inner.Trace(scrubbed) - - for _, l := range l.extra { - l.Trace(scrubbed) - } -} - -// trace logs at the trace level and the current stack depth plus the -// additional given one, called with sw.l held -func (sw *loggerPointer) traceStackDepth(s string, depth int) { - l := sw.Load() - scrubbed := l.scrub(s) - - l.inner.SetAdditionalStackDepth(defaultStackDepth + depth) //nolint:errcheck - l.inner.Trace(scrubbed) - l.inner.SetAdditionalStackDepth(defaultStackDepth) //nolint:errcheck - - for _, l := range l.extra { - l.Trace(scrubbed) - } -} - -// debug logs at the debug level, called with sw.l held -func (sw *loggerPointer) debug(s string) { - l := sw.Load() - scrubbed := l.scrub(s) - l.inner.Debug(scrubbed) - - for _, l := range l.extra { - l.Debug(scrubbed) - } -} - -// debug logs at the debug level and the current stack depth plus the additional given one, called with sw.l held -func (sw *loggerPointer) debugStackDepth(s string, depth int) { - l := sw.Load() - scrubbed := l.scrub(s) - l.inner.SetAdditionalStackDepth(defaultStackDepth + depth) //nolint:errcheck - l.inner.Debug(scrubbed) - l.inner.SetAdditionalStackDepth(defaultStackDepth) //nolint:errcheck - - for _, l := range l.extra { - l.Debug(scrubbed) //nolint:errcheck - } -} - -// info logs at the info level, called with sw.l held -func (sw *loggerPointer) info(s string) { - l := sw.Load() - scrubbed := l.scrub(s) - l.inner.Info(scrubbed) - for _, l := range l.extra { - l.Info(scrubbed) - } -} - -// info logs at the info level and the current stack depth plus the additional given one, called with sw.l held -func (sw *loggerPointer) infoStackDepth(s string, depth int) { - l := sw.Load() - scrubbed := l.scrub(s) - l.inner.SetAdditionalStackDepth(defaultStackDepth + depth) //nolint:errcheck - l.inner.Info(scrubbed) - l.inner.SetAdditionalStackDepth(defaultStackDepth) //nolint:errcheck - - for _, l := range l.extra { - l.Info(scrubbed) //nolint:errcheck - } -} - -// warn logs at the warn level, called with sw.l held -func (sw *loggerPointer) warn(s string) error { - l := sw.Load() - scrubbed := l.scrub(s) - err := l.inner.Warn(scrubbed) - - for _, l := range l.extra { - l.Warn(scrubbed) //nolint:errcheck - } - - return err -} - -// error logs at the error level and the current stack depth plus the additional given one, called with sw.l held -func (sw *loggerPointer) warnStackDepth(s string, depth int) error { - l := sw.Load() - scrubbed := l.scrub(s) - l.inner.SetAdditionalStackDepth(defaultStackDepth + depth) //nolint:errcheck - err := l.inner.Warn(scrubbed) - l.inner.SetAdditionalStackDepth(defaultStackDepth) //nolint:errcheck - - for _, l := range l.extra { - l.Warn(scrubbed) //nolint:errcheck - } - - return err -} - -// error logs at the error level, called with sw.l held -func (sw *loggerPointer) error(s string) error { - l := sw.Load() - scrubbed := l.scrub(s) - err := l.inner.Error(scrubbed) - - for _, l := range l.extra { - l.Error(scrubbed) //nolint:errcheck - } - - return err -} - -// error logs at the error level and the current stack depth plus the additional given one, called with sw.l held -func (sw *loggerPointer) errorStackDepth(s string, depth int) error { - l := sw.Load() - scrubbed := l.scrub(s) - l.inner.SetAdditionalStackDepth(defaultStackDepth + depth) //nolint:errcheck - err := l.inner.Error(scrubbed) - l.inner.SetAdditionalStackDepth(defaultStackDepth) //nolint:errcheck - - for _, l := range l.extra { - l.Error(scrubbed) //nolint:errcheck - } - - return err -} - -// critical logs at the critical level, called with sw.l held -func (sw *loggerPointer) critical(s string) error { - l := sw.Load() - scrubbed := l.scrub(s) - err := l.inner.Critical(scrubbed) - - for _, l := range l.extra { - l.Critical(scrubbed) //nolint:errcheck - } - - return err -} - -// critical logs at the critical level and the current stack depth plus the additional given one, called with sw.l held -func (sw *loggerPointer) criticalStackDepth(s string, depth int) error { - l := sw.Load() - scrubbed := l.scrub(s) - l.inner.SetAdditionalStackDepth(defaultStackDepth + depth) //nolint:errcheck - err := l.inner.Critical(scrubbed) - l.inner.SetAdditionalStackDepth(defaultStackDepth) //nolint:errcheck - - for _, l := range l.extra { - l.Critical(scrubbed) //nolint:errcheck - } - - return err -} - -// tracef logs with format at the trace level, called with sw.l held -func (sw *loggerPointer) tracef(format string, params ...interface{}) { - l := sw.Load() - scrubbed := l.scrub(fmt.Sprintf(format, params...)) - l.inner.Trace(scrubbed) - - for _, l := range l.extra { - l.Trace(scrubbed) - } -} - -// debugf logs with format at the debug level, called with sw.l held -func (sw *loggerPointer) debugf(format string, params ...interface{}) { - l := sw.Load() - scrubbed := l.scrub(fmt.Sprintf(format, params...)) - l.inner.Debug(scrubbed) - - for _, l := range l.extra { - l.Debug(scrubbed) - } -} - -// infof logs with format at the info level, called with sw.l held -func (sw *loggerPointer) infof(format string, params ...interface{}) { - l := sw.Load() - scrubbed := l.scrub(fmt.Sprintf(format, params...)) - l.inner.Info(scrubbed) - - for _, l := range l.extra { - l.Info(scrubbed) - } -} - -// warnf logs with format at the warn level, called with sw.l held -func (sw *loggerPointer) warnf(format string, params ...interface{}) error { - l := sw.Load() - scrubbed := l.scrub(fmt.Sprintf(format, params...)) - err := l.inner.Warn(scrubbed) - - for _, l := range l.extra { - l.Warn(scrubbed) //nolint:errcheck - } - - return err -} - -// errorf logs with format at the error level, called with sw.l held -func (sw *loggerPointer) errorf(format string, params ...interface{}) error { - l := sw.Load() - scrubbed := l.scrub(fmt.Sprintf(format, params...)) - err := l.inner.Error(scrubbed) - - for _, l := range l.extra { - l.Error(scrubbed) //nolint:errcheck - } - - return err -} - -// criticalf logs with format at the critical level, called with sw.l held -func (sw *loggerPointer) criticalf(format string, params ...interface{}) error { - l := sw.Load() - scrubbed := l.scrub(fmt.Sprintf(format, params...)) - err := l.inner.Critical(scrubbed) - - for _, l := range l.extra { - l.Critical(scrubbed) //nolint:errcheck - } - - return err -} - -// BuildLogEntry concatenates all inputs with spaces -func BuildLogEntry(v ...interface{}) string { - var fmtBuffer bytes.Buffer - - for i := 0; i < len(v)-1; i++ { - fmtBuffer.WriteString("%v ") - } - fmtBuffer.WriteString("%v") - - return fmt.Sprintf(fmtBuffer.String(), v...) -} - -func scrubMessage(message string) string { - msgScrubbed, err := scrubBytesFunc([]byte(message)) - if err == nil { - return string(msgScrubbed) - } - return "[REDACTED] - failure to clean the message" -} - -func formatErrorf(format string, params ...interface{}) error { - msg := scrubMessage(fmt.Sprintf(format, params...)) - return errors.New(msg) -} - -func formatError(v ...interface{}) error { - msg := scrubMessage(fmt.Sprint(v...)) - return errors.New(msg) -} - -func formatErrorc(message string, context ...interface{}) error { - // Build a format string like this: - // message (%s:%v, %s:%v, ... %s:%v) - var fmtBuffer bytes.Buffer - fmtBuffer.WriteString(message) - if len(context) > 0 && len(context)%2 == 0 { - fmtBuffer.WriteString(" (") - for i := 0; i < len(context); i += 2 { - fmtBuffer.WriteString("%s:%v") - if i != len(context)-2 { - fmtBuffer.WriteString(", ") - } - } - fmtBuffer.WriteString(")") - } - - msg := fmt.Sprintf(fmtBuffer.String(), context...) - return errors.New(scrubMessage(msg)) -} - -// Trace logs at the trace level -func Trace(v ...interface{}) { - log(seelog.TraceLvl, func() { Trace(v...) }, logger.trace, v...) -} - -// Tracef logs with format at the trace level -func Tracef(format string, params ...interface{}) { - logFormat(seelog.TraceLvl, func() { Tracef(format, params...) }, logger.tracef, format, params...) -} - -// TracefStackDepth logs with format at the trace level and the current stack depth plus the given depth -func TracefStackDepth(depth int, format string, params ...interface{}) { - currentLevel, _ := GetLogLevel() - if currentLevel > seelog.TraceLvl { - return - } - msg := fmt.Sprintf(format, params...) - log(seelog.TraceLvl, func() { TraceStackDepth(depth, msg) }, func(s string) { - logger.traceStackDepth(s, depth) - }, msg) -} - -// TracecStackDepth logs at the trace level with context and the current stack depth plus the additional given one -func TracecStackDepth(message string, depth int, context ...interface{}) { - logContext(seelog.TraceLvl, func() { Tracec(message, context...) }, logger.trace, message, depth, context...) -} - -// Tracec logs at the trace level with context -func Tracec(message string, context ...interface{}) { - TracecStackDepth(message, 1, context...) -} - -// TraceFunc calls and logs the result of 'logFunc' if and only if Trace (or more verbose) logs are enabled -func TraceFunc(logFunc func() string) { - currentLevel, _ := GetLogLevel() - if currentLevel <= seelog.TraceLvl { - TraceStackDepth(2, logFunc()) - } -} - -// Debug logs at the debug level -func Debug(v ...interface{}) { - log(seelog.DebugLvl, func() { Debug(v...) }, logger.debug, v...) -} - -// Debugf logs with format at the debug level -func Debugf(format string, params ...interface{}) { - logFormat(seelog.DebugLvl, func() { Debugf(format, params...) }, logger.debugf, format, params...) -} - -// DebugfStackDepth logs with format at the debug level and the current stack depth plus the given depth -func DebugfStackDepth(depth int, format string, params ...interface{}) { - currentLevel, _ := GetLogLevel() - if currentLevel > seelog.DebugLvl { - return - } - msg := fmt.Sprintf(format, params...) - log(seelog.DebugLvl, func() { DebugStackDepth(depth, msg) }, func(s string) { - logger.debugStackDepth(s, depth) - }, msg) -} - -// DebugcStackDepth logs at the debug level with context and the current stack depth plus the additional given one -func DebugcStackDepth(message string, depth int, context ...interface{}) { - logContext(seelog.DebugLvl, func() { Debugc(message, context...) }, logger.debug, message, depth, context...) -} - -// Debugc logs at the debug level with context -func Debugc(message string, context ...interface{}) { - DebugcStackDepth(message, 1, context...) -} - -// DebugFunc calls and logs the result of 'logFunc' if and only if Debug (or more verbose) logs are enabled -func DebugFunc(logFunc func() string) { - currentLevel, _ := GetLogLevel() - if currentLevel <= seelog.DebugLvl { - DebugStackDepth(2, logFunc()) - } -} - -// Info logs at the info level -func Info(v ...interface{}) { - log(seelog.InfoLvl, func() { Info(v...) }, logger.info, v...) -} - -// Infof logs with format at the info level -func Infof(format string, params ...interface{}) { - logFormat(seelog.InfoLvl, func() { Infof(format, params...) }, logger.infof, format, params...) -} - -// InfofStackDepth logs with format at the info level and the current stack depth plus the given depth -func InfofStackDepth(depth int, format string, params ...interface{}) { - currentLevel, _ := GetLogLevel() - if currentLevel > seelog.InfoLvl { - return - } - msg := fmt.Sprintf(format, params...) - log(seelog.InfoLvl, func() { InfoStackDepth(depth, msg) }, func(s string) { - logger.infoStackDepth(s, depth) - }, msg) -} - -// InfocStackDepth logs at the info level with context and the current stack depth plus the additional given one -func InfocStackDepth(message string, depth int, context ...interface{}) { - logContext(seelog.InfoLvl, func() { Infoc(message, context...) }, logger.info, message, depth, context...) -} - -// Infoc logs at the info level with context -func Infoc(message string, context ...interface{}) { - InfocStackDepth(message, 1, context...) -} - -// InfoFunc calls and logs the result of 'logFunc' if and only if Info (or more verbose) logs are enabled -func InfoFunc(logFunc func() string) { - currentLevel, _ := GetLogLevel() - if currentLevel <= seelog.InfoLvl { - InfoStackDepth(2, logFunc()) - } -} - -// Warn logs at the warn level and returns an error containing the formated log message -func Warn(v ...interface{}) error { - return logWithError(seelog.WarnLvl, func() { _ = Warn(v...) }, logger.warn, false, v...) -} - -// Warnf logs with format at the warn level and returns an error containing the formated log message -func Warnf(format string, params ...interface{}) error { - return logFormatWithError(seelog.WarnLvl, func() { _ = Warnf(format, params...) }, logger.warnf, format, false, params...) -} - -// WarnfStackDepth logs with format at the warn level and the current stack depth plus the given depth -func WarnfStackDepth(depth int, format string, params ...interface{}) error { - msg := fmt.Sprintf(format, params...) - return logWithError(seelog.WarnLvl, func() { _ = WarnStackDepth(depth, msg) }, func(s string) error { - return logger.warnStackDepth(s, depth) - }, false, msg) -} - -// WarncStackDepth logs at the warn level with context and the current stack depth plus the additional given one and returns an error containing the formated log message -func WarncStackDepth(message string, depth int, context ...interface{}) error { - return logContextWithError(seelog.WarnLvl, func() { _ = Warnc(message, context...) }, logger.warn, message, false, depth, context...) -} - -// Warnc logs at the warn level with context and returns an error containing the formated log message -func Warnc(message string, context ...interface{}) error { - return WarncStackDepth(message, 1, context...) -} - -// WarnFunc calls and logs the result of 'logFunc' if and only if Warn (or more verbose) logs are enabled -func WarnFunc(logFunc func() string) { - currentLevel, _ := GetLogLevel() - if currentLevel <= seelog.WarnLvl { - _ = WarnStackDepth(2, logFunc()) - } -} - -// Error logs at the error level and returns an error containing the formated log message -func Error(v ...interface{}) error { - return logWithError(seelog.ErrorLvl, func() { _ = Error(v...) }, logger.error, true, v...) -} - -// Errorf logs with format at the error level and returns an error containing the formated log message -func Errorf(format string, params ...interface{}) error { - return logFormatWithError(seelog.ErrorLvl, func() { _ = Errorf(format, params...) }, logger.errorf, format, true, params...) -} - -// ErrorfStackDepth logs with format at the error level and the current stack depth plus the given depth -func ErrorfStackDepth(depth int, format string, params ...interface{}) error { - msg := fmt.Sprintf(format, params...) - return logWithError(seelog.ErrorLvl, func() { _ = ErrorStackDepth(depth, msg) }, func(s string) error { - return logger.errorStackDepth(s, depth) - }, true, msg) -} - -// ErrorcStackDepth logs at the error level with context and the current stack depth plus the additional given one and returns an error containing the formated log message -func ErrorcStackDepth(message string, depth int, context ...interface{}) error { - return logContextWithError(seelog.ErrorLvl, func() { _ = Errorc(message, context...) }, logger.error, message, true, depth, context...) -} - -// Errorc logs at the error level with context and returns an error containing the formated log message -func Errorc(message string, context ...interface{}) error { - return ErrorcStackDepth(message, 1, context...) -} - -// ErrorFunc calls and logs the result of 'logFunc' if and only if Error (or more verbose) logs are enabled -func ErrorFunc(logFunc func() string) { - currentLevel, _ := GetLogLevel() - if currentLevel <= seelog.ErrorLvl { - _ = ErrorStackDepth(2, logFunc()) - } -} - -// Critical logs at the critical level and returns an error containing the formated log message -func Critical(v ...interface{}) error { - return logWithError(seelog.CriticalLvl, func() { _ = Critical(v...) }, logger.critical, true, v...) -} - -// Criticalf logs with format at the critical level and returns an error containing the formated log message -func Criticalf(format string, params ...interface{}) error { - return logFormatWithError(seelog.CriticalLvl, func() { _ = Criticalf(format, params...) }, logger.criticalf, format, true, params...) -} - -// CriticalfStackDepth logs with format at the critical level and the current stack depth plus the given depth -func CriticalfStackDepth(depth int, format string, params ...interface{}) error { - msg := fmt.Sprintf(format, params...) - return logWithError(seelog.CriticalLvl, func() { _ = CriticalStackDepth(depth, msg) }, func(s string) error { - return logger.criticalStackDepth(s, depth) - }, false, msg) -} - -// CriticalcStackDepth logs at the critical level with context and the current stack depth plus the additional given one and returns an error containing the formated log message -func CriticalcStackDepth(message string, depth int, context ...interface{}) error { - return logContextWithError(seelog.CriticalLvl, func() { _ = Criticalc(message, context...) }, logger.critical, message, true, depth, context...) -} - -// Criticalc logs at the critical level with context and returns an error containing the formated log message -func Criticalc(message string, context ...interface{}) error { - return CriticalcStackDepth(message, 1, context...) -} - -// CriticalFunc calls and logs the result of 'logFunc' if and only if Critical (or more verbose) logs are enabled -func CriticalFunc(logFunc func() string) { - currentLevel, _ := GetLogLevel() - if currentLevel <= seelog.CriticalLvl { - _ = CriticalStackDepth(2, logFunc()) - } -} - -// InfoStackDepth logs at the info level and the current stack depth plus the additional given one -func InfoStackDepth(depth int, v ...interface{}) { - log(seelog.InfoLvl, func() { InfoStackDepth(depth, v...) }, func(s string) { - logger.infoStackDepth(s, depth) - }, v...) -} - -// WarnStackDepth logs at the warn level and the current stack depth plus the additional given one and returns an error containing the formated log message -func WarnStackDepth(depth int, v ...interface{}) error { - return logWithError(seelog.WarnLvl, func() { _ = WarnStackDepth(depth, v...) }, func(s string) error { - return logger.warnStackDepth(s, depth) - }, false, v...) -} - -// DebugStackDepth logs at the debug level and the current stack depth plus the additional given one and returns an error containing the formated log message -func DebugStackDepth(depth int, v ...interface{}) { - log(seelog.DebugLvl, func() { DebugStackDepth(depth, v...) }, func(s string) { - logger.debugStackDepth(s, depth) - }, v...) -} - -// TraceStackDepth logs at the trace level and the current stack depth plus the additional given one and returns an error containing the formated log message -func TraceStackDepth(depth int, v ...interface{}) { - log(seelog.TraceLvl, func() { TraceStackDepth(depth, v...) }, func(s string) { - logger.traceStackDepth(s, depth) - }, v...) -} - -// ErrorStackDepth logs at the error level and the current stack depth plus the additional given one and returns an error containing the formated log message -func ErrorStackDepth(depth int, v ...interface{}) error { - return logWithError(seelog.ErrorLvl, func() { _ = ErrorStackDepth(depth, v...) }, func(s string) error { - return logger.errorStackDepth(s, depth) - }, true, v...) -} - -// CriticalStackDepth logs at the critical level and the current stack depth plus the additional given one and returns an error containing the formated log message -func CriticalStackDepth(depth int, v ...interface{}) error { - return logWithError(seelog.CriticalLvl, func() { _ = CriticalStackDepth(depth, v...) }, func(s string) error { - return logger.criticalStackDepth(s, depth) - }, true, v...) -} - -/* -* JMX Logger Section - */ - -// JMXError Logs for JMX check -func JMXError(v ...interface{}) error { - return logWithError(seelog.ErrorLvl, func() { _ = JMXError(v...) }, jmxLogger.error, true, v...) -} - -// JMXInfo Logs -func JMXInfo(v ...interface{}) { - log(seelog.InfoLvl, func() { JMXInfo(v...) }, jmxLogger.info, v...) -} - -// SetupJMXLogger setup JMXfetch specific logger -func SetupJMXLogger(i seelog.LoggerInterface, level string) { - jmxLogger.Store(setupCommonLogger(i, level)) -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/util/log/log_limit.go b/vendor/github.com/DataDog/datadog-agent/pkg/util/log/log_limit.go deleted file mode 100644 index 290382f3..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/util/log/log_limit.go +++ /dev/null @@ -1,74 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package log - -import ( - "time" - - "go.uber.org/atomic" -) - -// Limit is a utility that can be used to avoid logging noisily -type Limit struct { - // n is the times remaining that the Limit will return true for ShouldLog. - // we repeatedly subtract 1 from it, if it is nonzero. - n *atomic.Int32 - - // exit and ticker must be different channels - // because Stopping a ticker will not close the ticker channel, - // and we will otherwise leak memory - ticker *time.Ticker - exit chan struct{} -} - -// NewLogLimit creates a Limit where shouldLog will return -// true the first N times it is called, and will return true once every -// interval thereafter. -func NewLogLimit(n int, interval time.Duration) *Limit { - l := &Limit{ - n: atomic.NewInt32(int32(n)), - ticker: time.NewTicker(interval), - exit: make(chan struct{}), - } - - go l.resetLoop() - return l -} - -// ShouldLog returns true if the caller should log -func (l *Limit) ShouldLog() bool { - n := l.n.Load() - if n > 0 { - // try to decrement n, doing nothing on concurrent attempts - l.n.CompareAndSwap(n, n-1) - return true - } - - return false -} - -// Close will stop the underlying ticker -func (l *Limit) Close() { - l.ticker.Stop() - close(l.exit) -} - -func (l *Limit) resetLoop() { - for { - select { - case <-l.ticker.C: - l.resetCounter() - case <-l.exit: - return - } - } -} - -func (l *Limit) resetCounter() { - // c.n == 0, it means we have gotten through the first few logs, and after ticker.T we should - // do another log - l.n.CompareAndSwap(0, 1) -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/util/log/log_not_serverless.go b/vendor/github.com/DataDog/datadog-agent/pkg/util/log/log_not_serverless.go deleted file mode 100644 index 8b7d7688..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/util/log/log_not_serverless.go +++ /dev/null @@ -1,18 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -//go:build !serverless - -package log - -// DebugServerless logs at the debug level only in a serverless context -// no-op in a non serverless context -func DebugServerless(_ ...interface{}) { -} - -// DebugfServerless logs with format at the debug level only in a serverless context -// no-op in a non serverless context -func DebugfServerless(_ string, _ ...interface{}) { -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/util/log/log_serverless.go b/vendor/github.com/DataDog/datadog-agent/pkg/util/log/log_serverless.go deleted file mode 100644 index 9ad3aa42..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/util/log/log_serverless.go +++ /dev/null @@ -1,18 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -//go:build serverless - -package log - -// DebugServerless logs at the debug level only in a serverless context -func DebugServerless(v ...interface{}) { - Debug(v...) -} - -// DebugfServerless logs with format at the debug level only in a serverless context -func DebugfServerless(format string, params ...interface{}) { - Debugf(format, params...) -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/util/log/log_test_init.go b/vendor/github.com/DataDog/datadog-agent/pkg/util/log/log_test_init.go deleted file mode 100644 index 7dd6bcd7..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/util/log/log_test_init.go +++ /dev/null @@ -1,22 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -//go:build test - -package log - -import ( - "os" - - "github.com/cihub/seelog" -) - -func init() { - level := os.Getenv("DD_LOG_LEVEL") - if level == "" { - level = "debug" - } - SetupLogger(seelog.Default, level) -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/util/log/wrapper.go b/vendor/github.com/DataDog/datadog-agent/pkg/util/log/wrapper.go deleted file mode 100644 index 52ff4c08..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/util/log/wrapper.go +++ /dev/null @@ -1,77 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package log - -// Wrapper wraps all the logger function on a struct. This is meant to be used by the comp/core/log component to expose -// the logger functionnality to components. This should only be use by the log component. -type Wrapper struct { - stackDepth int -} - -// NewWrapper returns a new Wrapper. This should only be use by the log component. -func NewWrapper(stackDepth int) *Wrapper { - return &Wrapper{stackDepth: stackDepth} -} - -// Until the log migration to component is done, we use *StackDepth to pkglog. The log component add 1 layer to the call -// stack and *StackDepth add another. -// -// We check the current log level to avoid calling Sprintf when it's not needed (Sprintf from Tracef uses a lot a CPU) - -// Trace implements Component#Trace. -func (l *Wrapper) Trace(v ...interface{}) { TraceStackDepth(l.stackDepth, v...) } - -// Tracef implements Component#Tracef. -func (l *Wrapper) Tracef(format string, params ...interface{}) { - TracefStackDepth(l.stackDepth, format, params...) -} - -// Debug implements Component#Debug. -func (l *Wrapper) Debug(v ...interface{}) { DebugStackDepth(l.stackDepth, v...) } - -// Debugf implements Component#Debugf. -func (l *Wrapper) Debugf(format string, params ...interface{}) { - DebugfStackDepth(l.stackDepth, format, params...) -} - -// Info implements Component#Info. -func (l *Wrapper) Info(v ...interface{}) { InfoStackDepth(l.stackDepth, v...) } - -// Infof implements Component#Infof. -func (l *Wrapper) Infof(format string, params ...interface{}) { - InfofStackDepth(l.stackDepth, format, params...) -} - -// Warn implements Component#Warn. -func (l *Wrapper) Warn(v ...interface{}) error { return WarnStackDepth(l.stackDepth, v...) } - -// Warnf implements Component#Warnf. -func (l *Wrapper) Warnf(format string, params ...interface{}) error { - return WarnfStackDepth(l.stackDepth, format, params...) -} - -// Error implements Component#Error. -func (l *Wrapper) Error(v ...interface{}) error { return ErrorStackDepth(l.stackDepth, v...) } - -// Errorf implements Component#Errorf. -func (l *Wrapper) Errorf(format string, params ...interface{}) error { - return ErrorfStackDepth(l.stackDepth, format, params...) -} - -// Critical implements Component#Critical. -func (l *Wrapper) Critical(v ...interface{}) error { - return CriticalStackDepth(l.stackDepth, v...) -} - -// Criticalf implements Component#Criticalf. -func (l *Wrapper) Criticalf(format string, params ...interface{}) error { - return CriticalfStackDepth(l.stackDepth, format, params...) -} - -// Flush implements Component#Flush. -func (l *Wrapper) Flush() { - Flush() -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/util/scrubber/LICENSE b/vendor/github.com/DataDog/datadog-agent/pkg/util/scrubber/LICENSE deleted file mode 100644 index b370545b..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/util/scrubber/LICENSE +++ /dev/null @@ -1,200 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2016-present Datadog, Inc. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/util/scrubber/default.go b/vendor/github.com/DataDog/datadog-agent/pkg/util/scrubber/default.go deleted file mode 100644 index 290592dd..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/util/scrubber/default.go +++ /dev/null @@ -1,378 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package scrubber - -import ( - "fmt" - "regexp" - "slices" - "strings" - "sync" -) - -var ( - // DefaultScrubber is the scrubber used by the package-level cleaning functions. - // - // It includes a set of agent-specific replacers. It can scrub DataDog App - // and API keys, passwords from URLs, and multi-line PEM-formatted TLS keys and - // certificates. It contains special handling for YAML-like content (with - // lines of the form "key: value") and can scrub passwords, tokens, and SNMP - // community strings in such content. - // - // See default.go for details of these replacers. - DefaultScrubber = &Scrubber{} - - defaultReplacement = "********" - - // dynamicReplacers are replacers added at runtime. New Replacer can be added through configuration or by the - // secrets package for example. - dynamicReplacers = []Replacer{} - dynamicReplacersMutex = sync.Mutex{} -) - -func init() { - AddDefaultReplacers(DefaultScrubber) -} - -// AddDefaultReplacers to a scrubber. This is called automatically for -// DefaultScrubber, but can be used to initialize other, custom scrubbers with -// the default replacers. -func AddDefaultReplacers(scrubber *Scrubber) { - hintedAPIKeyReplacer := Replacer{ - // If hinted, mask the value regardless if it doesn't match 32-char hexadecimal string - Regex: regexp.MustCompile(`(api_?key=)\b[a-zA-Z0-9]+([a-zA-Z0-9]{5})\b`), - Hints: []string{"api_key", "apikey"}, - Repl: []byte(`$1***************************$2`), - } - hintedAPPKeyReplacer := Replacer{ - // If hinted, mask the value regardless if it doesn't match 40-char hexadecimal string - Regex: regexp.MustCompile(`(ap(?:p|plication)_?key=)\b[a-zA-Z0-9]+([a-zA-Z0-9]{5})\b`), - Hints: []string{"app_key", "appkey", "application_key"}, - Repl: []byte(`$1***********************************$2`), - } - - // replacers are check one by one in order. We first try to scrub 64 bytes token, keeping the last 5 digit. If - // the token has a different size we scrub it entirely. - hintedBearerReplacer := Replacer{ - Regex: regexp.MustCompile(`\bBearer [a-fA-F0-9]{59}([a-fA-F0-9]{5})\b`), - Hints: []string{"Bearer"}, - Repl: []byte(`Bearer ***********************************************************$1`), - } - // For this one we match any characters - hintedBearerInvalidReplacer := Replacer{ - Regex: regexp.MustCompile(`\bBearer\s+[^*]+\b`), - Hints: []string{"Bearer"}, - Repl: []byte("Bearer " + defaultReplacement), - } - - apiKeyReplacerYAML := Replacer{ - Regex: regexp.MustCompile(`(\-|\:|,|\[|\{)(\s+)?\b[a-fA-F0-9]{27}([a-fA-F0-9]{5})\b`), - Repl: []byte(`$1$2"***************************$3"`), - } - apiKeyReplacer := Replacer{ - Regex: regexp.MustCompile(`\b[a-fA-F0-9]{27}([a-fA-F0-9]{5})\b`), - Repl: []byte(`***************************$1`), - } - appKeyReplacerYAML := Replacer{ - Regex: regexp.MustCompile(`(\-|\:|,|\[|\{)(\s+)?\b[a-fA-F0-9]{35}([a-fA-F0-9]{5})\b`), - Repl: []byte(`$1$2"***********************************$3"`), - } - appKeyReplacer := Replacer{ - Regex: regexp.MustCompile(`\b[a-fA-F0-9]{35}([a-fA-F0-9]{5})\b`), - Repl: []byte(`***********************************$1`), - } - rcAppKeyReplacer := Replacer{ - Regex: regexp.MustCompile(`\bDDRCM_[A-Z0-9]+([A-Z0-9]{5})\b`), - Repl: []byte(`***********************************$1`), - } - // URI Generic Syntax - // https://tools.ietf.org/html/rfc3986 - uriPasswordReplacer := Replacer{ - Regex: regexp.MustCompile(`(?i)([a-z][a-z0-9+-.]+://|\b)([^:]+):([^\s|"]+)@`), - Repl: []byte(`$1$2:********@`), - } - yamlPasswordReplacer := matchYAMLKeyPart( - `(pass(word)?|pwd)`, - []string{"pass", "pwd"}, - []byte(`$1 "********"`), - ) - passwordReplacer := Replacer{ - // this regex has three parts: - // * key: case-insensitive, optionally quoted (pass | password | pswd | pwd), not anchored to match on args like --mysql_password= etc. - // * separator: (= or :) with optional opening quote we don't want to match as part of the password - // * password string: alphanum + special chars except quotes and semicolon - Regex: regexp.MustCompile(`(?i)(\"?(?:pass(?:word)?|pswd|pwd)\"?)((?:=| = |: )\"?)([0-9A-Za-z#!$%&()*+,\-./:<=>?@[\\\]^_{|}~]+)`), - // replace the 3rd capture group (password string) with ******** - Repl: []byte(`$1$2********`), - } - tokenReplacer := matchYAMLKeyEnding( - `token`, - []string{"token"}, - []byte(`$1 "********"`), - ) - snmpReplacer := matchYAMLKey( - `(community_string|authKey|privKey|community|authentication_key|privacy_key|Authorization|authorization)`, - []string{"community_string", "authKey", "privKey", "community", "authentication_key", "privacy_key", "Authorization", "authorization"}, - []byte(`$1 "********"`), - ) - snmpMultilineReplacer := matchYAMLKeyWithListValue( - "(community_strings)", - "community_strings", - []byte(`$1 "********"`), - ) - certReplacer := Replacer{ - /* - Try to match as accurately as possible. RFC 7468's ABNF - Backreferences are not available in go, so we cannot verify - here that the BEGIN label is the same as the END label. - */ - Regex: regexp.MustCompile(`-----BEGIN (?:.*)-----[A-Za-z0-9=\+\/\s]*-----END (?:.*)-----`), - Hints: []string{"BEGIN"}, - Repl: []byte(`********`), - } - - // The following replacers works on YAML object only - - apiKeyYaml := matchYAMLOnly( - `api_key`, - func(data interface{}) interface{} { - if apiKey, ok := data.(string); ok { - apiKey := strings.TrimSpace(apiKey) - if apiKey == "" { - return "" - } - if len(apiKey) == 32 { - return HideKeyExceptLastFiveChars(apiKey) - } - } - return defaultReplacement - }, - ) - - appKeyYaml := matchYAMLOnly( - `ap(?:p|plication)_?key`, - func(data interface{}) interface{} { - if appKey, ok := data.(string); ok { - appKey := strings.TrimSpace(appKey) - if appKey == "" { - return "" - } - if len(appKey) == 40 { - return HideKeyExceptLastFiveChars(appKey) - } - } - return defaultReplacement - }, - ) - - scrubber.AddReplacer(SingleLine, hintedAPIKeyReplacer) - scrubber.AddReplacer(SingleLine, hintedAPPKeyReplacer) - scrubber.AddReplacer(SingleLine, hintedBearerReplacer) - scrubber.AddReplacer(SingleLine, hintedBearerInvalidReplacer) - scrubber.AddReplacer(SingleLine, apiKeyReplacerYAML) - scrubber.AddReplacer(SingleLine, apiKeyReplacer) - scrubber.AddReplacer(SingleLine, appKeyReplacerYAML) - scrubber.AddReplacer(SingleLine, appKeyReplacer) - scrubber.AddReplacer(SingleLine, rcAppKeyReplacer) - scrubber.AddReplacer(SingleLine, uriPasswordReplacer) - scrubber.AddReplacer(SingleLine, yamlPasswordReplacer) - scrubber.AddReplacer(SingleLine, passwordReplacer) - scrubber.AddReplacer(SingleLine, tokenReplacer) - scrubber.AddReplacer(SingleLine, snmpReplacer) - - scrubber.AddReplacer(SingleLine, apiKeyYaml) - scrubber.AddReplacer(SingleLine, appKeyYaml) - - scrubber.AddReplacer(MultiLine, snmpMultilineReplacer) - scrubber.AddReplacer(MultiLine, certReplacer) - - dynamicReplacersMutex.Lock() - for _, r := range dynamicReplacers { - scrubber.AddReplacer(SingleLine, r) - } - dynamicReplacersMutex.Unlock() -} - -// Yaml helpers produce replacers that work on both a yaml object (aka map[interface{}]interface{}) and on a serialized -// YAML string. - -func matchYAMLKeyPart(part string, hints []string, repl []byte) Replacer { - return Replacer{ - Regex: regexp.MustCompile(fmt.Sprintf(`(\s*(\w|_)*%s(\w|_)*\s*:).+`, part)), - YAMLKeyRegex: regexp.MustCompile(part), - Hints: hints, - Repl: repl, - } -} - -func matchYAMLKey(key string, hints []string, repl []byte) Replacer { - return Replacer{ - Regex: regexp.MustCompile(fmt.Sprintf(`(\s*%s\s*:).+`, key)), - YAMLKeyRegex: regexp.MustCompile(fmt.Sprintf(`^%s$`, key)), - Hints: hints, - Repl: repl, - } -} - -func matchYAMLKeyEnding(ending string, hints []string, repl []byte) Replacer { - return Replacer{ - Regex: regexp.MustCompile(fmt.Sprintf(`(^\s*(\w|_)*%s\s*:).+`, ending)), - YAMLKeyRegex: regexp.MustCompile(fmt.Sprintf(`^.*%s$`, ending)), - Hints: hints, - Repl: repl, - } -} - -// This only works on a YAML object not on serialized YAML data -func matchYAMLOnly(key string, cb func(interface{}) interface{}) Replacer { - return Replacer{ - YAMLKeyRegex: regexp.MustCompile(key), - ProcessValue: cb, - } -} - -// matchYAMLKeyWithListValue matches YAML keys with array values. -// caveat: doesn't work if the array contain nested arrays. -// -// Example: -// -// key: [ -// [a, b, c], -// def] -func matchYAMLKeyWithListValue(key string, hints string, repl []byte) Replacer { - /* - Example 1: - network_devices: - snmp_traps: - community_strings: - - 'pass1' - - 'pass2' - - Example 2: - network_devices: - snmp_traps: - community_strings: ['pass1', 'pass2'] - - Example 3: - network_devices: - snmp_traps: - community_strings: [ - 'pass1', - 'pass2'] - */ - return Replacer{ - Regex: regexp.MustCompile(fmt.Sprintf(`(\s*%s\s*:)\s*(?:\n(?:\s+-\s+.*)*|\[(?:\n?.*?)*?\])`, key)), - /* ----------- --------------- ------------- - match key(s) | | - match multiple match anything - lines starting enclosed between `[` and `]` - with `-` - */ - YAMLKeyRegex: regexp.MustCompile(key), - Hints: []string{hints}, - Repl: repl, - } -} - -// ScrubFile scrubs credentials from the given file, using the -// default scrubber. -func ScrubFile(filePath string) ([]byte, error) { - return DefaultScrubber.ScrubFile(filePath) -} - -// ScrubBytes scrubs credentials from the given slice of bytes, -// using the default scrubber. -func ScrubBytes(file []byte) ([]byte, error) { - return DefaultScrubber.ScrubBytes(file) -} - -// ScrubYaml scrubs credentials from the given YAML by loading the data and scrubbing the object instead of the -// serialized string, using the default scrubber. -func ScrubYaml(data []byte) ([]byte, error) { - return DefaultScrubber.ScrubYaml(data) -} - -// ScrubYamlString scrubs credentials from the given YAML string by loading the data and scrubbing the object instead of -// the serialized string, using the default scrubber. -func ScrubYamlString(data string) (string, error) { - res, err := DefaultScrubber.ScrubYaml([]byte(data)) - if err != nil { - return "", err - } - return string(res), nil -} - -// ScrubJSON scrubs credentials from the given JSON by loading the data and scrubbing the object instead of the -// serialized string, using the default scrubber. -func ScrubJSON(data []byte) ([]byte, error) { - return DefaultScrubber.ScrubJSON(data) -} - -// ScrubJSONString scrubs credentials from the given JSON string by loading the data and scrubbing the object instead of -// the serialized string, using the default scrubber. -func ScrubJSONString(data string) (string, error) { - res, err := ScrubJSON([]byte(data)) - if err != nil { - return "", err - } - return string(res), nil -} - -// ScrubString scrubs credentials from the given string, using the default scrubber. -func ScrubString(data string) (string, error) { - res, err := DefaultScrubber.ScrubBytes([]byte(data)) - if err != nil { - return "", err - } - return string(res), nil -} - -// ScrubLine scrubs credentials from a single line of text, using the default -// scrubber. It can be safely applied to URLs or to strings containing URLs. -// It does not run multi-line replacers, and should not be used on multi-line -// inputs. -func ScrubLine(url string) string { - return DefaultScrubber.ScrubLine(url) -} - -// ScrubDataObj scrubs credentials from the data interface by recursively walking over all the nodes -func ScrubDataObj(data *interface{}) { - DefaultScrubber.ScrubDataObj(data) -} - -// HideKeyExceptLastFiveChars replaces all characters in the key with "*", except -// for the last 5 characters. If the key is an unrecognized length, replace -// all of it with the default string of "*"s instead. -func HideKeyExceptLastFiveChars(key string) string { - if len(key) != 32 && len(key) != 40 { - return defaultReplacement - } - return strings.Repeat("*", len(key)-5) + key[len(key)-5:] -} - -// AddStrippedKeys adds to the set of YAML keys that will be recognized and have their values stripped. This modifies -// the DefaultScrubber directly and be added to any created scrubbers. -func AddStrippedKeys(strippedKeys []string) { - // API and APP keys are already handled by default rules - strippedKeys = slices.Clone(strippedKeys) - strippedKeys = slices.DeleteFunc(strippedKeys, func(s string) bool { - return s == "api_key" || s == "app_key" - }) - - if len(strippedKeys) > 0 { - replacer := matchYAMLKey( - fmt.Sprintf("(%s)", strings.Join(strippedKeys, "|")), - strippedKeys, - []byte(`$1 "********"`), - ) - // We add the new replacer to the default scrubber and to the list of dynamicReplacers so any new - // scubber will inherit it. - DefaultScrubber.AddReplacer(SingleLine, replacer) - dynamicReplacersMutex.Lock() - dynamicReplacers = append(dynamicReplacers, replacer) - dynamicReplacersMutex.Unlock() - } -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/util/scrubber/json_scrubber.go b/vendor/github.com/DataDog/datadog-agent/pkg/util/scrubber/json_scrubber.go deleted file mode 100644 index 34c65dd3..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/util/scrubber/json_scrubber.go +++ /dev/null @@ -1,33 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package scrubber - -import ( - "fmt" - "os" - - "encoding/json" -) - -// ScrubJSON scrubs credentials from the given json by loading the data and scrubbing the -// object instead of the serialized string. -func (c *Scrubber) ScrubJSON(input []byte) ([]byte, error) { - var data *interface{} - err := json.Unmarshal(input, &data) - - // if we can't load the json run the default scrubber on the input - if len(input) != 0 && err == nil { - c.ScrubDataObj(data) - - newInput, err := json.Marshal(data) - if err == nil { - return newInput, nil - } - // Since the scrubber is a dependency of the logger we can't use it here. - fmt.Fprintf(os.Stderr, "error scrubbing json, falling back on text scrubber: %s\n", err) - } - return c.ScrubBytes(input) -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/util/scrubber/scrubber.go b/vendor/github.com/DataDog/datadog-agent/pkg/util/scrubber/scrubber.go deleted file mode 100644 index 1aaad14c..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/util/scrubber/scrubber.go +++ /dev/null @@ -1,196 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -// Package scrubber implements support for cleaning sensitive information out of strings -// and files. -// -// # Compatibility -// -// This module's API is not yet stable, and may change incompatibly from version to version. -package scrubber - -import ( - "bufio" - "bytes" - "io" - "os" - "regexp" -) - -// Replacer represents a replacement of sensitive information with a "clean" version. -type Replacer struct { - // Regex must match the sensitive information - Regex *regexp.Regexp - // YAMLKeyRegex matches the key of sensitive information in a dict/map. This is used when iterating over a - // map[string]interface{} to scrub data for all matching key before being serialized. - YAMLKeyRegex *regexp.Regexp - // ProcessValue is a callback to be executed when YAMLKeyRegex matches the key of a map/dict in a YAML object. The - // value is passed to the function and replaced by the returned interface. This is useful to produce custom - // scrubbing. Example: keeping the last 5 digit of an api key. - ProcessValue func(data interface{}) interface{} - // Hints, if given, are strings which must also be present in the text for the regexp to match. - // Especially in single-line replacers, this can be used to limit the contexts where an otherwise - // very broad Regex is actually replaced. - Hints []string - // Repl is the text to replace the substring matching Regex. It can use the regexp package's - // replacement characters ($1, etc.) (see regexp#Regexp.ReplaceAll). - Repl []byte - // ReplFunc, if set, is called with the matched bytes (see regexp#Regexp.ReplaceAllFunc). Only - // one of Repl and ReplFunc should be set. - ReplFunc func(b []byte) []byte -} - -// ReplacerKind modifies how a Replacer is applied -type ReplacerKind int - -const ( - // SingleLine indicates to Cleaner#AddReplacer that the replacer applies to - // single lines. - SingleLine ReplacerKind = iota - // MultiLine indicates to Cleaner#AddReplacer that the replacer applies to - // entire multiline text values. - MultiLine -) - -var commentRegex = regexp.MustCompile(`^\s*#.*$`) -var blankRegex = regexp.MustCompile(`^\s*$`) - -// Scrubber implements support for cleaning sensitive information out of strings -// and files. Its intended use is to "clean" data before it is logged or -// transmitted to a remote system, so that the meaning of the data remains -// clear without disclosing any sensitive information. -// -// Scrubber works by applying a set of replacers, in order. It first applies -// all SingleLine replacers to each non-comment, non-blank line of the input. -// -// Comments and blank lines are omitted. Comments are considered to begin with `#`. -// -// It then applies all MultiLine replacers to the entire text of the input. -type Scrubber struct { - singleLineReplacers []Replacer - multiLineReplacers []Replacer -} - -// New creates a new scrubber with no replacers installed. -func New() *Scrubber { - return &Scrubber{ - singleLineReplacers: make([]Replacer, 0), - multiLineReplacers: make([]Replacer, 0), - } -} - -// NewWithDefaults creates a new scrubber with the default replacers installed. -func NewWithDefaults() *Scrubber { - s := New() - AddDefaultReplacers(s) - return s -} - -// AddReplacer adds a replacer of the given kind to the scrubber. -func (c *Scrubber) AddReplacer(kind ReplacerKind, replacer Replacer) { - switch kind { - case SingleLine: - c.singleLineReplacers = append(c.singleLineReplacers, replacer) - case MultiLine: - c.multiLineReplacers = append(c.multiLineReplacers, replacer) - } -} - -// ScrubFile scrubs credentials from file given by pathname -func (c *Scrubber) ScrubFile(filePath string) ([]byte, error) { - file, err := os.Open(filePath) - if err != nil { - return nil, err - } - defer file.Close() - - var sizeHint int - stats, err := file.Stat() - if err == nil { - sizeHint = int(stats.Size()) - } - - return c.scrubReader(file, sizeHint) -} - -// ScrubBytes scrubs credentials from slice of bytes -func (c *Scrubber) ScrubBytes(data []byte) ([]byte, error) { - r := bytes.NewReader(data) - return c.scrubReader(r, r.Len()) -} - -// ScrubLine scrubs credentials from a single line of text. It can be safely -// applied to URLs or to strings containing URLs. It does not run multi-line -// replacers, and should not be used on multi-line inputs. -func (c *Scrubber) ScrubLine(message string) string { - return string(c.scrub([]byte(message), c.singleLineReplacers)) -} - -// scrubReader applies the cleaning algorithm to a Reader -func (c *Scrubber) scrubReader(file io.Reader, sizeHint int) ([]byte, error) { - var cleanedBuffer bytes.Buffer - if sizeHint > 0 { - cleanedBuffer.Grow(sizeHint) - } - - scanner := bufio.NewScanner(file) - if sizeHint+1 > bufio.MaxScanTokenSize { - buffer := make([]byte, 0, sizeHint+1) - scanner.Buffer(buffer, sizeHint+1) - } - - // First, we go through the file line by line, applying any - // single-line replacer that matches the line. - first := true - for scanner.Scan() { - b := scanner.Bytes() - if blankRegex.Match(b) { - cleanedBuffer.WriteRune('\n') - } else if !commentRegex.Match(b) { - b = c.scrub(b, c.singleLineReplacers) - if !first { - cleanedBuffer.WriteRune('\n') - } - - cleanedBuffer.Write(b) - first = false - } - } - - if err := scanner.Err(); err != nil { - return nil, err - } - - // Then we apply multiline replacers on the cleaned file - cleanedFile := c.scrub(cleanedBuffer.Bytes(), c.multiLineReplacers) - - return cleanedFile, nil -} - -// scrub applies the given replacers to the given data. -func (c *Scrubber) scrub(data []byte, replacers []Replacer) []byte { - for _, repl := range replacers { - if repl.Regex == nil { - // ignoring YAML only replacers - continue - } - - containsHint := false - for _, hint := range repl.Hints { - if bytes.Contains(data, []byte(hint)) { - containsHint = true - break - } - } - if len(repl.Hints) == 0 || containsHint { - if repl.ReplFunc != nil { - data = repl.Regex.ReplaceAllFunc(data, repl.ReplFunc) - } else { - data = repl.Regex.ReplaceAll(data, repl.Repl) - } - } - } - return data -} diff --git a/vendor/github.com/DataDog/datadog-agent/pkg/util/scrubber/yaml_scrubber.go b/vendor/github.com/DataDog/datadog-agent/pkg/util/scrubber/yaml_scrubber.go deleted file mode 100644 index 74016778..00000000 --- a/vendor/github.com/DataDog/datadog-agent/pkg/util/scrubber/yaml_scrubber.go +++ /dev/null @@ -1,117 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package scrubber - -import ( - "fmt" - "os" - - "gopkg.in/yaml.v2" -) - -type scrubCallback = func(string, interface{}) (bool, interface{}) - -func walkSlice(data []interface{}, callback scrubCallback) { - for _, k := range data { - switch v := k.(type) { - case map[interface{}]interface{}: - walkHash(v, callback) - case []interface{}: - walkSlice(v, callback) - case map[string]interface{}: - walkStringMap(v, callback) - } - } -} - -func walkHash(data map[interface{}]interface{}, callback scrubCallback) { - for k, v := range data { - if keyString, ok := k.(string); ok { - if match, newValue := callback(keyString, v); match { - data[keyString] = newValue - continue - } - } - - switch v := data[k].(type) { - case map[interface{}]interface{}: - walkHash(v, callback) - case []interface{}: - walkSlice(v, callback) - } - } -} - -func walkStringMap(data map[string]interface{}, callback scrubCallback) { - for k, v := range data { - if match, newValue := callback(k, v); match { - data[k] = newValue - continue - } - switch v := data[k].(type) { - case map[string]interface{}: - walkStringMap(v, callback) - case []interface{}: - walkSlice(v, callback) - } - - } -} - -// walk will go through loaded data and call callback on every strings allowing -// the callback to overwrite the string value -func walk(data *interface{}, callback scrubCallback) { - if data == nil { - return - } - - switch v := (*data).(type) { - case map[interface{}]interface{}: - walkHash(v, callback) - case []interface{}: - walkSlice(v, callback) - case map[string]interface{}: - walkStringMap(v, callback) - } -} - -// ScrubDataObj scrubs credentials from the data interface by recursively walking over all the nodes -func (c *Scrubber) ScrubDataObj(data *interface{}) { - walk(data, func(key string, value interface{}) (bool, interface{}) { - for _, replacer := range c.singleLineReplacers { - if replacer.YAMLKeyRegex == nil { - continue - } - if replacer.YAMLKeyRegex.Match([]byte(key)) { - if replacer.ProcessValue != nil { - return true, replacer.ProcessValue(value) - } - return true, defaultReplacement - } - } - return false, "" - }) -} - -// ScrubYaml scrubs credentials from the given YAML by loading the data and scrubbing the object instead of the -// serialized string. -func (c *Scrubber) ScrubYaml(input []byte) ([]byte, error) { - var data *interface{} - err := yaml.Unmarshal(input, &data) - - // if we can't load the yaml run the default scrubber on the input - if len(input) != 0 && err == nil { - c.ScrubDataObj(data) - newInput, err := yaml.Marshal(data) - if err == nil { - input = newInput - } else { - // Since the scrubber is a dependency of the logger we can use it here. - fmt.Fprintf(os.Stderr, "error scrubbing YAML, falling back on text scrubber: %s\n", err) - } - } - return c.ScrubBytes(input) -} diff --git a/vendor/github.com/DataDog/datadog-go/v5/LICENSE.txt b/vendor/github.com/DataDog/datadog-go/v5/LICENSE.txt deleted file mode 100644 index 97cd06d7..00000000 --- a/vendor/github.com/DataDog/datadog-go/v5/LICENSE.txt +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2015 Datadog, Inc - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/README.md b/vendor/github.com/DataDog/datadog-go/v5/statsd/README.md deleted file mode 100644 index 2fc89968..00000000 --- a/vendor/github.com/DataDog/datadog-go/v5/statsd/README.md +++ /dev/null @@ -1,4 +0,0 @@ -## Overview - -Package `statsd` provides a Go [dogstatsd](http://docs.datadoghq.com/guides/dogstatsd/) client. Dogstatsd extends Statsd, adding tags -and histograms. diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/aggregator.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/aggregator.go deleted file mode 100644 index 33eb930a..00000000 --- a/vendor/github.com/DataDog/datadog-go/v5/statsd/aggregator.go +++ /dev/null @@ -1,298 +0,0 @@ -package statsd - -import ( - "strings" - "sync" - "sync/atomic" - "time" -) - -type ( - countsMap map[string]*countMetric - gaugesMap map[string]*gaugeMetric - setsMap map[string]*setMetric - bufferedMetricMap map[string]*bufferedMetric -) - -type aggregator struct { - nbContextGauge uint64 - nbContextCount uint64 - nbContextSet uint64 - - countsM sync.RWMutex - gaugesM sync.RWMutex - setsM sync.RWMutex - - gauges gaugesMap - counts countsMap - sets setsMap - histograms bufferedMetricContexts - distributions bufferedMetricContexts - timings bufferedMetricContexts - - closed chan struct{} - - client *Client - - // aggregator implements channelMode mechanism to receive histograms, - // distributions and timings. Since they need sampling they need to - // lock for random. When using both channelMode and ExtendedAggregation - // we don't want goroutine to fight over the lock. - inputMetrics chan metric - stopChannelMode chan struct{} - wg sync.WaitGroup -} - -func newAggregator(c *Client, maxSamplesPerContext int64) *aggregator { - return &aggregator{ - client: c, - counts: countsMap{}, - gauges: gaugesMap{}, - sets: setsMap{}, - histograms: newBufferedContexts(newHistogramMetric, maxSamplesPerContext), - distributions: newBufferedContexts(newDistributionMetric, maxSamplesPerContext), - timings: newBufferedContexts(newTimingMetric, maxSamplesPerContext), - closed: make(chan struct{}), - stopChannelMode: make(chan struct{}), - } -} - -func (a *aggregator) start(flushInterval time.Duration) { - ticker := time.NewTicker(flushInterval) - - go func() { - for { - select { - case <-ticker.C: - a.flush() - case <-a.closed: - ticker.Stop() - return - } - } - }() -} - -func (a *aggregator) startReceivingMetric(bufferSize int, nbWorkers int) { - a.inputMetrics = make(chan metric, bufferSize) - for i := 0; i < nbWorkers; i++ { - a.wg.Add(1) - go a.pullMetric() - } -} - -func (a *aggregator) stopReceivingMetric() { - close(a.stopChannelMode) - a.wg.Wait() -} - -func (a *aggregator) stop() { - a.closed <- struct{}{} -} - -func (a *aggregator) pullMetric() { - for { - select { - case m := <-a.inputMetrics: - switch m.metricType { - case histogram: - a.histogram(m.name, m.fvalue, m.tags, m.rate) - case distribution: - a.distribution(m.name, m.fvalue, m.tags, m.rate) - case timing: - a.timing(m.name, m.fvalue, m.tags, m.rate) - } - case <-a.stopChannelMode: - a.wg.Done() - return - } - } -} - -func (a *aggregator) flush() { - for _, m := range a.flushMetrics() { - a.client.sendBlocking(m) - } -} - -func (a *aggregator) flushTelemetryMetrics(t *Telemetry) { - if a == nil { - // aggregation is disabled - return - } - - t.AggregationNbContextGauge = atomic.LoadUint64(&a.nbContextGauge) - t.AggregationNbContextCount = atomic.LoadUint64(&a.nbContextCount) - t.AggregationNbContextSet = atomic.LoadUint64(&a.nbContextSet) - t.AggregationNbContextHistogram = a.histograms.getNbContext() - t.AggregationNbContextDistribution = a.distributions.getNbContext() - t.AggregationNbContextTiming = a.timings.getNbContext() -} - -func (a *aggregator) flushMetrics() []metric { - metrics := []metric{} - - // We reset the values to avoid sending 'zero' values for metrics not - // sampled during this flush interval - - a.setsM.Lock() - sets := a.sets - a.sets = setsMap{} - a.setsM.Unlock() - - for _, s := range sets { - metrics = append(metrics, s.flushUnsafe()...) - } - - a.gaugesM.Lock() - gauges := a.gauges - a.gauges = gaugesMap{} - a.gaugesM.Unlock() - - for _, g := range gauges { - metrics = append(metrics, g.flushUnsafe()) - } - - a.countsM.Lock() - counts := a.counts - a.counts = countsMap{} - a.countsM.Unlock() - - for _, c := range counts { - metrics = append(metrics, c.flushUnsafe()) - } - - metrics = a.histograms.flush(metrics) - metrics = a.distributions.flush(metrics) - metrics = a.timings.flush(metrics) - - atomic.AddUint64(&a.nbContextCount, uint64(len(counts))) - atomic.AddUint64(&a.nbContextGauge, uint64(len(gauges))) - atomic.AddUint64(&a.nbContextSet, uint64(len(sets))) - return metrics -} - -// getContext returns the context for a metric name and tags. -// -// The context is the metric name and tags separated by a separator symbol. -// It is not intended to be used as a metric name but as a unique key to aggregate -func getContext(name string, tags []string) string { - c, _ := getContextAndTags(name, tags) - return c -} - -// getContextAndTags returns the context and tags for a metric name and tags. -// -// See getContext for usage for context -// The tags are the tags separated by a separator symbol and can be re-used to pass down to the writer -func getContextAndTags(name string, tags []string) (string, string) { - if len(tags) == 0 { - return name, "" - } - n := len(name) + len(nameSeparatorSymbol) + len(tagSeparatorSymbol)*(len(tags)-1) - for _, s := range tags { - n += len(s) - } - - var sb strings.Builder - sb.Grow(n) - sb.WriteString(name) - sb.WriteString(nameSeparatorSymbol) - sb.WriteString(tags[0]) - for _, s := range tags[1:] { - sb.WriteString(tagSeparatorSymbol) - sb.WriteString(s) - } - - s := sb.String() - - return s, s[len(name)+len(nameSeparatorSymbol):] -} - -func (a *aggregator) count(name string, value int64, tags []string) error { - context := getContext(name, tags) - a.countsM.RLock() - if count, found := a.counts[context]; found { - count.sample(value) - a.countsM.RUnlock() - return nil - } - a.countsM.RUnlock() - - a.countsM.Lock() - // Check if another goroutines hasn't created the value betwen the RUnlock and 'Lock' - if count, found := a.counts[context]; found { - count.sample(value) - a.countsM.Unlock() - return nil - } - - a.counts[context] = newCountMetric(name, value, tags) - a.countsM.Unlock() - return nil -} - -func (a *aggregator) gauge(name string, value float64, tags []string) error { - context := getContext(name, tags) - a.gaugesM.RLock() - if gauge, found := a.gauges[context]; found { - gauge.sample(value) - a.gaugesM.RUnlock() - return nil - } - a.gaugesM.RUnlock() - - gauge := newGaugeMetric(name, value, tags) - - a.gaugesM.Lock() - // Check if another goroutines hasn't created the value betwen the 'RUnlock' and 'Lock' - if gauge, found := a.gauges[context]; found { - gauge.sample(value) - a.gaugesM.Unlock() - return nil - } - a.gauges[context] = gauge - a.gaugesM.Unlock() - return nil -} - -func (a *aggregator) set(name string, value string, tags []string) error { - context := getContext(name, tags) - a.setsM.RLock() - if set, found := a.sets[context]; found { - set.sample(value) - a.setsM.RUnlock() - return nil - } - a.setsM.RUnlock() - - a.setsM.Lock() - // Check if another goroutines hasn't created the value betwen the 'RUnlock' and 'Lock' - if set, found := a.sets[context]; found { - set.sample(value) - a.setsM.Unlock() - return nil - } - a.sets[context] = newSetMetric(name, value, tags) - a.setsM.Unlock() - return nil -} - -// Only histograms, distributions and timings are sampled with a rate since we -// only pack them in on message instead of aggregating them. Discarding the -// sample rate will have impacts on the CPU and memory usage of the Agent. - -// type alias for Client.sendToAggregator -type bufferedMetricSampleFunc func(name string, value float64, tags []string, rate float64) error - -func (a *aggregator) histogram(name string, value float64, tags []string, rate float64) error { - return a.histograms.sample(name, value, tags, rate) -} - -func (a *aggregator) distribution(name string, value float64, tags []string, rate float64) error { - return a.distributions.sample(name, value, tags, rate) -} - -func (a *aggregator) timing(name string, value float64, tags []string, rate float64) error { - return a.timings.sample(name, value, tags, rate) -} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/buffer.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/buffer.go deleted file mode 100644 index 91f2e32b..00000000 --- a/vendor/github.com/DataDog/datadog-go/v5/statsd/buffer.go +++ /dev/null @@ -1,198 +0,0 @@ -package statsd - -import ( - "strconv" -) - -// MessageTooLongError is an error returned when a sample, event or service check is too large once serialized. See -// WithMaxBytesPerPayload option for more details. -type MessageTooLongError struct{} - -func (e MessageTooLongError) Error() string { - return "message too long. See 'WithMaxBytesPerPayload' documentation." -} - -var errBufferFull = MessageTooLongError{} - -type partialWriteError string - -func (e partialWriteError) Error() string { return string(e) } - -const errPartialWrite = partialWriteError("value partially written") - -const metricOverhead = 512 - -// statsdBuffer is a buffer containing statsd messages -// this struct methods are NOT safe for concurrent use -type statsdBuffer struct { - buffer []byte - maxSize int - maxElements int - elementCount int -} - -func newStatsdBuffer(maxSize, maxElements int) *statsdBuffer { - return &statsdBuffer{ - buffer: make([]byte, 0, maxSize+metricOverhead), // pre-allocate the needed size + metricOverhead to avoid having Go re-allocate on it's own if an element does not fit - maxSize: maxSize, - maxElements: maxElements, - } -} - -func (b *statsdBuffer) writeGauge(namespace string, globalTags []string, name string, value float64, tags []string, rate float64, timestamp int64) error { - if b.elementCount >= b.maxElements { - return errBufferFull - } - originalBuffer := b.buffer - b.buffer = appendGauge(b.buffer, namespace, globalTags, name, value, tags, rate) - b.buffer = appendTimestamp(b.buffer, timestamp) - b.writeSeparator() - return b.validateNewElement(originalBuffer) -} - -func (b *statsdBuffer) writeCount(namespace string, globalTags []string, name string, value int64, tags []string, rate float64, timestamp int64) error { - if b.elementCount >= b.maxElements { - return errBufferFull - } - originalBuffer := b.buffer - b.buffer = appendCount(b.buffer, namespace, globalTags, name, value, tags, rate) - b.buffer = appendTimestamp(b.buffer, timestamp) - b.writeSeparator() - return b.validateNewElement(originalBuffer) -} - -func (b *statsdBuffer) writeHistogram(namespace string, globalTags []string, name string, value float64, tags []string, rate float64) error { - if b.elementCount >= b.maxElements { - return errBufferFull - } - originalBuffer := b.buffer - b.buffer = appendHistogram(b.buffer, namespace, globalTags, name, value, tags, rate) - b.writeSeparator() - return b.validateNewElement(originalBuffer) -} - -// writeAggregated serialized as many values as possible in the current buffer and return the position in values where it stopped. -func (b *statsdBuffer) writeAggregated(metricSymbol []byte, namespace string, globalTags []string, name string, values []float64, tags string, tagSize int, precision int, rate float64) (int, error) { - if b.elementCount >= b.maxElements { - return 0, errBufferFull - } - - originalBuffer := b.buffer - b.buffer = appendHeader(b.buffer, namespace, name) - - // buffer already full - if len(b.buffer)+tagSize > b.maxSize { - b.buffer = originalBuffer - return 0, errBufferFull - } - - // We add as many value as possible - var position int - for idx, v := range values { - previousBuffer := b.buffer - if idx != 0 { - b.buffer = append(b.buffer, ':') - } - - b.buffer = strconv.AppendFloat(b.buffer, v, 'f', precision, 64) - - // Should we stop serializing and switch to another buffer - if len(b.buffer)+tagSize > b.maxSize { - b.buffer = previousBuffer - break - } - position = idx + 1 - } - - // we could not add a single value - if position == 0 { - b.buffer = originalBuffer - return 0, errBufferFull - } - - b.buffer = append(b.buffer, '|') - b.buffer = append(b.buffer, metricSymbol...) - b.buffer = appendRate(b.buffer, rate) - b.buffer = appendTagsAggregated(b.buffer, globalTags, tags) - b.buffer = appendContainerID(b.buffer) - b.writeSeparator() - b.elementCount++ - - if position != len(values) { - return position, errPartialWrite - } - return position, nil - -} - -func (b *statsdBuffer) writeDistribution(namespace string, globalTags []string, name string, value float64, tags []string, rate float64) error { - if b.elementCount >= b.maxElements { - return errBufferFull - } - originalBuffer := b.buffer - b.buffer = appendDistribution(b.buffer, namespace, globalTags, name, value, tags, rate) - b.writeSeparator() - return b.validateNewElement(originalBuffer) -} - -func (b *statsdBuffer) writeSet(namespace string, globalTags []string, name string, value string, tags []string, rate float64) error { - if b.elementCount >= b.maxElements { - return errBufferFull - } - originalBuffer := b.buffer - b.buffer = appendSet(b.buffer, namespace, globalTags, name, value, tags, rate) - b.writeSeparator() - return b.validateNewElement(originalBuffer) -} - -func (b *statsdBuffer) writeTiming(namespace string, globalTags []string, name string, value float64, tags []string, rate float64) error { - if b.elementCount >= b.maxElements { - return errBufferFull - } - originalBuffer := b.buffer - b.buffer = appendTiming(b.buffer, namespace, globalTags, name, value, tags, rate) - b.writeSeparator() - return b.validateNewElement(originalBuffer) -} - -func (b *statsdBuffer) writeEvent(event *Event, globalTags []string) error { - if b.elementCount >= b.maxElements { - return errBufferFull - } - originalBuffer := b.buffer - b.buffer = appendEvent(b.buffer, event, globalTags) - b.writeSeparator() - return b.validateNewElement(originalBuffer) -} - -func (b *statsdBuffer) writeServiceCheck(serviceCheck *ServiceCheck, globalTags []string) error { - if b.elementCount >= b.maxElements { - return errBufferFull - } - originalBuffer := b.buffer - b.buffer = appendServiceCheck(b.buffer, serviceCheck, globalTags) - b.writeSeparator() - return b.validateNewElement(originalBuffer) -} - -func (b *statsdBuffer) validateNewElement(originalBuffer []byte) error { - if len(b.buffer) > b.maxSize { - b.buffer = originalBuffer - return errBufferFull - } - b.elementCount++ - return nil -} - -func (b *statsdBuffer) writeSeparator() { - b.buffer = append(b.buffer, '\n') -} - -func (b *statsdBuffer) reset() { - b.buffer = b.buffer[:0] - b.elementCount = 0 -} - -func (b *statsdBuffer) bytes() []byte { - return b.buffer -} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/buffer_pool.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/buffer_pool.go deleted file mode 100644 index 7a3e3c9d..00000000 --- a/vendor/github.com/DataDog/datadog-go/v5/statsd/buffer_pool.go +++ /dev/null @@ -1,40 +0,0 @@ -package statsd - -type bufferPool struct { - pool chan *statsdBuffer - bufferMaxSize int - bufferMaxElements int -} - -func newBufferPool(poolSize, bufferMaxSize, bufferMaxElements int) *bufferPool { - p := &bufferPool{ - pool: make(chan *statsdBuffer, poolSize), - bufferMaxSize: bufferMaxSize, - bufferMaxElements: bufferMaxElements, - } - for i := 0; i < poolSize; i++ { - p.addNewBuffer() - } - return p -} - -func (p *bufferPool) addNewBuffer() { - p.pool <- newStatsdBuffer(p.bufferMaxSize, p.bufferMaxElements) -} - -func (p *bufferPool) borrowBuffer() *statsdBuffer { - select { - case b := <-p.pool: - return b - default: - return newStatsdBuffer(p.bufferMaxSize, p.bufferMaxElements) - } -} - -func (p *bufferPool) returnBuffer(buffer *statsdBuffer) { - buffer.reset() - select { - case p.pool <- buffer: - default: - } -} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/buffered_metric_context.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/buffered_metric_context.go deleted file mode 100644 index 94b31fe5..00000000 --- a/vendor/github.com/DataDog/datadog-go/v5/statsd/buffered_metric_context.go +++ /dev/null @@ -1,104 +0,0 @@ -package statsd - -import ( - "math/rand" - "sync" - "sync/atomic" - "time" -) - -// bufferedMetricContexts represent the contexts for Histograms, Distributions -// and Timing. Since those 3 metric types behave the same way and are sampled -// with the same type they're represented by the same class. -type bufferedMetricContexts struct { - nbContext uint64 - mutex sync.RWMutex - values bufferedMetricMap - newMetric func(string, float64, string, float64) *bufferedMetric - - // Each bufferedMetricContexts uses its own random source and random - // lock to prevent goroutines from contending for the lock on the - // "math/rand" package-global random source (e.g. calls like - // "rand.Float64()" must acquire a shared lock to get the next - // pseudorandom number). - random *rand.Rand - randomLock sync.Mutex -} - -func newBufferedContexts(newMetric func(string, float64, string, int64, float64) *bufferedMetric, maxSamples int64) bufferedMetricContexts { - return bufferedMetricContexts{ - values: bufferedMetricMap{}, - newMetric: func(name string, value float64, stringTags string, rate float64) *bufferedMetric { - return newMetric(name, value, stringTags, maxSamples, rate) - }, - // Note that calling "time.Now().UnixNano()" repeatedly quickly may return - // very similar values. That's fine for seeding the worker-specific random - // source because we just need an evenly distributed stream of float values. - // Do not use this random source for cryptographic randomness. - random: rand.New(rand.NewSource(time.Now().UnixNano())), - } -} - -func (bc *bufferedMetricContexts) flush(metrics []metric) []metric { - bc.mutex.Lock() - values := bc.values - bc.values = bufferedMetricMap{} - bc.mutex.Unlock() - - for _, d := range values { - d.Lock() - metrics = append(metrics, d.flushUnsafe()) - d.Unlock() - } - atomic.AddUint64(&bc.nbContext, uint64(len(values))) - return metrics -} - -func (bc *bufferedMetricContexts) sample(name string, value float64, tags []string, rate float64) error { - keepingSample := shouldSample(rate, bc.random, &bc.randomLock) - - // If we don't keep the sample, return early. If we do keep the sample - // we end up storing the *first* observed sampling rate in the metric. - // This is the *wrong* behavior but it's the one we had before and the alternative would increase lock contention too - // much with the current code. - // TODO: change this behavior in the future, probably by introducing thread-local storage and lockless stuctures. - // If this code is removed, also remove the observed sampling rate in the metric and fix `bufferedMetric.flushUnsafe()` - if !keepingSample { - return nil - } - - context, stringTags := getContextAndTags(name, tags) - var v *bufferedMetric - - bc.mutex.RLock() - v, _ = bc.values[context] - bc.mutex.RUnlock() - - // Create it if it wasn't found - if v == nil { - bc.mutex.Lock() - // It might have been created by another goroutine since last call - v, _ = bc.values[context] - if v == nil { - // If we might keep a sample that we should have skipped, but that should not drastically affect performances. - bc.values[context] = bc.newMetric(name, value, stringTags, rate) - // We added a new value, we need to unlock the mutex and quit - bc.mutex.Unlock() - return nil - } - bc.mutex.Unlock() - } - - // Now we can keep the sample or skip it - if keepingSample { - v.maybeKeepSample(value, bc.random, &bc.randomLock) - } else { - v.skipSample() - } - - return nil -} - -func (bc *bufferedMetricContexts) getNbContext() uint64 { - return atomic.LoadUint64(&bc.nbContext) -} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/container.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/container.go deleted file mode 100644 index 20d69ef6..00000000 --- a/vendor/github.com/DataDog/datadog-go/v5/statsd/container.go +++ /dev/null @@ -1,19 +0,0 @@ -package statsd - -import ( - "sync" -) - -var ( - // containerID holds the container ID. - containerID = "" - - initOnce sync.Once -) - -// getContainerID returns the container ID configured at the client creation -// It can either be auto-discovered with origin detection or provided by the user. -// User-defined container ID is prioritized. -func getContainerID() string { - return containerID -} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/container_linux.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/container_linux.go deleted file mode 100644 index ad74f7ab..00000000 --- a/vendor/github.com/DataDog/datadog-go/v5/statsd/container_linux.go +++ /dev/null @@ -1,206 +0,0 @@ -//go:build linux -// +build linux - -package statsd - -import ( - "bufio" - "fmt" - "io" - "os" - "path" - "regexp" - "strings" - "syscall" -) - -const ( - // cgroupPath is the path to the cgroup file where we can find the container id if one exists. - cgroupPath = "/proc/self/cgroup" - - // selfMountinfo is the path to the mountinfo path where we can find the container id in case cgroup namespace is preventing the use of /proc/self/cgroup - selfMountInfoPath = "/proc/self/mountinfo" - - // defaultCgroupMountPath is the default path to the cgroup mount point. - defaultCgroupMountPath = "/sys/fs/cgroup" - - // cgroupV1BaseController is the controller used to identify the container-id for cgroup v1 - cgroupV1BaseController = "memory" - - uuidSource = "[0-9a-f]{8}[-_][0-9a-f]{4}[-_][0-9a-f]{4}[-_][0-9a-f]{4}[-_][0-9a-f]{12}" - containerSource = "[0-9a-f]{64}" - taskSource = "[0-9a-f]{32}-\\d+" - - containerdSandboxPrefix = "sandboxes" - - // ContainerRegexpStr defines the regexp used to match container IDs - // ([0-9a-f]{64}) is standard container id used pretty much everywhere - // ([0-9a-f]{32}-[0-9]{10}) is container id used by AWS ECS - // ([0-9a-f]{8}(-[0-9a-f]{4}){4}$) is container id used by Garden - containerRegexpStr = "([0-9a-f]{64})|([0-9a-f]{32}-[0-9]{10})|([0-9a-f]{8}(-[0-9a-f]{4}){4}$)" - // cIDRegexpStr defines the regexp used to match container IDs in /proc/self/mountinfo - cIDRegexpStr = `.*/([^\s/]+)/(` + containerRegexpStr + `)/[\S]*hostname` - - // From https://github.com/torvalds/linux/blob/5859a2b1991101d6b978f3feb5325dad39421f29/include/linux/proc_ns.h#L41-L49 - // Currently, host namespace inode number are hardcoded, which can be used to detect - // if we're running in host namespace or not (does not work when running in DinD) - hostCgroupNamespaceInode = 0xEFFFFFFB -) - -var ( - // expLine matches a line in the /proc/self/cgroup file. It has a submatch for the last element (path), which contains the container ID. - expLine = regexp.MustCompile(`^\d+:[^:]*:(.+)$`) - - // expContainerID matches contained IDs and sources. Source: https://github.com/Qard/container-info/blob/master/index.js - expContainerID = regexp.MustCompile(fmt.Sprintf(`(%s|%s|%s)(?:.scope)?$`, uuidSource, containerSource, taskSource)) - - cIDMountInfoRegexp = regexp.MustCompile(cIDRegexpStr) - - // initContainerID initializes the container ID. - initContainerID = internalInitContainerID -) - -// parseContainerID finds the first container ID reading from r and returns it. -func parseContainerID(r io.Reader) string { - scn := bufio.NewScanner(r) - for scn.Scan() { - path := expLine.FindStringSubmatch(scn.Text()) - if len(path) != 2 { - // invalid entry, continue - continue - } - if parts := expContainerID.FindStringSubmatch(path[1]); len(parts) == 2 { - return parts[1] - } - } - return "" -} - -// readContainerID attempts to return the container ID from the provided file path or empty on failure. -func readContainerID(fpath string) string { - f, err := os.Open(fpath) - if err != nil { - return "" - } - defer f.Close() - return parseContainerID(f) -} - -// Parsing /proc/self/mountinfo is not always reliable in Kubernetes+containerd (at least) -// We're still trying to use it as it may help in some cgroupv2 configurations (Docker, ECS, raw containerd) -func parseMountinfo(r io.Reader) string { - scn := bufio.NewScanner(r) - for scn.Scan() { - line := scn.Text() - allMatches := cIDMountInfoRegexp.FindAllStringSubmatch(line, -1) - if len(allMatches) == 0 { - continue - } - - // We're interest in rightmost match - matches := allMatches[len(allMatches)-1] - if len(matches) > 0 && matches[1] != containerdSandboxPrefix { - return matches[2] - } - } - - return "" -} - -func readMountinfo(path string) string { - f, err := os.Open(path) - if err != nil { - return "" - } - defer f.Close() - return parseMountinfo(f) -} - -func isHostCgroupNamespace() bool { - fi, err := os.Stat("/proc/self/ns/cgroup") - if err != nil { - return false - } - - inode := fi.Sys().(*syscall.Stat_t).Ino - - return inode == hostCgroupNamespaceInode -} - -// parseCgroupNodePath parses /proc/self/cgroup and returns a map of controller to its associated cgroup node path. -func parseCgroupNodePath(r io.Reader) map[string]string { - res := make(map[string]string) - scn := bufio.NewScanner(r) - for scn.Scan() { - line := scn.Text() - tokens := strings.Split(line, ":") - if len(tokens) != 3 { - continue - } - if tokens[1] == cgroupV1BaseController || tokens[1] == "" { - res[tokens[1]] = tokens[2] - } - } - return res -} - -// getCgroupInode returns the cgroup controller inode if it exists otherwise an empty string. -// The inode is prefixed by "in-" and is used by the agent to retrieve the container ID. -// For cgroup v1, we use the memory controller. -func getCgroupInode(cgroupMountPath, procSelfCgroupPath string) string { - // Parse /proc/self/cgroup to retrieve the paths to the memory controller (cgroupv1) and the cgroup node (cgroupv2) - f, err := os.Open(procSelfCgroupPath) - if err != nil { - return "" - } - defer f.Close() - cgroupControllersPaths := parseCgroupNodePath(f) - // Retrieve the cgroup inode from /sys/fs/cgroup+controller+cgroupNodePath - for _, controller := range []string{cgroupV1BaseController, ""} { - cgroupNodePath, ok := cgroupControllersPaths[controller] - if !ok { - continue - } - inode := inodeForPath(path.Join(cgroupMountPath, controller, cgroupNodePath)) - if inode != "" { - return inode - } - } - return "" -} - -// inodeForPath returns the inode for the provided path or empty on failure. -func inodeForPath(path string) string { - fi, err := os.Stat(path) - if err != nil { - return "" - } - stats, ok := fi.Sys().(*syscall.Stat_t) - if !ok { - return "" - } - return fmt.Sprintf("in-%d", stats.Ino) -} - -// internalInitContainerID initializes the container ID. -// It can either be provided by the user or read from cgroups. -func internalInitContainerID(userProvidedID string, cgroupFallback bool) { - initOnce.Do(func() { - if userProvidedID != "" { - containerID = userProvidedID - return - } - - if cgroupFallback { - isHostCgroupNs := isHostCgroupNamespace() - if isHostCgroupNs { - containerID = readContainerID(cgroupPath) - return - } - containerID = readMountinfo(selfMountInfoPath) - if containerID != "" { - containerID = getCgroupInode(defaultCgroupMountPath, cgroupPath) - } - } - }) -} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/container_stub.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/container_stub.go deleted file mode 100644 index 5a143d19..00000000 --- a/vendor/github.com/DataDog/datadog-go/v5/statsd/container_stub.go +++ /dev/null @@ -1,13 +0,0 @@ -//go:build !linux -// +build !linux - -package statsd - -var initContainerID = func(userProvidedID string, cgroupFallback bool) { - initOnce.Do(func() { - if userProvidedID != "" { - containerID = userProvidedID - return - } - }) -} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/error_handler.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/error_handler.go deleted file mode 100644 index 00762627..00000000 --- a/vendor/github.com/DataDog/datadog-go/v5/statsd/error_handler.go +++ /dev/null @@ -1,22 +0,0 @@ -package statsd - -import ( - "log" -) - -func LoggingErrorHandler(err error) { - if e, ok := err.(*ErrorInputChannelFull); ok { - log.Printf( - "Input Queue is full (%d elements): %s %s dropped - %s - increase channel buffer size with `WithChannelModeBufferSize()`", - e.ChannelSize, e.Metric.name, e.Metric.tags, e.Msg, - ) - return - } else if e, ok := err.(*ErrorSenderChannelFull); ok { - log.Printf( - "Sender Queue is full (%d elements): %d metrics dropped - %s - increase sender queue size with `WithSenderQueueSize()`", - e.ChannelSize, e.LostElements, e.Msg, - ) - } else { - log.Printf("Error: %v", err) - } -} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/event.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/event.go deleted file mode 100644 index a2ca4faf..00000000 --- a/vendor/github.com/DataDog/datadog-go/v5/statsd/event.go +++ /dev/null @@ -1,75 +0,0 @@ -package statsd - -import ( - "fmt" - "time" -) - -// Events support -// EventAlertType and EventAlertPriority became exported types after this issue was submitted: https://github.com/DataDog/datadog-go/issues/41 -// The reason why they got exported is so that client code can directly use the types. - -// EventAlertType is the alert type for events -type EventAlertType string - -const ( - // Info is the "info" AlertType for events - Info EventAlertType = "info" - // Error is the "error" AlertType for events - Error EventAlertType = "error" - // Warning is the "warning" AlertType for events - Warning EventAlertType = "warning" - // Success is the "success" AlertType for events - Success EventAlertType = "success" -) - -// EventPriority is the event priority for events -type EventPriority string - -const ( - // Normal is the "normal" Priority for events - Normal EventPriority = "normal" - // Low is the "low" Priority for events - Low EventPriority = "low" -) - -// An Event is an object that can be posted to your DataDog event stream. -type Event struct { - // Title of the event. Required. - Title string - // Text is the description of the event. - Text string - // Timestamp is a timestamp for the event. If not provided, the dogstatsd - // server will set this to the current time. - Timestamp time.Time - // Hostname for the event. - Hostname string - // AggregationKey groups this event with others of the same key. - AggregationKey string - // Priority of the event. Can be statsd.Low or statsd.Normal. - Priority EventPriority - // SourceTypeName is a source type for the event. - SourceTypeName string - // AlertType can be statsd.Info, statsd.Error, statsd.Warning, or statsd.Success. - // If absent, the default value applied by the dogstatsd server is Info. - AlertType EventAlertType - // Tags for the event. - Tags []string -} - -// NewEvent creates a new event with the given title and text. Error checking -// against these values is done at send-time, or upon running e.Check. -func NewEvent(title, text string) *Event { - return &Event{ - Title: title, - Text: text, - } -} - -// Check verifies that an event is valid. -func (e *Event) Check() error { - if len(e.Title) == 0 { - return fmt.Errorf("statsd.Event title is required") - } - return nil -} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/fnv1a.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/fnv1a.go deleted file mode 100644 index 03dc8a07..00000000 --- a/vendor/github.com/DataDog/datadog-go/v5/statsd/fnv1a.go +++ /dev/null @@ -1,39 +0,0 @@ -package statsd - -const ( - // FNV-1a - offset32 = uint32(2166136261) - prime32 = uint32(16777619) - - // init32 is what 32 bits hash values should be initialized with. - init32 = offset32 -) - -// HashString32 returns the hash of s. -func hashString32(s string) uint32 { - return addString32(init32, s) -} - -// AddString32 adds the hash of s to the precomputed hash value h. -func addString32(h uint32, s string) uint32 { - i := 0 - n := (len(s) / 8) * 8 - - for i != n { - h = (h ^ uint32(s[i])) * prime32 - h = (h ^ uint32(s[i+1])) * prime32 - h = (h ^ uint32(s[i+2])) * prime32 - h = (h ^ uint32(s[i+3])) * prime32 - h = (h ^ uint32(s[i+4])) * prime32 - h = (h ^ uint32(s[i+5])) * prime32 - h = (h ^ uint32(s[i+6])) * prime32 - h = (h ^ uint32(s[i+7])) * prime32 - i += 8 - } - - for _, c := range s[i:] { - h = (h ^ uint32(c)) * prime32 - } - - return h -} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/format.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/format.go deleted file mode 100644 index f3ab9231..00000000 --- a/vendor/github.com/DataDog/datadog-go/v5/statsd/format.go +++ /dev/null @@ -1,280 +0,0 @@ -package statsd - -import ( - "strconv" - "strings" -) - -var ( - gaugeSymbol = []byte("g") - countSymbol = []byte("c") - histogramSymbol = []byte("h") - distributionSymbol = []byte("d") - setSymbol = []byte("s") - timingSymbol = []byte("ms") - tagSeparatorSymbol = "," - nameSeparatorSymbol = ":" -) - -func appendHeader(buffer []byte, namespace string, name string) []byte { - if namespace != "" { - buffer = append(buffer, namespace...) - } - buffer = append(buffer, name...) - buffer = append(buffer, ':') - return buffer -} - -func appendRate(buffer []byte, rate float64) []byte { - if rate < 1 { - buffer = append(buffer, "|@"...) - buffer = strconv.AppendFloat(buffer, rate, 'f', -1, 64) - } - return buffer -} - -func appendWithoutNewlines(buffer []byte, s string) []byte { - // fastpath for strings without newlines - if strings.IndexByte(s, '\n') == -1 { - return append(buffer, s...) - } - - for _, b := range []byte(s) { - if b != '\n' { - buffer = append(buffer, b) - } - } - return buffer -} - -func appendTags(buffer []byte, globalTags []string, tags []string) []byte { - if len(globalTags) == 0 && len(tags) == 0 { - return buffer - } - buffer = append(buffer, "|#"...) - firstTag := true - - for _, tag := range globalTags { - if !firstTag { - buffer = append(buffer, tagSeparatorSymbol...) - } - buffer = appendWithoutNewlines(buffer, tag) - firstTag = false - } - for _, tag := range tags { - if !firstTag { - buffer = append(buffer, tagSeparatorSymbol...) - } - buffer = appendWithoutNewlines(buffer, tag) - firstTag = false - } - return buffer -} - -func appendTagsAggregated(buffer []byte, globalTags []string, tags string) []byte { - if len(globalTags) == 0 && tags == "" { - return buffer - } - - buffer = append(buffer, "|#"...) - firstTag := true - - for _, tag := range globalTags { - if !firstTag { - buffer = append(buffer, tagSeparatorSymbol...) - } - buffer = appendWithoutNewlines(buffer, tag) - firstTag = false - } - if tags != "" { - if !firstTag { - buffer = append(buffer, tagSeparatorSymbol...) - } - buffer = appendWithoutNewlines(buffer, tags) - } - return buffer -} - -func appendFloatMetric(buffer []byte, typeSymbol []byte, namespace string, globalTags []string, name string, value float64, tags []string, rate float64, precision int) []byte { - buffer = appendHeader(buffer, namespace, name) - buffer = strconv.AppendFloat(buffer, value, 'f', precision, 64) - buffer = append(buffer, '|') - buffer = append(buffer, typeSymbol...) - buffer = appendRate(buffer, rate) - buffer = appendTags(buffer, globalTags, tags) - buffer = appendContainerID(buffer) - return buffer -} - -func appendIntegerMetric(buffer []byte, typeSymbol []byte, namespace string, globalTags []string, name string, value int64, tags []string, rate float64) []byte { - buffer = appendHeader(buffer, namespace, name) - buffer = strconv.AppendInt(buffer, value, 10) - buffer = append(buffer, '|') - buffer = append(buffer, typeSymbol...) - buffer = appendRate(buffer, rate) - buffer = appendTags(buffer, globalTags, tags) - buffer = appendContainerID(buffer) - return buffer -} - -func appendStringMetric(buffer []byte, typeSymbol []byte, namespace string, globalTags []string, name string, value string, tags []string, rate float64) []byte { - buffer = appendHeader(buffer, namespace, name) - buffer = append(buffer, value...) - buffer = append(buffer, '|') - buffer = append(buffer, typeSymbol...) - buffer = appendRate(buffer, rate) - buffer = appendTags(buffer, globalTags, tags) - buffer = appendContainerID(buffer) - return buffer -} - -func appendGauge(buffer []byte, namespace string, globalTags []string, name string, value float64, tags []string, rate float64) []byte { - return appendFloatMetric(buffer, gaugeSymbol, namespace, globalTags, name, value, tags, rate, -1) -} - -func appendCount(buffer []byte, namespace string, globalTags []string, name string, value int64, tags []string, rate float64) []byte { - return appendIntegerMetric(buffer, countSymbol, namespace, globalTags, name, value, tags, rate) -} - -func appendHistogram(buffer []byte, namespace string, globalTags []string, name string, value float64, tags []string, rate float64) []byte { - return appendFloatMetric(buffer, histogramSymbol, namespace, globalTags, name, value, tags, rate, -1) -} - -func appendDistribution(buffer []byte, namespace string, globalTags []string, name string, value float64, tags []string, rate float64) []byte { - return appendFloatMetric(buffer, distributionSymbol, namespace, globalTags, name, value, tags, rate, -1) -} - -func appendSet(buffer []byte, namespace string, globalTags []string, name string, value string, tags []string, rate float64) []byte { - return appendStringMetric(buffer, setSymbol, namespace, globalTags, name, value, tags, rate) -} - -func appendTiming(buffer []byte, namespace string, globalTags []string, name string, value float64, tags []string, rate float64) []byte { - return appendFloatMetric(buffer, timingSymbol, namespace, globalTags, name, value, tags, rate, 6) -} - -func escapedEventTextLen(text string) int { - return len(text) + strings.Count(text, "\n") -} - -func appendEscapedEventText(buffer []byte, text string) []byte { - for _, b := range []byte(text) { - if b != '\n' { - buffer = append(buffer, b) - } else { - buffer = append(buffer, "\\n"...) - } - } - return buffer -} - -func appendEvent(buffer []byte, event *Event, globalTags []string) []byte { - escapedTextLen := escapedEventTextLen(event.Text) - - buffer = append(buffer, "_e{"...) - buffer = strconv.AppendInt(buffer, int64(len(event.Title)), 10) - buffer = append(buffer, tagSeparatorSymbol...) - buffer = strconv.AppendInt(buffer, int64(escapedTextLen), 10) - buffer = append(buffer, "}:"...) - buffer = append(buffer, event.Title...) - buffer = append(buffer, '|') - if escapedTextLen != len(event.Text) { - buffer = appendEscapedEventText(buffer, event.Text) - } else { - buffer = append(buffer, event.Text...) - } - - if !event.Timestamp.IsZero() { - buffer = append(buffer, "|d:"...) - buffer = strconv.AppendInt(buffer, int64(event.Timestamp.Unix()), 10) - } - - if len(event.Hostname) != 0 { - buffer = append(buffer, "|h:"...) - buffer = append(buffer, event.Hostname...) - } - - if len(event.AggregationKey) != 0 { - buffer = append(buffer, "|k:"...) - buffer = append(buffer, event.AggregationKey...) - } - - if len(event.Priority) != 0 { - buffer = append(buffer, "|p:"...) - buffer = append(buffer, event.Priority...) - } - - if len(event.SourceTypeName) != 0 { - buffer = append(buffer, "|s:"...) - buffer = append(buffer, event.SourceTypeName...) - } - - if len(event.AlertType) != 0 { - buffer = append(buffer, "|t:"...) - buffer = append(buffer, string(event.AlertType)...) - } - - buffer = appendTags(buffer, globalTags, event.Tags) - buffer = appendContainerID(buffer) - return buffer -} - -func appendEscapedServiceCheckText(buffer []byte, text string) []byte { - for i := 0; i < len(text); i++ { - if text[i] == '\n' { - buffer = append(buffer, "\\n"...) - } else if text[i] == 'm' && i+1 < len(text) && text[i+1] == ':' { - buffer = append(buffer, "m\\:"...) - i++ - } else { - buffer = append(buffer, text[i]) - } - } - return buffer -} - -func appendServiceCheck(buffer []byte, serviceCheck *ServiceCheck, globalTags []string) []byte { - buffer = append(buffer, "_sc|"...) - buffer = append(buffer, serviceCheck.Name...) - buffer = append(buffer, '|') - buffer = strconv.AppendInt(buffer, int64(serviceCheck.Status), 10) - - if !serviceCheck.Timestamp.IsZero() { - buffer = append(buffer, "|d:"...) - buffer = strconv.AppendInt(buffer, int64(serviceCheck.Timestamp.Unix()), 10) - } - - if len(serviceCheck.Hostname) != 0 { - buffer = append(buffer, "|h:"...) - buffer = append(buffer, serviceCheck.Hostname...) - } - - buffer = appendTags(buffer, globalTags, serviceCheck.Tags) - - if len(serviceCheck.Message) != 0 { - buffer = append(buffer, "|m:"...) - buffer = appendEscapedServiceCheckText(buffer, serviceCheck.Message) - } - - buffer = appendContainerID(buffer) - return buffer -} - -func appendSeparator(buffer []byte) []byte { - return append(buffer, '\n') -} - -func appendContainerID(buffer []byte) []byte { - if containerID := getContainerID(); len(containerID) > 0 { - buffer = append(buffer, "|c:"...) - buffer = append(buffer, containerID...) - } - return buffer -} - -func appendTimestamp(buffer []byte, timestamp int64) []byte { - if timestamp > noTimestamp { - buffer = append(buffer, "|T"...) - buffer = strconv.AppendInt(buffer, timestamp, 10) - } - return buffer -} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/metrics.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/metrics.go deleted file mode 100644 index 3d243b7a..00000000 --- a/vendor/github.com/DataDog/datadog-go/v5/statsd/metrics.go +++ /dev/null @@ -1,268 +0,0 @@ -package statsd - -import ( - "math" - "math/rand" - "sync" - "sync/atomic" -) - -/* -Those are metrics type that can be aggregated on the client side: - - Gauge - - Count - - Set -*/ - -type countMetric struct { - value int64 - name string - tags []string -} - -func newCountMetric(name string, value int64, tags []string) *countMetric { - return &countMetric{ - value: value, - name: name, - tags: copySlice(tags), - } -} - -func (c *countMetric) sample(v int64) { - atomic.AddInt64(&c.value, v) -} - -func (c *countMetric) flushUnsafe() metric { - return metric{ - metricType: count, - name: c.name, - tags: c.tags, - rate: 1, - ivalue: c.value, - } -} - -// Gauge - -type gaugeMetric struct { - value uint64 - name string - tags []string -} - -func newGaugeMetric(name string, value float64, tags []string) *gaugeMetric { - return &gaugeMetric{ - value: math.Float64bits(value), - name: name, - tags: copySlice(tags), - } -} - -func (g *gaugeMetric) sample(v float64) { - atomic.StoreUint64(&g.value, math.Float64bits(v)) -} - -func (g *gaugeMetric) flushUnsafe() metric { - return metric{ - metricType: gauge, - name: g.name, - tags: g.tags, - rate: 1, - fvalue: math.Float64frombits(g.value), - } -} - -// Set - -type setMetric struct { - data map[string]struct{} - name string - tags []string - sync.Mutex -} - -func newSetMetric(name string, value string, tags []string) *setMetric { - set := &setMetric{ - data: map[string]struct{}{}, - name: name, - tags: copySlice(tags), - } - set.data[value] = struct{}{} - return set -} - -func (s *setMetric) sample(v string) { - s.Lock() - defer s.Unlock() - s.data[v] = struct{}{} -} - -// Sets are aggregated on the agent side too. We flush the keys so a set from -// multiple application can be correctly aggregated on the agent side. -func (s *setMetric) flushUnsafe() []metric { - if len(s.data) == 0 { - return nil - } - - metrics := make([]metric, len(s.data)) - i := 0 - for value := range s.data { - metrics[i] = metric{ - metricType: set, - name: s.name, - tags: s.tags, - rate: 1, - svalue: value, - } - i++ - } - return metrics -} - -// Histograms, Distributions and Timings - -type bufferedMetric struct { - sync.Mutex - - // Kept samples (after sampling) - data []float64 - // Total stored samples (after sampling) - storedSamples int64 - // Total number of observed samples (before sampling). This is used to keep - // the sampling rate correct. - totalSamples int64 - - name string - // Histograms and Distributions store tags as one string since we need - // to compute its size multiple time when serializing. - tags string - mtype metricType - - // maxSamples is the maximum number of samples we keep in memory - maxSamples int64 - - // The first observed user-specified sample rate. When specified - // it is used because we don't know better. - specifiedRate float64 -} - -func (s *bufferedMetric) sample(v float64) { - s.Lock() - defer s.Unlock() - s.sampleUnsafe(v) -} - -func (s *bufferedMetric) sampleUnsafe(v float64) { - s.data = append(s.data, v) - s.storedSamples++ - // Total samples needs to be incremented though an atomic because it can be accessed without the lock. - atomic.AddInt64(&s.totalSamples, 1) -} - -func (s *bufferedMetric) maybeKeepSample(v float64, rand *rand.Rand, randLock *sync.Mutex) { - s.Lock() - defer s.Unlock() - if s.maxSamples > 0 { - if s.storedSamples >= s.maxSamples { - // We reached the maximum number of samples we can keep in memory, so we randomly - // replace a sample. - randLock.Lock() - i := rand.Int63n(atomic.LoadInt64(&s.totalSamples)) - randLock.Unlock() - if i < s.maxSamples { - s.data[i] = v - } - } else { - s.data[s.storedSamples] = v - s.storedSamples++ - } - s.totalSamples++ - } else { - // This code path appends to the slice since we did not pre-allocate memory in this case. - s.sampleUnsafe(v) - } -} - -func (s *bufferedMetric) skipSample() { - atomic.AddInt64(&s.totalSamples, 1) -} - -func (s *bufferedMetric) flushUnsafe() metric { - totalSamples := atomic.LoadInt64(&s.totalSamples) - var rate float64 - - // If the user had a specified rate send it because we don't know better. - // This code should be removed once we can also remove the early return at the top of - // `bufferedMetricContexts.sample` - if s.specifiedRate != 1.0 { - rate = s.specifiedRate - } else { - rate = float64(s.storedSamples) / float64(totalSamples) - } - - return metric{ - metricType: s.mtype, - name: s.name, - stags: s.tags, - rate: rate, - fvalues: s.data[:s.storedSamples], - } -} - -type histogramMetric = bufferedMetric - -func newHistogramMetric(name string, value float64, stringTags string, maxSamples int64, rate float64) *histogramMetric { - return &histogramMetric{ - data: newData(value, maxSamples), - totalSamples: 1, - storedSamples: 1, - name: name, - tags: stringTags, - mtype: histogramAggregated, - maxSamples: maxSamples, - specifiedRate: rate, - } -} - -type distributionMetric = bufferedMetric - -func newDistributionMetric(name string, value float64, stringTags string, maxSamples int64, rate float64) *distributionMetric { - return &distributionMetric{ - data: newData(value, maxSamples), - totalSamples: 1, - storedSamples: 1, - name: name, - tags: stringTags, - mtype: distributionAggregated, - maxSamples: maxSamples, - specifiedRate: rate, - } -} - -type timingMetric = bufferedMetric - -func newTimingMetric(name string, value float64, stringTags string, maxSamples int64, rate float64) *timingMetric { - return &timingMetric{ - data: newData(value, maxSamples), - totalSamples: 1, - storedSamples: 1, - name: name, - tags: stringTags, - mtype: timingAggregated, - maxSamples: maxSamples, - specifiedRate: rate, - } -} - -// newData creates a new slice of float64 with the given capacity. If maxSample -// is less than or equal to 0, it returns a slice with the given value as the -// only element. -func newData(value float64, maxSample int64) []float64 { - if maxSample <= 0 { - return []float64{value} - } else { - data := make([]float64, maxSample) - data[0] = value - return data - } -} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/noop.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/noop.go deleted file mode 100644 index 6500cde9..00000000 --- a/vendor/github.com/DataDog/datadog-go/v5/statsd/noop.go +++ /dev/null @@ -1,118 +0,0 @@ -package statsd - -import "time" - -// NoOpClient is a statsd client that does nothing. Can be useful in testing -// situations for library users. -type NoOpClient struct{} - -// Gauge does nothing and returns nil -func (n *NoOpClient) Gauge(name string, value float64, tags []string, rate float64) error { - return nil -} - -// GaugeWithTimestamp does nothing and returns nil -func (n *NoOpClient) GaugeWithTimestamp(name string, value float64, tags []string, rate float64, timestamp time.Time) error { - return nil -} - -// Count does nothing and returns nil -func (n *NoOpClient) Count(name string, value int64, tags []string, rate float64) error { - return nil -} - -// CountWithTimestamp does nothing and returns nil -func (n *NoOpClient) CountWithTimestamp(name string, value int64, tags []string, rate float64, timestamp time.Time) error { - return nil -} - -// Histogram does nothing and returns nil -func (n *NoOpClient) Histogram(name string, value float64, tags []string, rate float64) error { - return nil -} - -// Distribution does nothing and returns nil -func (n *NoOpClient) Distribution(name string, value float64, tags []string, rate float64) error { - return nil -} - -// Decr does nothing and returns nil -func (n *NoOpClient) Decr(name string, tags []string, rate float64) error { - return nil -} - -// Incr does nothing and returns nil -func (n *NoOpClient) Incr(name string, tags []string, rate float64) error { - return nil -} - -// Set does nothing and returns nil -func (n *NoOpClient) Set(name string, value string, tags []string, rate float64) error { - return nil -} - -// Timing does nothing and returns nil -func (n *NoOpClient) Timing(name string, value time.Duration, tags []string, rate float64) error { - return nil -} - -// TimeInMilliseconds does nothing and returns nil -func (n *NoOpClient) TimeInMilliseconds(name string, value float64, tags []string, rate float64) error { - return nil -} - -// Event does nothing and returns nil -func (n *NoOpClient) Event(e *Event) error { - return nil -} - -// SimpleEvent does nothing and returns nil -func (n *NoOpClient) SimpleEvent(title, text string) error { - return nil -} - -// ServiceCheck does nothing and returns nil -func (n *NoOpClient) ServiceCheck(sc *ServiceCheck) error { - return nil -} - -// SimpleServiceCheck does nothing and returns nil -func (n *NoOpClient) SimpleServiceCheck(name string, status ServiceCheckStatus) error { - return nil -} - -// Close does nothing and returns nil -func (n *NoOpClient) Close() error { - return nil -} - -// Flush does nothing and returns nil -func (n *NoOpClient) Flush() error { - return nil -} - -// IsClosed does nothing and return false -func (n *NoOpClient) IsClosed() bool { - return false -} - -// GetTelemetry does nothing and returns an empty Telemetry -func (n *NoOpClient) GetTelemetry() Telemetry { - return Telemetry{} -} - -// Verify that NoOpClient implements the ClientInterface. -// https://golang.org/doc/faq#guarantee_satisfies_interface -var _ ClientInterface = &NoOpClient{} - -// NoOpClientDirect implements ClientDirectInterface and does nothing. -type NoOpClientDirect struct { - NoOpClient -} - -// DistributionSamples does nothing and returns nil -func (n *NoOpClientDirect) DistributionSamples(name string, values []float64, tags []string, rate float64) error { - return nil -} - -var _ ClientDirectInterface = &NoOpClientDirect{} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/options.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/options.go deleted file mode 100644 index 29e09800..00000000 --- a/vendor/github.com/DataDog/datadog-go/v5/statsd/options.go +++ /dev/null @@ -1,413 +0,0 @@ -package statsd - -import ( - "fmt" - "math" - "strings" - "time" -) - -var ( - defaultNamespace = "" - defaultTags = []string{} - defaultMaxBytesPerPayload = 0 - defaultMaxMessagesPerPayload = math.MaxInt32 - defaultBufferPoolSize = 0 - defaultBufferFlushInterval = 100 * time.Millisecond - defaultWorkerCount = 32 - defaultSenderQueueSize = 0 - defaultWriteTimeout = 100 * time.Millisecond - defaultConnectTimeout = 1000 * time.Millisecond - defaultTelemetry = true - defaultReceivingMode = mutexMode - defaultChannelModeBufferSize = 4096 - defaultAggregationFlushInterval = 2 * time.Second - defaultAggregation = true - defaultExtendedAggregation = false - defaultMaxBufferedSamplesPerContext = -1 - defaultOriginDetection = true - defaultChannelModeErrorsWhenFull = false - defaultErrorHandler = func(error) {} -) - -// Options contains the configuration options for a client. -type Options struct { - namespace string - tags []string - maxBytesPerPayload int - maxMessagesPerPayload int - bufferPoolSize int - bufferFlushInterval time.Duration - workersCount int - senderQueueSize int - writeTimeout time.Duration - connectTimeout time.Duration - telemetry bool - receiveMode receivingMode - channelModeBufferSize int - aggregationFlushInterval time.Duration - aggregation bool - extendedAggregation bool - maxBufferedSamplesPerContext int - telemetryAddr string - originDetection bool - containerID string - channelModeErrorsWhenFull bool - errorHandler ErrorHandler -} - -func resolveOptions(options []Option) (*Options, error) { - o := &Options{ - namespace: defaultNamespace, - tags: defaultTags, - maxBytesPerPayload: defaultMaxBytesPerPayload, - maxMessagesPerPayload: defaultMaxMessagesPerPayload, - bufferPoolSize: defaultBufferPoolSize, - bufferFlushInterval: defaultBufferFlushInterval, - workersCount: defaultWorkerCount, - senderQueueSize: defaultSenderQueueSize, - writeTimeout: defaultWriteTimeout, - connectTimeout: defaultConnectTimeout, - telemetry: defaultTelemetry, - receiveMode: defaultReceivingMode, - channelModeBufferSize: defaultChannelModeBufferSize, - aggregationFlushInterval: defaultAggregationFlushInterval, - aggregation: defaultAggregation, - extendedAggregation: defaultExtendedAggregation, - maxBufferedSamplesPerContext: defaultMaxBufferedSamplesPerContext, - originDetection: defaultOriginDetection, - channelModeErrorsWhenFull: defaultChannelModeErrorsWhenFull, - errorHandler: defaultErrorHandler, - } - - for _, option := range options { - err := option(o) - if err != nil { - return nil, err - } - } - - return o, nil -} - -// Option is a client option. Can return an error if validation fails. -type Option func(*Options) error - -// WithNamespace sets a string to be prepend to all metrics, events and service checks name. -// -// A '.' will automatically be added after the namespace if needed. For example a metrics 'test' with a namespace 'prod' -// will produce a final metric named 'prod.test'. -func WithNamespace(namespace string) Option { - return func(o *Options) error { - if strings.HasSuffix(namespace, ".") { - o.namespace = namespace - } else { - o.namespace = namespace + "." - } - return nil - } -} - -// WithTags sets global tags to be applied to every metrics, events and service checks. -func WithTags(tags []string) Option { - return func(o *Options) error { - o.tags = tags - return nil - } -} - -// WithMaxMessagesPerPayload sets the maximum number of metrics, events and/or service checks that a single payload can -// contain. -// -// The default is 'math.MaxInt32' which will most likely let the WithMaxBytesPerPayload option take precedence. This -// option can be set to `1` to create an unbuffered client (each metrics/event/service check will be send in its own -// payload to the agent). -func WithMaxMessagesPerPayload(maxMessagesPerPayload int) Option { - return func(o *Options) error { - o.maxMessagesPerPayload = maxMessagesPerPayload - return nil - } -} - -// WithMaxBytesPerPayload sets the maximum number of bytes a single payload can contain. Each sample, even and service -// check must be lower than this value once serialized or an `MessageTooLongError` is returned. -// -// The default value 0 which will set the option to the optimal size for the transport protocol used: 1432 for UDP and -// named pipe and 8192 for UDS. Those values offer the best performances. -// Be careful when changing this option, see -// https://docs.datadoghq.com/developers/dogstatsd/high_throughput/#ensure-proper-packet-sizes. -func WithMaxBytesPerPayload(MaxBytesPerPayload int) Option { - return func(o *Options) error { - o.maxBytesPerPayload = MaxBytesPerPayload - return nil - } -} - -// WithBufferPoolSize sets the size of the pool of buffers used to serialized metrics, events and service_checks. -// -// The default, 0, will set the option to the optimal size for the transport protocol used: 2048 for UDP and named pipe -// and 512 for UDS. -func WithBufferPoolSize(bufferPoolSize int) Option { - return func(o *Options) error { - o.bufferPoolSize = bufferPoolSize - return nil - } -} - -// WithBufferFlushInterval sets the interval after which the current buffer is flushed. -// -// A buffers are used to serialized data, they're flushed either when full (see WithMaxBytesPerPayload) or when it's -// been open for longer than this interval. -// -// With apps sending a high number of metrics/events/service_checks the interval rarely timeout. But with slow sending -// apps increasing this value will reduce the number of payload sent on the wire as more data is serialized in the same -// payload. -// -// Default is 100ms -func WithBufferFlushInterval(bufferFlushInterval time.Duration) Option { - return func(o *Options) error { - o.bufferFlushInterval = bufferFlushInterval - return nil - } -} - -// WithWorkersCount sets the number of workers that will be used to serialized data. -// -// Those workers allow the use of multiple buffers at the same time (see WithBufferPoolSize) to reduce lock contention. -// -// Default is 32. -func WithWorkersCount(workersCount int) Option { - return func(o *Options) error { - if workersCount < 1 { - return fmt.Errorf("workersCount must be a positive integer") - } - o.workersCount = workersCount - return nil - } -} - -// WithSenderQueueSize sets the size of the sender queue in number of buffers. -// -// After data has been serialized in a buffer they're pushed to a queue that the sender will consume and then each one -// ot the agent. -// -// The default value 0 will set the option to the optimal size for the transport protocol used: 2048 for UDP and named -// pipe and 512 for UDS. -func WithSenderQueueSize(senderQueueSize int) Option { - return func(o *Options) error { - o.senderQueueSize = senderQueueSize - return nil - } -} - -// WithWriteTimeout sets the timeout for network communication with the Agent, after this interval a payload is -// dropped. This is only used for UDS and named pipes connection. -func WithWriteTimeout(writeTimeout time.Duration) Option { - return func(o *Options) error { - o.writeTimeout = writeTimeout - return nil - } -} - -// WithConnectTimeout sets the timeout for network connection with the Agent, after this interval the connection -// attempt is aborted. This is only used for UDS connection. This will also reset the connection if nothing can be -// written to it for this duration. -func WithConnectTimeout(connectTimeout time.Duration) Option { - return func(o *Options) error { - o.connectTimeout = connectTimeout - return nil - } -} - -// WithChannelMode make the client use channels to receive metrics -// -// This determines how the client receive metrics from the app (for example when calling the `Gauge()` method). -// The client will either drop the metrics if its buffers are full (WithChannelMode option) or block the caller until the -// metric can be handled (WithMutexMode option). By default, the client use mutexes. -// -// WithChannelMode uses a channel (see WithChannelModeBufferSize to configure its size) to receive metrics and drops metrics if -// the channel is full. Sending metrics in this mode is much slower that WithMutexMode (because of the channel), but will not -// block the application. This mode is made for application using statsd directly into the application code instead of -// a separated periodic reporter. The goal is to not slow down the application at the cost of dropping metrics and having a lower max -// throughput. -func WithChannelMode() Option { - return func(o *Options) error { - o.receiveMode = channelMode - return nil - } -} - -// WithMutexMode will use mutex to receive metrics from the app through the API. -// -// This determines how the client receive metrics from the app (for example when calling the `Gauge()` method). -// The client will either drop the metrics if its buffers are full (WithChannelMode option) or block the caller until the -// metric can be handled (WithMutexMode option). By default the client use mutexes. -// -// WithMutexMode uses mutexes to receive metrics which is much faster than channels but can cause some lock contention -// when used with a high number of goroutines sending the same metrics. Mutexes are sharded based on the metrics name -// which limit mutex contention when multiple goroutines send different metrics (see WithWorkersCount). This is the -// default behavior which will produce the best throughput. -func WithMutexMode() Option { - return func(o *Options) error { - o.receiveMode = mutexMode - return nil - } -} - -// WithChannelModeBufferSize sets the size of the channel holding incoming metrics when WithChannelMode is used. -func WithChannelModeBufferSize(bufferSize int) Option { - return func(o *Options) error { - o.channelModeBufferSize = bufferSize - return nil - } -} - -// WithChannelModeErrorsWhenFull makes the client return an error when the channel is full. -// This should be enabled if you want to be notified when the client is dropping metrics. You -// will also need to set `WithErrorHandler` to be notified of sender error. This might have -// a small performance impact. -func WithChannelModeErrorsWhenFull() Option { - return func(o *Options) error { - o.channelModeErrorsWhenFull = true - return nil - } -} - -// WithoutChannelModeErrorsWhenFull makes the client not return an error when the channel is full. -func WithoutChannelModeErrorsWhenFull() Option { - return func(o *Options) error { - o.channelModeErrorsWhenFull = false - return nil - } -} - -// WithErrorHandler sets a function that will be called when an error occurs. -func WithErrorHandler(errorHandler ErrorHandler) Option { - return func(o *Options) error { - o.errorHandler = errorHandler - return nil - } -} - -// WithAggregationInterval sets the interval at which aggregated metrics are flushed. See WithClientSideAggregation and -// WithExtendedClientSideAggregation for more. -// -// The default interval is 2s. The interval must divide the Agent reporting period (default=10s) evenly to reduce "aliasing" -// that can cause values to appear irregular/spiky. -// -// For example a 3s aggregation interval will create spikes in the final graph: a application sending a count metric -// that increments at a constant 1000 time per second will appear noisy with an interval of 3s. This is because -// client-side aggregation would report every 3 seconds, while the agent is reporting every 10 seconds. This means in -// each agent bucket, the values are: 9000, 9000, 12000. -func WithAggregationInterval(interval time.Duration) Option { - return func(o *Options) error { - o.aggregationFlushInterval = interval - return nil - } -} - -// WithClientSideAggregation enables client side aggregation for Gauges, Counts and Sets. -func WithClientSideAggregation() Option { - return func(o *Options) error { - o.aggregation = true - return nil - } -} - -// WithoutClientSideAggregation disables client side aggregation. -func WithoutClientSideAggregation() Option { - return func(o *Options) error { - o.aggregation = false - o.extendedAggregation = false - return nil - } -} - -// WithExtendedClientSideAggregation enables client side aggregation for all types. This feature is only compatible with -// Agent's version >=6.25.0 && <7.0.0 or Agent's versions >=7.25.0. -// When enabled, the use of `rate` with distribution is discouraged and `WithMaxSamplesPerContext()` should be used. -// If `rate` is used with different values of `rate` the resulting rate is not guaranteed to be correct. -func WithExtendedClientSideAggregation() Option { - return func(o *Options) error { - o.aggregation = true - o.extendedAggregation = true - return nil - } -} - -// WithMaxSamplesPerContext limits the number of sample for metric types that require multiple samples to be send -// over statsd to the agent, such as distributions or timings. This limits the number of sample per -// context for a distribution to a given number. Gauges and counts will not be affected as a single sample per context -// is sent with client side aggregation. -// - This will enable client side aggregation for all metrics. -// - This feature should be used with `WithExtendedClientSideAggregation` for optimal results. -func WithMaxSamplesPerContext(maxSamplesPerDistribution int) Option { - return func(o *Options) error { - o.aggregation = true - o.maxBufferedSamplesPerContext = maxSamplesPerDistribution - return nil - } -} - -// WithoutTelemetry disables the client telemetry. -// -// More on this here: https://docs.datadoghq.com/developers/dogstatsd/high_throughput/#client-side-telemetry -func WithoutTelemetry() Option { - return func(o *Options) error { - o.telemetry = false - return nil - } -} - -// WithTelemetryAddr sets a different address for telemetry metrics. By default the same address as the client is used -// for telemetry. -// -// More on this here: https://docs.datadoghq.com/developers/dogstatsd/high_throughput/#client-side-telemetry -func WithTelemetryAddr(addr string) Option { - return func(o *Options) error { - o.telemetryAddr = addr - return nil - } -} - -// WithoutOriginDetection disables the client origin detection. -// When enabled, the client tries to discover its container ID and sends it to the Agent -// to enrich the metrics with container tags. -// Origin detection can also be disabled by configuring the environment variabe DD_ORIGIN_DETECTION_ENABLED=false -// The client tries to read the container ID by parsing the file /proc/self/cgroup, this is not supported on Windows. -// The client prioritizes the value passed via DD_ENTITY_ID (if set) over the container ID. -// -// More on this here: https://docs.datadoghq.com/developers/dogstatsd/?tab=kubernetes#origin-detection-over-udp -func WithoutOriginDetection() Option { - return func(o *Options) error { - o.originDetection = false - return nil - } -} - -// WithOriginDetection enables the client origin detection. -// This feature requires Datadog Agent version >=6.35.0 && <7.0.0 or Agent versions >=7.35.0. -// When enabled, the client tries to discover its container ID and sends it to the Agent -// to enrich the metrics with container tags. -// Origin detection can be disabled by configuring the environment variabe DD_ORIGIN_DETECTION_ENABLED=false -// The client tries to read the container ID by parsing the file /proc/self/cgroup, this is not supported on Windows. -// The client prioritizes the value passed via DD_ENTITY_ID (if set) over the container ID. -// -// More on this here: https://docs.datadoghq.com/developers/dogstatsd/?tab=kubernetes#origin-detection-over-udp -func WithOriginDetection() Option { - return func(o *Options) error { - o.originDetection = true - return nil - } -} - -// WithContainerID allows passing the container ID, this will be used by the Agent to enrich metrics with container tags. -// This feature requires Datadog Agent version >=6.35.0 && <7.0.0 or Agent versions >=7.35.0. -// When configured, the provided container ID is prioritized over the container ID discovered via Origin Detection. -// The client prioritizes the value passed via DD_ENTITY_ID (if set) over the container ID. -func WithContainerID(id string) Option { - return func(o *Options) error { - o.containerID = id - return nil - } -} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/pipe.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/pipe.go deleted file mode 100644 index 1188b00f..00000000 --- a/vendor/github.com/DataDog/datadog-go/v5/statsd/pipe.go +++ /dev/null @@ -1,13 +0,0 @@ -//go:build !windows -// +build !windows - -package statsd - -import ( - "errors" - "time" -) - -func newWindowsPipeWriter(pipepath string, writeTimeout time.Duration) (Transport, error) { - return nil, errors.New("Windows Named Pipes are only supported on Windows") -} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/pipe_windows.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/pipe_windows.go deleted file mode 100644 index c27434cc..00000000 --- a/vendor/github.com/DataDog/datadog-go/v5/statsd/pipe_windows.go +++ /dev/null @@ -1,81 +0,0 @@ -//go:build windows -// +build windows - -package statsd - -import ( - "net" - "sync" - "time" - - "github.com/Microsoft/go-winio" -) - -type pipeWriter struct { - mu sync.RWMutex - conn net.Conn - timeout time.Duration - pipepath string -} - -func (p *pipeWriter) Write(data []byte) (n int, err error) { - conn, err := p.ensureConnection() - if err != nil { - return 0, err - } - - p.mu.RLock() - conn.SetWriteDeadline(time.Now().Add(p.timeout)) - p.mu.RUnlock() - - n, err = conn.Write(data) - if err != nil { - if e, ok := err.(net.Error); !ok || !e.Temporary() { - // disconnected; retry again on next attempt - p.mu.Lock() - p.conn = nil - p.mu.Unlock() - } - } - return n, err -} - -func (p *pipeWriter) ensureConnection() (net.Conn, error) { - p.mu.RLock() - conn := p.conn - p.mu.RUnlock() - if conn != nil { - return conn, nil - } - - // looks like we might need to connect - try again with write locking. - p.mu.Lock() - defer p.mu.Unlock() - if p.conn != nil { - return p.conn, nil - } - newconn, err := winio.DialPipe(p.pipepath, nil) - if err != nil { - return nil, err - } - p.conn = newconn - return newconn, nil -} - -func (p *pipeWriter) Close() error { - return p.conn.Close() -} - -// GetTransportName returns the name of the transport -func (p *pipeWriter) GetTransportName() string { - return writerWindowsPipe -} - -func newWindowsPipeWriter(pipepath string, writeTimeout time.Duration) (*pipeWriter, error) { - // Defer connection establishment to first write - return &pipeWriter{ - conn: nil, - timeout: writeTimeout, - pipepath: pipepath, - }, nil -} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/sender.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/sender.go deleted file mode 100644 index fc80395c..00000000 --- a/vendor/github.com/DataDog/datadog-go/v5/statsd/sender.go +++ /dev/null @@ -1,145 +0,0 @@ -package statsd - -import ( - "io" - "sync/atomic" -) - -// senderTelemetry contains telemetry about the health of the sender -type senderTelemetry struct { - totalPayloadsSent uint64 - totalPayloadsDroppedQueueFull uint64 - totalPayloadsDroppedWriter uint64 - totalBytesSent uint64 - totalBytesDroppedQueueFull uint64 - totalBytesDroppedWriter uint64 -} - -type Transport interface { - io.WriteCloser - - // GetTransportName returns the name of the transport - GetTransportName() string -} - -type sender struct { - transport Transport - pool *bufferPool - queue chan *statsdBuffer - telemetry *senderTelemetry - stop chan struct{} - flushSignal chan struct{} - errorHandler ErrorHandler -} - -type ErrorSenderChannelFull struct { - LostElements int - ChannelSize int - Msg string -} - -func (e *ErrorSenderChannelFull) Error() string { - return e.Msg -} - -func newSender(transport Transport, queueSize int, pool *bufferPool, errorHandler ErrorHandler) *sender { - sender := &sender{ - transport: transport, - pool: pool, - queue: make(chan *statsdBuffer, queueSize), - telemetry: &senderTelemetry{}, - stop: make(chan struct{}), - flushSignal: make(chan struct{}), - errorHandler: errorHandler, - } - - go sender.sendLoop() - return sender -} - -func (s *sender) send(buffer *statsdBuffer) { - select { - case s.queue <- buffer: - default: - if s.errorHandler != nil { - err := &ErrorSenderChannelFull{ - LostElements: buffer.elementCount, - ChannelSize: len(s.queue), - Msg: "Sender queue is full", - } - s.errorHandler(err) - } - atomic.AddUint64(&s.telemetry.totalPayloadsDroppedQueueFull, 1) - atomic.AddUint64(&s.telemetry.totalBytesDroppedQueueFull, uint64(len(buffer.bytes()))) - s.pool.returnBuffer(buffer) - } -} - -func (s *sender) write(buffer *statsdBuffer) { - _, err := s.transport.Write(buffer.bytes()) - if err != nil { - atomic.AddUint64(&s.telemetry.totalPayloadsDroppedWriter, 1) - atomic.AddUint64(&s.telemetry.totalBytesDroppedWriter, uint64(len(buffer.bytes()))) - if s.errorHandler != nil { - s.errorHandler(err) - } - } else { - atomic.AddUint64(&s.telemetry.totalPayloadsSent, 1) - atomic.AddUint64(&s.telemetry.totalBytesSent, uint64(len(buffer.bytes()))) - } - s.pool.returnBuffer(buffer) -} - -func (s *sender) flushTelemetryMetrics(t *Telemetry) { - t.TotalPayloadsSent = atomic.LoadUint64(&s.telemetry.totalPayloadsSent) - t.TotalPayloadsDroppedQueueFull = atomic.LoadUint64(&s.telemetry.totalPayloadsDroppedQueueFull) - t.TotalPayloadsDroppedWriter = atomic.LoadUint64(&s.telemetry.totalPayloadsDroppedWriter) - - t.TotalBytesSent = atomic.LoadUint64(&s.telemetry.totalBytesSent) - t.TotalBytesDroppedQueueFull = atomic.LoadUint64(&s.telemetry.totalBytesDroppedQueueFull) - t.TotalBytesDroppedWriter = atomic.LoadUint64(&s.telemetry.totalBytesDroppedWriter) -} - -func (s *sender) sendLoop() { - defer close(s.stop) - for { - select { - case buffer := <-s.queue: - s.write(buffer) - case <-s.stop: - return - case <-s.flushSignal: - // At that point we know that the workers are paused (the statsd client - // will pause them before calling sender.flush()). - // So we can fully flush the input queue - s.flushInputQueue() - s.flushSignal <- struct{}{} - } - } -} - -func (s *sender) flushInputQueue() { - for { - select { - case buffer := <-s.queue: - s.write(buffer) - default: - return - } - } -} -func (s *sender) flush() { - s.flushSignal <- struct{}{} - <-s.flushSignal -} - -func (s *sender) close() error { - s.stop <- struct{}{} - <-s.stop - s.flushInputQueue() - return s.transport.Close() -} - -func (s *sender) getTransportName() string { - return s.transport.GetTransportName() -} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/service_check.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/service_check.go deleted file mode 100644 index e2850465..00000000 --- a/vendor/github.com/DataDog/datadog-go/v5/statsd/service_check.go +++ /dev/null @@ -1,57 +0,0 @@ -package statsd - -import ( - "fmt" - "time" -) - -// ServiceCheckStatus support -type ServiceCheckStatus byte - -const ( - // Ok is the "ok" ServiceCheck status - Ok ServiceCheckStatus = 0 - // Warn is the "warning" ServiceCheck status - Warn ServiceCheckStatus = 1 - // Critical is the "critical" ServiceCheck status - Critical ServiceCheckStatus = 2 - // Unknown is the "unknown" ServiceCheck status - Unknown ServiceCheckStatus = 3 -) - -// A ServiceCheck is an object that contains status of DataDog service check. -type ServiceCheck struct { - // Name of the service check. Required. - Name string - // Status of service check. Required. - Status ServiceCheckStatus - // Timestamp is a timestamp for the serviceCheck. If not provided, the dogstatsd - // server will set this to the current time. - Timestamp time.Time - // Hostname for the serviceCheck. - Hostname string - // A message describing the current state of the serviceCheck. - Message string - // Tags for the serviceCheck. - Tags []string -} - -// NewServiceCheck creates a new serviceCheck with the given name and status. Error checking -// against these values is done at send-time, or upon running sc.Check. -func NewServiceCheck(name string, status ServiceCheckStatus) *ServiceCheck { - return &ServiceCheck{ - Name: name, - Status: status, - } -} - -// Check verifies that a service check is valid. -func (sc *ServiceCheck) Check() error { - if len(sc.Name) == 0 { - return fmt.Errorf("statsd.ServiceCheck name is required") - } - if byte(sc.Status) < 0 || byte(sc.Status) > 3 { - return fmt.Errorf("statsd.ServiceCheck status has invalid value") - } - return nil -} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/statsd.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/statsd.go deleted file mode 100644 index 33792a53..00000000 --- a/vendor/github.com/DataDog/datadog-go/v5/statsd/statsd.go +++ /dev/null @@ -1,919 +0,0 @@ -// Copyright 2013 Ooyala, Inc. - -/* -Package statsd provides a Go dogstatsd client. Dogstatsd extends the popular statsd, -adding tags and histograms and pushing upstream to Datadog. - -Refer to http://docs.datadoghq.com/guides/dogstatsd/ for information about DogStatsD. - -statsd is based on go-statsd-client. -*/ -package statsd - -//go:generate mockgen -source=statsd.go -destination=mocks/statsd.go - -import ( - "errors" - "fmt" - "io" - "net/url" - "os" - "strconv" - "strings" - "sync" - "sync/atomic" - "time" -) - -/* -OptimalUDPPayloadSize defines the optimal payload size for a UDP datagram, 1432 bytes -is optimal for regular networks with an MTU of 1500 so datagrams don't get -fragmented. It's generally recommended not to fragment UDP datagrams as losing -a single fragment will cause the entire datagram to be lost. -*/ -const OptimalUDPPayloadSize = 1432 - -/* -MaxUDPPayloadSize defines the maximum payload size for a UDP datagram. -Its value comes from the calculation: 65535 bytes Max UDP datagram size - -8byte UDP header - 60byte max IP headers -any number greater than that will see frames being cut out. -*/ -const MaxUDPPayloadSize = 65467 - -// DefaultUDPBufferPoolSize is the default size of the buffer pool for UDP clients. -const DefaultUDPBufferPoolSize = 2048 - -// DefaultUDSBufferPoolSize is the default size of the buffer pool for UDS clients. -const DefaultUDSBufferPoolSize = 512 - -/* -DefaultMaxAgentPayloadSize is the default maximum payload size the agent -can receive. This can be adjusted by changing dogstatsd_buffer_size in the -agent configuration file datadog.yaml. This is also used as the optimal payload size -for UDS datagrams. -*/ -const DefaultMaxAgentPayloadSize = 8192 - -/* -UnixAddressPrefix holds the prefix to use to enable Unix Domain Socket -traffic instead of UDP. The type of the socket will be guessed. -*/ -const UnixAddressPrefix = "unix://" - -/* -UnixDatagramAddressPrefix holds the prefix to use to enable Unix Domain Socket -datagram traffic instead of UDP. -*/ -const UnixAddressDatagramPrefix = "unixgram://" - -/* -UnixAddressStreamPrefix holds the prefix to use to enable Unix Domain Socket -stream traffic instead of UDP. -*/ -const UnixAddressStreamPrefix = "unixstream://" - -/* -WindowsPipeAddressPrefix holds the prefix to use to enable Windows Named Pipes -traffic instead of UDP. -*/ -const WindowsPipeAddressPrefix = `\\.\pipe\` - -var ( - AddressPrefixes = []string{UnixAddressPrefix, UnixAddressDatagramPrefix, UnixAddressStreamPrefix, WindowsPipeAddressPrefix} -) - -const ( - agentHostEnvVarName = "DD_AGENT_HOST" - agentPortEnvVarName = "DD_DOGSTATSD_PORT" - agentURLEnvVarName = "DD_DOGSTATSD_URL" - defaultUDPPort = "8125" -) - -const ( - // ddEntityID specifies client-side user-specified entity ID injection. - // This env var can be set to the Pod UID on Kubernetes via the downward API. - // Docs: https://docs.datadoghq.com/developers/dogstatsd/?tab=kubernetes#origin-detection-over-udp - ddEntityID = "DD_ENTITY_ID" - - // ddEntityIDTag specifies the tag name for the client-side entity ID injection - // The Agent expects this tag to contain a non-prefixed Kubernetes Pod UID. - ddEntityIDTag = "dd.internal.entity_id" - - // originDetectionEnabled specifies the env var to enable/disable sending the container ID field. - originDetectionEnabled = "DD_ORIGIN_DETECTION_ENABLED" -) - -/* -ddEnvTagsMapping is a mapping of each "DD_" prefixed environment variable -to a specific tag name. We use a slice to keep the order and simplify tests. -*/ -var ddEnvTagsMapping = []struct{ envName, tagName string }{ - {ddEntityID, ddEntityIDTag}, // Client-side entity ID injection for container tagging. - {"DD_ENV", "env"}, // The name of the env in which the service runs. - {"DD_SERVICE", "service"}, // The name of the running service. - {"DD_VERSION", "version"}, // The current version of the running service. -} - -type metricType int - -const ( - gauge metricType = iota - count - histogram - histogramAggregated - distribution - distributionAggregated - set - timing - timingAggregated - event - serviceCheck -) - -type receivingMode int - -const ( - mutexMode receivingMode = iota - channelMode -) - -const ( - writerNameUDP string = "udp" - writerNameUDS string = "uds" - writerNameUDSStream string = "uds-stream" - writerWindowsPipe string = "pipe" - writerNameCustom string = "custom" -) - -// noTimestamp is used as a value for metric without a given timestamp. -const noTimestamp = int64(0) - -type metric struct { - metricType metricType - namespace string - globalTags []string - name string - fvalue float64 - fvalues []float64 - ivalue int64 - svalue string - evalue *Event - scvalue *ServiceCheck - tags []string - stags string - rate float64 - timestamp int64 -} - -type noClientErr string - -// ErrNoClient is returned if statsd reporting methods are invoked on -// a nil client. -const ErrNoClient = noClientErr("statsd client is nil") - -func (e noClientErr) Error() string { - return string(e) -} - -type invalidTimestampErr string - -// InvalidTimestamp is returned if a provided timestamp is invalid. -const InvalidTimestamp = invalidTimestampErr("invalid timestamp") - -func (e invalidTimestampErr) Error() string { - return string(e) -} - -// ClientInterface is an interface that exposes the common client functions for the -// purpose of being able to provide a no-op client or even mocking. This can aid -// downstream users' with their testing. -type ClientInterface interface { - // Gauge measures the value of a metric at a particular time. - Gauge(name string, value float64, tags []string, rate float64) error - - // GaugeWithTimestamp measures the value of a metric at a given time. - // BETA - Please contact our support team for more information to use this feature: https://www.datadoghq.com/support/ - // The value will bypass any aggregation on the client side and agent side, this is - // useful when sending points in the past. - // - // Minimum Datadog Agent version: 7.40.0 - GaugeWithTimestamp(name string, value float64, tags []string, rate float64, timestamp time.Time) error - - // Count tracks how many times something happened per second. - Count(name string, value int64, tags []string, rate float64) error - - // CountWithTimestamp tracks how many times something happened at the given second. - // BETA - Please contact our support team for more information to use this feature: https://www.datadoghq.com/support/ - // The value will bypass any aggregation on the client side and agent side, this is - // useful when sending points in the past. - // - // Minimum Datadog Agent version: 7.40.0 - CountWithTimestamp(name string, value int64, tags []string, rate float64, timestamp time.Time) error - - // Histogram tracks the statistical distribution of a set of values on each host. - Histogram(name string, value float64, tags []string, rate float64) error - - // Distribution tracks the statistical distribution of a set of values across your infrastructure. - // - // It is recommended to use `WithMaxBufferedMetricsPerContext` to avoid dropping metrics at high throughput, `rate` can - // also be used to limit the load. Both options can *not* be used together. - Distribution(name string, value float64, tags []string, rate float64) error - - // Decr is just Count of -1 - Decr(name string, tags []string, rate float64) error - - // Incr is just Count of 1 - Incr(name string, tags []string, rate float64) error - - // Set counts the number of unique elements in a group. - Set(name string, value string, tags []string, rate float64) error - - // Timing sends timing information, it is an alias for TimeInMilliseconds - Timing(name string, value time.Duration, tags []string, rate float64) error - - // TimeInMilliseconds sends timing information in milliseconds. - // It is flushed by statsd with percentiles, mean and other info (https://github.com/etsy/statsd/blob/master/docs/metric_types.md#timing) - TimeInMilliseconds(name string, value float64, tags []string, rate float64) error - - // Event sends the provided Event. - Event(e *Event) error - - // SimpleEvent sends an event with the provided title and text. - SimpleEvent(title, text string) error - - // ServiceCheck sends the provided ServiceCheck. - ServiceCheck(sc *ServiceCheck) error - - // SimpleServiceCheck sends an serviceCheck with the provided name and status. - SimpleServiceCheck(name string, status ServiceCheckStatus) error - - // Close the client connection. - Close() error - - // Flush forces a flush of all the queued dogstatsd payloads. - Flush() error - - // IsClosed returns if the client has been closed. - IsClosed() bool - - // GetTelemetry return the telemetry metrics for the client since it started. - GetTelemetry() Telemetry -} - -type ErrorHandler func(error) - -// A Client is a handle for sending messages to dogstatsd. It is safe to -// use one Client from multiple goroutines simultaneously. -type Client struct { - // Sender handles the underlying networking protocol - sender *sender - // namespace to prepend to all statsd calls - namespace string - // tags are global tags to be added to every statsd call - tags []string - flushTime time.Duration - telemetry *statsdTelemetry - telemetryClient *telemetryClient - stop chan struct{} - wg sync.WaitGroup - workers []*worker - closerLock sync.Mutex - workersMode receivingMode - aggregatorMode receivingMode - agg *aggregator - aggExtended *aggregator - options []Option - addrOption string - isClosed bool - errorOnBlockedChannel bool - errorHandler ErrorHandler -} - -// statsdTelemetry contains telemetry metrics about the client -type statsdTelemetry struct { - totalMetricsGauge uint64 - totalMetricsCount uint64 - totalMetricsHistogram uint64 - totalMetricsDistribution uint64 - totalMetricsSet uint64 - totalMetricsTiming uint64 - totalEvents uint64 - totalServiceChecks uint64 - totalDroppedOnReceive uint64 -} - -// Verify that Client implements the ClientInterface. -// https://golang.org/doc/faq#guarantee_satisfies_interface -var _ ClientInterface = &Client{} - -func resolveAddr(addr string) string { - envPort := "" - - if addr == "" { - addr = os.Getenv(agentHostEnvVarName) - envPort = os.Getenv(agentPortEnvVarName) - agentURL, _ := os.LookupEnv(agentURLEnvVarName) - agentURL = parseAgentURL(agentURL) - - // agentURLEnvVarName has priority over agentHostEnvVarName - if agentURL != "" { - return agentURL - } - } - - if addr == "" { - return "" - } - - for _, prefix := range AddressPrefixes { - if strings.HasPrefix(addr, prefix) { - return addr - } - } - // TODO: How does this work for IPv6? - if strings.Contains(addr, ":") { - return addr - } - if envPort != "" { - addr = fmt.Sprintf("%s:%s", addr, envPort) - } else { - addr = fmt.Sprintf("%s:%s", addr, defaultUDPPort) - } - return addr -} - -func parseAgentURL(agentURL string) string { - if agentURL != "" { - if strings.HasPrefix(agentURL, WindowsPipeAddressPrefix) { - return agentURL - } - - parsedURL, err := url.Parse(agentURL) - if err != nil { - return "" - } - - if parsedURL.Scheme == "udp" { - if strings.Contains(parsedURL.Host, ":") { - return parsedURL.Host - } - return fmt.Sprintf("%s:%s", parsedURL.Host, defaultUDPPort) - } - - if parsedURL.Scheme == "unix" { - return agentURL - } - } - return "" -} - -func createWriter(addr string, writeTimeout time.Duration, connectTimeout time.Duration) (Transport, string, error) { - addr = resolveAddr(addr) - if addr == "" { - return nil, "", errors.New("No address passed and autodetection from environment failed") - } - - switch { - case strings.HasPrefix(addr, WindowsPipeAddressPrefix): - w, err := newWindowsPipeWriter(addr, writeTimeout) - return w, writerWindowsPipe, err - case strings.HasPrefix(addr, UnixAddressPrefix): - w, err := newUDSWriter(addr[len(UnixAddressPrefix):], writeTimeout, connectTimeout, "") - return w, writerNameUDS, err - case strings.HasPrefix(addr, UnixAddressDatagramPrefix): - w, err := newUDSWriter(addr[len(UnixAddressDatagramPrefix):], writeTimeout, connectTimeout, "unixgram") - return w, writerNameUDS, err - case strings.HasPrefix(addr, UnixAddressStreamPrefix): - w, err := newUDSWriter(addr[len(UnixAddressStreamPrefix):], writeTimeout, connectTimeout, "unix") - return w, writerNameUDS, err - default: - w, err := newUDPWriter(addr, writeTimeout) - return w, writerNameUDP, err - } -} - -// New returns a pointer to a new Client given an addr in the format "hostname:port" for UDP, -// "unix:///path/to/socket" for UDS or "\\.\pipe\path\to\pipe" for Windows Named Pipes. -func New(addr string, options ...Option) (*Client, error) { - o, err := resolveOptions(options) - if err != nil { - return nil, err - } - - w, writerType, err := createWriter(addr, o.writeTimeout, o.connectTimeout) - if err != nil { - return nil, err - } - - client, err := newWithWriter(w, o, writerType) - if err == nil { - client.options = append(client.options, options...) - client.addrOption = addr - } - return client, err -} - -type customWriter struct { - io.WriteCloser -} - -func (w *customWriter) GetTransportName() string { - return writerNameCustom -} - -// NewWithWriter creates a new Client with given writer. Writer is a -// io.WriteCloser -func NewWithWriter(w io.WriteCloser, options ...Option) (*Client, error) { - o, err := resolveOptions(options) - if err != nil { - return nil, err - } - return newWithWriter(&customWriter{w}, o, writerNameCustom) -} - -// CloneWithExtraOptions create a new Client with extra options -func CloneWithExtraOptions(c *Client, options ...Option) (*Client, error) { - if c == nil { - return nil, ErrNoClient - } - - if c.addrOption == "" { - return nil, fmt.Errorf("can't clone client with no addrOption") - } - opt := append(c.options, options...) - return New(c.addrOption, opt...) -} - -func newWithWriter(w Transport, o *Options, writerName string) (*Client, error) { - c := Client{ - namespace: o.namespace, - tags: o.tags, - telemetry: &statsdTelemetry{}, - errorOnBlockedChannel: o.channelModeErrorsWhenFull, - errorHandler: o.errorHandler, - } - - hasEntityID := false - // Inject values of DD_* environment variables as global tags. - for _, mapping := range ddEnvTagsMapping { - if value := os.Getenv(mapping.envName); value != "" { - if mapping.envName == ddEntityID { - hasEntityID = true - } - c.tags = append(c.tags, fmt.Sprintf("%s:%s", mapping.tagName, value)) - } - } - - if !hasEntityID { - initContainerID(o.containerID, isOriginDetectionEnabled(o, hasEntityID)) - } - - isUDS := writerName == writerNameUDS - - if o.maxBytesPerPayload == 0 { - if isUDS { - o.maxBytesPerPayload = DefaultMaxAgentPayloadSize - } else { - o.maxBytesPerPayload = OptimalUDPPayloadSize - } - } - if o.bufferPoolSize == 0 { - if isUDS { - o.bufferPoolSize = DefaultUDSBufferPoolSize - } else { - o.bufferPoolSize = DefaultUDPBufferPoolSize - } - } - if o.senderQueueSize == 0 { - if isUDS { - o.senderQueueSize = DefaultUDSBufferPoolSize - } else { - o.senderQueueSize = DefaultUDPBufferPoolSize - } - } - - bufferPool := newBufferPool(o.bufferPoolSize, o.maxBytesPerPayload, o.maxMessagesPerPayload) - c.sender = newSender(w, o.senderQueueSize, bufferPool, o.errorHandler) - c.aggregatorMode = o.receiveMode - - c.workersMode = o.receiveMode - // channelMode mode at the worker level is not enabled when - // ExtendedAggregation is since the user app will not directly - // use the worker (the aggregator sit between the app and the - // workers). - if o.extendedAggregation { - c.workersMode = mutexMode - } - - if o.aggregation || o.extendedAggregation || o.maxBufferedSamplesPerContext > 0 { - c.agg = newAggregator(&c, int64(o.maxBufferedSamplesPerContext)) - c.agg.start(o.aggregationFlushInterval) - - if o.extendedAggregation { - c.aggExtended = c.agg - - if c.aggregatorMode == channelMode { - c.agg.startReceivingMetric(o.channelModeBufferSize, o.workersCount) - } - } - } - - for i := 0; i < o.workersCount; i++ { - w := newWorker(bufferPool, c.sender) - c.workers = append(c.workers, w) - - if c.workersMode == channelMode { - w.startReceivingMetric(o.channelModeBufferSize) - } - } - - c.flushTime = o.bufferFlushInterval - c.stop = make(chan struct{}, 1) - - c.wg.Add(1) - go func() { - defer c.wg.Done() - c.watch() - }() - - if o.telemetry { - if o.telemetryAddr == "" { - c.telemetryClient = newTelemetryClient(&c, c.agg != nil) - } else { - var err error - c.telemetryClient, err = newTelemetryClientWithCustomAddr(&c, o.telemetryAddr, c.agg != nil, bufferPool, o.writeTimeout, o.connectTimeout) - if err != nil { - return nil, err - } - } - c.telemetryClient.run(&c.wg, c.stop) - } - - return &c, nil -} - -func (c *Client) watch() { - ticker := time.NewTicker(c.flushTime) - - for { - select { - case <-ticker.C: - for _, w := range c.workers { - w.flush() - } - case <-c.stop: - ticker.Stop() - return - } - } -} - -// Flush forces a flush of all the queued dogstatsd payloads This method is -// blocking and will not return until everything is sent through the network. -// In mutexMode, this will also block sampling new data to the client while the -// workers and sender are flushed. -func (c *Client) Flush() error { - if c == nil { - return ErrNoClient - } - if c.agg != nil { - c.agg.flush() - } - for _, w := range c.workers { - w.pause() - defer w.unpause() - w.flushUnsafe() - } - // Now that the worker are pause the sender can flush the queue between - // worker and senders - c.sender.flush() - return nil -} - -// IsClosed returns if the client has been closed. -func (c *Client) IsClosed() bool { - c.closerLock.Lock() - defer c.closerLock.Unlock() - return c.isClosed -} - -func (c *Client) flushTelemetryMetrics(t *Telemetry) { - t.TotalMetricsGauge = atomic.LoadUint64(&c.telemetry.totalMetricsGauge) - t.TotalMetricsCount = atomic.LoadUint64(&c.telemetry.totalMetricsCount) - t.TotalMetricsSet = atomic.LoadUint64(&c.telemetry.totalMetricsSet) - t.TotalMetricsHistogram = atomic.LoadUint64(&c.telemetry.totalMetricsHistogram) - t.TotalMetricsDistribution = atomic.LoadUint64(&c.telemetry.totalMetricsDistribution) - t.TotalMetricsTiming = atomic.LoadUint64(&c.telemetry.totalMetricsTiming) - t.TotalEvents = atomic.LoadUint64(&c.telemetry.totalEvents) - t.TotalServiceChecks = atomic.LoadUint64(&c.telemetry.totalServiceChecks) - t.TotalDroppedOnReceive = atomic.LoadUint64(&c.telemetry.totalDroppedOnReceive) -} - -// GetTelemetry return the telemetry metrics for the client since it started. -func (c *Client) GetTelemetry() Telemetry { - return c.telemetryClient.getTelemetry() -} - -// GetTransport return the name of the transport used. -func (c *Client) GetTransport() string { - if c.sender == nil { - return "" - } - return c.sender.getTransportName() -} - -type ErrorInputChannelFull struct { - Metric metric - ChannelSize int - Msg string -} - -func (e ErrorInputChannelFull) Error() string { - return e.Msg -} - -func (c *Client) send(m metric) error { - h := hashString32(m.name) - worker := c.workers[h%uint32(len(c.workers))] - - if c.workersMode == channelMode { - select { - case worker.inputMetrics <- m: - default: - atomic.AddUint64(&c.telemetry.totalDroppedOnReceive, 1) - err := &ErrorInputChannelFull{m, len(worker.inputMetrics), "Worker input channel full"} - if c.errorHandler != nil { - c.errorHandler(err) - } - if c.errorOnBlockedChannel { - return err - } - } - return nil - } - return worker.processMetric(m) -} - -// sendBlocking is used by the aggregator to inject aggregated metrics. -func (c *Client) sendBlocking(m metric) error { - m.globalTags = c.tags - m.namespace = c.namespace - - h := hashString32(m.name) - worker := c.workers[h%uint32(len(c.workers))] - return worker.processMetric(m) -} - -func (c *Client) sendToAggregator(mType metricType, name string, value float64, tags []string, rate float64, f bufferedMetricSampleFunc) error { - if c.aggregatorMode == channelMode { - m := metric{metricType: mType, name: name, fvalue: value, tags: tags, rate: rate} - select { - case c.aggExtended.inputMetrics <- m: - default: - atomic.AddUint64(&c.telemetry.totalDroppedOnReceive, 1) - err := &ErrorInputChannelFull{m, len(c.aggExtended.inputMetrics), "Aggregator input channel full"} - if c.errorHandler != nil { - c.errorHandler(err) - } - if c.errorOnBlockedChannel { - return err - } - } - return nil - } - return f(name, value, tags, rate) -} - -// Gauge measures the value of a metric at a particular time. -func (c *Client) Gauge(name string, value float64, tags []string, rate float64) error { - if c == nil { - return ErrNoClient - } - atomic.AddUint64(&c.telemetry.totalMetricsGauge, 1) - if c.agg != nil { - return c.agg.gauge(name, value, tags) - } - return c.send(metric{metricType: gauge, name: name, fvalue: value, tags: tags, rate: rate, globalTags: c.tags, namespace: c.namespace}) -} - -// GaugeWithTimestamp measures the value of a metric at a given time. -// BETA - Please contact our support team for more information to use this feature: https://www.datadoghq.com/support/ -// The value will bypass any aggregation on the client side and agent side, this is -// useful when sending points in the past. -// -// Minimum Datadog Agent version: 7.40.0 -func (c *Client) GaugeWithTimestamp(name string, value float64, tags []string, rate float64, timestamp time.Time) error { - if c == nil { - return ErrNoClient - } - - if timestamp.IsZero() || timestamp.Unix() <= noTimestamp { - return InvalidTimestamp - } - - atomic.AddUint64(&c.telemetry.totalMetricsGauge, 1) - return c.send(metric{metricType: gauge, name: name, fvalue: value, tags: tags, rate: rate, globalTags: c.tags, namespace: c.namespace, timestamp: timestamp.Unix()}) -} - -// Count tracks how many times something happened per second. -func (c *Client) Count(name string, value int64, tags []string, rate float64) error { - if c == nil { - return ErrNoClient - } - atomic.AddUint64(&c.telemetry.totalMetricsCount, 1) - if c.agg != nil { - return c.agg.count(name, value, tags) - } - return c.send(metric{metricType: count, name: name, ivalue: value, tags: tags, rate: rate, globalTags: c.tags, namespace: c.namespace}) -} - -// CountWithTimestamp tracks how many times something happened at the given second. -// BETA - Please contact our support team for more information to use this feature: https://www.datadoghq.com/support/ -// The value will bypass any aggregation on the client side and agent side, this is -// useful when sending points in the past. -// -// Minimum Datadog Agent version: 7.40.0 -func (c *Client) CountWithTimestamp(name string, value int64, tags []string, rate float64, timestamp time.Time) error { - if c == nil { - return ErrNoClient - } - - if timestamp.IsZero() || timestamp.Unix() <= noTimestamp { - return InvalidTimestamp - } - - atomic.AddUint64(&c.telemetry.totalMetricsCount, 1) - return c.send(metric{metricType: count, name: name, ivalue: value, tags: tags, rate: rate, globalTags: c.tags, namespace: c.namespace, timestamp: timestamp.Unix()}) -} - -// Histogram tracks the statistical distribution of a set of values on each host. -func (c *Client) Histogram(name string, value float64, tags []string, rate float64) error { - if c == nil { - return ErrNoClient - } - atomic.AddUint64(&c.telemetry.totalMetricsHistogram, 1) - if c.aggExtended != nil { - return c.sendToAggregator(histogram, name, value, tags, rate, c.aggExtended.histogram) - } - return c.send(metric{metricType: histogram, name: name, fvalue: value, tags: tags, rate: rate, globalTags: c.tags, namespace: c.namespace}) -} - -// Distribution tracks the statistical distribution of a set of values across your infrastructure. -func (c *Client) Distribution(name string, value float64, tags []string, rate float64) error { - if c == nil { - return ErrNoClient - } - atomic.AddUint64(&c.telemetry.totalMetricsDistribution, 1) - if c.aggExtended != nil { - return c.sendToAggregator(distribution, name, value, tags, rate, c.aggExtended.distribution) - } - return c.send(metric{metricType: distribution, name: name, fvalue: value, tags: tags, rate: rate, globalTags: c.tags, namespace: c.namespace}) -} - -// Decr is just Count of -1 -func (c *Client) Decr(name string, tags []string, rate float64) error { - return c.Count(name, -1, tags, rate) -} - -// Incr is just Count of 1 -func (c *Client) Incr(name string, tags []string, rate float64) error { - return c.Count(name, 1, tags, rate) -} - -// Set counts the number of unique elements in a group. -func (c *Client) Set(name string, value string, tags []string, rate float64) error { - if c == nil { - return ErrNoClient - } - atomic.AddUint64(&c.telemetry.totalMetricsSet, 1) - if c.agg != nil { - return c.agg.set(name, value, tags) - } - return c.send(metric{metricType: set, name: name, svalue: value, tags: tags, rate: rate, globalTags: c.tags, namespace: c.namespace}) -} - -// Timing sends timing information, it is an alias for TimeInMilliseconds -func (c *Client) Timing(name string, value time.Duration, tags []string, rate float64) error { - return c.TimeInMilliseconds(name, value.Seconds()*1000, tags, rate) -} - -// TimeInMilliseconds sends timing information in milliseconds. -// It is flushed by statsd with percentiles, mean and other info (https://github.com/etsy/statsd/blob/master/docs/metric_types.md#timing) -func (c *Client) TimeInMilliseconds(name string, value float64, tags []string, rate float64) error { - if c == nil { - return ErrNoClient - } - atomic.AddUint64(&c.telemetry.totalMetricsTiming, 1) - if c.aggExtended != nil { - return c.sendToAggregator(timing, name, value, tags, rate, c.aggExtended.timing) - } - return c.send(metric{metricType: timing, name: name, fvalue: value, tags: tags, rate: rate, globalTags: c.tags, namespace: c.namespace}) -} - -// Event sends the provided Event. -func (c *Client) Event(e *Event) error { - if c == nil { - return ErrNoClient - } - atomic.AddUint64(&c.telemetry.totalEvents, 1) - return c.send(metric{metricType: event, evalue: e, rate: 1, globalTags: c.tags, namespace: c.namespace}) -} - -// SimpleEvent sends an event with the provided title and text. -func (c *Client) SimpleEvent(title, text string) error { - e := NewEvent(title, text) - return c.Event(e) -} - -// ServiceCheck sends the provided ServiceCheck. -func (c *Client) ServiceCheck(sc *ServiceCheck) error { - if c == nil { - return ErrNoClient - } - atomic.AddUint64(&c.telemetry.totalServiceChecks, 1) - return c.send(metric{metricType: serviceCheck, scvalue: sc, rate: 1, globalTags: c.tags, namespace: c.namespace}) -} - -// SimpleServiceCheck sends an serviceCheck with the provided name and status. -func (c *Client) SimpleServiceCheck(name string, status ServiceCheckStatus) error { - sc := NewServiceCheck(name, status) - return c.ServiceCheck(sc) -} - -// Close the client connection. -func (c *Client) Close() error { - if c == nil { - return ErrNoClient - } - - // Acquire closer lock to ensure only one thread can close the stop channel - c.closerLock.Lock() - defer c.closerLock.Unlock() - - if c.isClosed { - return nil - } - - // Notify all other threads that they should stop - select { - case <-c.stop: - return nil - default: - } - close(c.stop) - - if c.workersMode == channelMode { - for _, w := range c.workers { - w.stopReceivingMetric() - } - } - - // flush the aggregator first - if c.agg != nil { - if c.aggExtended != nil && c.aggregatorMode == channelMode { - c.agg.stopReceivingMetric() - } - c.agg.stop() - } - - // Wait for the threads to stop - c.wg.Wait() - - c.Flush() - - c.isClosed = true - return c.sender.close() -} - -// isOriginDetectionEnabled returns whether the clients should fill the container field. -// -// If DD_ENTITY_ID is set, we don't send the container ID -// If a user-defined container ID is provided, we don't ignore origin detection -// as dd.internal.entity_id is prioritized over the container field for backward compatibility. -// If DD_ENTITY_ID is not set, we try to fill the container field automatically unless -// DD_ORIGIN_DETECTION_ENABLED is explicitly set to false. -func isOriginDetectionEnabled(o *Options, hasEntityID bool) bool { - if !o.originDetection || hasEntityID || o.containerID != "" { - // originDetection is explicitly disabled - // or DD_ENTITY_ID was found - // or a user-defined container ID was provided - return false - } - - envVarValue := os.Getenv(originDetectionEnabled) - if envVarValue == "" { - // DD_ORIGIN_DETECTION_ENABLED is not set - // default to true - return true - } - - enabled, err := strconv.ParseBool(envVarValue) - if err != nil { - // Error due to an unsupported DD_ORIGIN_DETECTION_ENABLED value - // default to true - return true - } - - return enabled -} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/statsd_direct.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/statsd_direct.go deleted file mode 100644 index af66517c..00000000 --- a/vendor/github.com/DataDog/datadog-go/v5/statsd/statsd_direct.go +++ /dev/null @@ -1,69 +0,0 @@ -package statsd - -import ( - "io" - "strings" - "sync/atomic" -) - -type ClientDirectInterface interface { - DistributionSamples(name string, values []float64, tags []string, rate float64) error -} - -// ClientDirect is an *experimental* statsd client that gives direct access to some dogstatsd features. -// -// It is not recommended to use this client in production. This client might allow you to take advantage of -// new features in the agent before they are released, but it might also break your application. -type ClientDirect struct { - *Client -} - -// NewDirect returns a pointer to a new ClientDirect given an addr in the format "hostname:port" for UDP, -// "unix:///path/to/socket" for UDS or "\\.\pipe\path\to\pipe" for Windows Named Pipes. -func NewDirect(addr string, options ...Option) (*ClientDirect, error) { - client, err := New(addr, options...) - if err != nil { - return nil, err - } - return &ClientDirect{ - client, - }, nil -} - -func NewDirectWithWriter(writer io.WriteCloser, options ...Option) (*ClientDirect, error) { - client, err := NewWithWriter(writer, options...) - if err != nil { - return nil, err - } - return &ClientDirect{ - client, - }, nil -} - -// DistributionSamples is similar to Distribution, but it lets the client deals with the sampling. -// -// The provided `rate` is the sampling rate applied by the client and will *not* be used to apply further -// sampling. This is recommended in high performance cases were the overhead of the statsd library might be -// significant and the sampling is already done by the client. -// -// `WithMaxBufferedMetricsPerContext` is ignored when using this method. -func (c *ClientDirect) DistributionSamples(name string, values []float64, tags []string, rate float64) error { - if c == nil { - return ErrNoClient - } - atomic.AddUint64(&c.telemetry.totalMetricsDistribution, uint64(len(values))) - return c.send(metric{ - metricType: distributionAggregated, - name: name, - fvalues: values, - tags: tags, - stags: strings.Join(tags, tagSeparatorSymbol), - rate: rate, - globalTags: c.tags, - namespace: c.namespace, - }) -} - -// Validate that ClientDirect implements ClientDirectInterface and ClientInterface. -var _ ClientDirectInterface = (*ClientDirect)(nil) -var _ ClientInterface = (*ClientDirect)(nil) diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/telemetry.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/telemetry.go deleted file mode 100644 index 61025c37..00000000 --- a/vendor/github.com/DataDog/datadog-go/v5/statsd/telemetry.go +++ /dev/null @@ -1,306 +0,0 @@ -package statsd - -import ( - "fmt" - "sync" - "time" -) - -/* -telemetryInterval is the interval at which telemetry will be sent by the client. -*/ -const telemetryInterval = 10 * time.Second - -/* -clientTelemetryTag is a tag identifying this specific client. -*/ -var clientTelemetryTag = "client:go" - -/* -clientVersionTelemetryTag is a tag identifying this specific client version. -*/ -var clientVersionTelemetryTag = "client_version:5.4.0" - -// Telemetry represents internal metrics about the client behavior since it started. -type Telemetry struct { - // - // Those are produced by the 'Client' - // - - // TotalMetrics is the total number of metrics sent by the client before aggregation and sampling. - TotalMetrics uint64 - // TotalMetricsGauge is the total number of gauges sent by the client before aggregation and sampling. - TotalMetricsGauge uint64 - // TotalMetricsCount is the total number of counts sent by the client before aggregation and sampling. - TotalMetricsCount uint64 - // TotalMetricsHistogram is the total number of histograms sent by the client before aggregation and sampling. - TotalMetricsHistogram uint64 - // TotalMetricsDistribution is the total number of distributions sent by the client before aggregation and - // sampling. - TotalMetricsDistribution uint64 - // TotalMetricsSet is the total number of sets sent by the client before aggregation and sampling. - TotalMetricsSet uint64 - // TotalMetricsTiming is the total number of timings sent by the client before aggregation and sampling. - TotalMetricsTiming uint64 - // TotalEvents is the total number of events sent by the client before aggregation and sampling. - TotalEvents uint64 - // TotalServiceChecks is the total number of service_checks sent by the client before aggregation and sampling. - TotalServiceChecks uint64 - - // TotalDroppedOnReceive is the total number metrics/event/service_checks dropped when using ChannelMode (see - // WithChannelMode option). - TotalDroppedOnReceive uint64 - - // - // Those are produced by the 'sender' - // - - // TotalPayloadsSent is the total number of payload (packet on the network) succesfully sent by the client. When - // using UDP we don't know if packet dropped or not, so all packet are considered as succesfully sent. - TotalPayloadsSent uint64 - // TotalPayloadsDropped is the total number of payload dropped by the client. This includes all cause of dropped - // (TotalPayloadsDroppedQueueFull and TotalPayloadsDroppedWriter). When using UDP This won't includes the - // network dropped. - TotalPayloadsDropped uint64 - // TotalPayloadsDroppedWriter is the total number of payload dropped by the writer (when using UDS or named - // pipe) due to network timeout or error. - TotalPayloadsDroppedWriter uint64 - // TotalPayloadsDroppedQueueFull is the total number of payload dropped internally because the queue of payloads - // waiting to be sent on the wire is full. This means the client is generating more metrics than can be sent on - // the wire. If your app sends metrics in batch look at WithSenderQueueSize option to increase the queue size. - TotalPayloadsDroppedQueueFull uint64 - - // TotalBytesSent is the total number of bytes succesfully sent by the client. When using UDP we don't know if - // packet dropped or not, so all packet are considered as succesfully sent. - TotalBytesSent uint64 - // TotalBytesDropped is the total number of bytes dropped by the client. This includes all cause of dropped - // (TotalBytesDroppedQueueFull and TotalBytesDroppedWriter). When using UDP This - // won't includes the network dropped. - TotalBytesDropped uint64 - // TotalBytesDroppedWriter is the total number of bytes dropped by the writer (when using UDS or named pipe) due - // to network timeout or error. - TotalBytesDroppedWriter uint64 - // TotalBytesDroppedQueueFull is the total number of bytes dropped internally because the queue of payloads - // waiting to be sent on the wire is full. This means the client is generating more metrics than can be sent on - // the wire. If your app sends metrics in batch look at WithSenderQueueSize option to increase the queue size. - TotalBytesDroppedQueueFull uint64 - - // - // Those are produced by the 'aggregator' - // - - // AggregationNbContext is the total number of contexts flushed by the aggregator when either - // WithClientSideAggregation or WithExtendedClientSideAggregation options are enabled. - AggregationNbContext uint64 - // AggregationNbContextGauge is the total number of contexts for gauges flushed by the aggregator when either - // WithClientSideAggregation or WithExtendedClientSideAggregation options are enabled. - AggregationNbContextGauge uint64 - // AggregationNbContextCount is the total number of contexts for counts flushed by the aggregator when either - // WithClientSideAggregation or WithExtendedClientSideAggregation options are enabled. - AggregationNbContextCount uint64 - // AggregationNbContextSet is the total number of contexts for sets flushed by the aggregator when either - // WithClientSideAggregation or WithExtendedClientSideAggregation options are enabled. - AggregationNbContextSet uint64 - // AggregationNbContextHistogram is the total number of contexts for histograms flushed by the aggregator when either - // WithClientSideAggregation or WithExtendedClientSideAggregation options are enabled. - AggregationNbContextHistogram uint64 - // AggregationNbContextDistribution is the total number of contexts for distributions flushed by the aggregator when either - // WithClientSideAggregation or WithExtendedClientSideAggregation options are enabled. - AggregationNbContextDistribution uint64 - // AggregationNbContextTiming is the total number of contexts for timings flushed by the aggregator when either - // WithClientSideAggregation or WithExtendedClientSideAggregation options are enabled. - AggregationNbContextTiming uint64 -} - -type telemetryClient struct { - sync.RWMutex // used mostly to change the transport tag. - - c *Client - aggEnabled bool // is aggregation enabled and should we sent aggregation telemetry. - transport string - tags []string - tagsByType map[metricType][]string - transportTagKnown bool - sender *sender - worker *worker - lastSample Telemetry // The previous sample of telemetry sent -} - -func newTelemetryClient(c *Client, aggregationEnabled bool) *telemetryClient { - t := &telemetryClient{ - c: c, - aggEnabled: aggregationEnabled, - tags: []string{}, - tagsByType: map[metricType][]string{}, - } - - t.setTags() - return t -} - -func newTelemetryClientWithCustomAddr(c *Client, telemetryAddr string, aggregationEnabled bool, pool *bufferPool, - writeTimeout time.Duration, connectTimeout time.Duration, -) (*telemetryClient, error) { - telemetryWriter, _, err := createWriter(telemetryAddr, writeTimeout, connectTimeout) - if err != nil { - return nil, fmt.Errorf("Could not resolve telemetry address: %v", err) - } - - t := newTelemetryClient(c, aggregationEnabled) - - // Creating a custom sender/worker with 1 worker in mutex mode for the - // telemetry that share the same bufferPool. - // FIXME due to performance pitfall, we're always using UDP defaults - // even for UDS. - t.sender = newSender(telemetryWriter, DefaultUDPBufferPoolSize, pool, c.errorHandler) - t.worker = newWorker(pool, t.sender) - return t, nil -} - -func (t *telemetryClient) run(wg *sync.WaitGroup, stop chan struct{}) { - wg.Add(1) - go func() { - defer wg.Done() - ticker := time.NewTicker(telemetryInterval) - for { - select { - case <-ticker.C: - t.sendTelemetry() - case <-stop: - ticker.Stop() - if t.sender != nil { - t.sender.close() - } - return - } - } - }() -} - -func (t *telemetryClient) sendTelemetry() { - for _, m := range t.flush() { - if t.worker != nil { - t.worker.processMetric(m) - } else { - t.c.send(m) - } - } - - if t.worker != nil { - t.worker.flush() - } -} - -func (t *telemetryClient) getTelemetry() Telemetry { - if t == nil { - // telemetry was disabled through the WithoutTelemetry option - return Telemetry{} - } - - tlm := Telemetry{} - t.c.flushTelemetryMetrics(&tlm) - t.c.sender.flushTelemetryMetrics(&tlm) - t.c.agg.flushTelemetryMetrics(&tlm) - - tlm.TotalMetrics = tlm.TotalMetricsGauge + - tlm.TotalMetricsCount + - tlm.TotalMetricsSet + - tlm.TotalMetricsHistogram + - tlm.TotalMetricsDistribution + - tlm.TotalMetricsTiming - - tlm.TotalPayloadsDropped = tlm.TotalPayloadsDroppedQueueFull + tlm.TotalPayloadsDroppedWriter - tlm.TotalBytesDropped = tlm.TotalBytesDroppedQueueFull + tlm.TotalBytesDroppedWriter - - if t.aggEnabled { - tlm.AggregationNbContext = tlm.AggregationNbContextGauge + - tlm.AggregationNbContextCount + - tlm.AggregationNbContextSet + - tlm.AggregationNbContextHistogram + - tlm.AggregationNbContextDistribution + - tlm.AggregationNbContextTiming - } - return tlm -} - -// setTransportTag if it was never set and is now known. -func (t *telemetryClient) setTags() { - transport := t.c.GetTransport() - t.RLock() - // We need to refresh if we never set the tags or if the transport changed. - // For example when `unix://` is used we might return `uds` until we actually connect and detect that - // this is a UDS Stream socket and then return `uds-stream`. - needsRefresh := len(t.tags) == len(t.c.tags) || t.transport != transport - t.RUnlock() - - if !needsRefresh { - return - } - - t.Lock() - defer t.Unlock() - - t.transport = transport - t.tags = append(t.c.tags, clientTelemetryTag, clientVersionTelemetryTag) - if transport != "" { - t.tags = append(t.tags, "client_transport:"+transport) - } - t.tagsByType[gauge] = append(append([]string{}, t.tags...), "metrics_type:gauge") - t.tagsByType[count] = append(append([]string{}, t.tags...), "metrics_type:count") - t.tagsByType[set] = append(append([]string{}, t.tags...), "metrics_type:set") - t.tagsByType[timing] = append(append([]string{}, t.tags...), "metrics_type:timing") - t.tagsByType[histogram] = append(append([]string{}, t.tags...), "metrics_type:histogram") - t.tagsByType[distribution] = append(append([]string{}, t.tags...), "metrics_type:distribution") -} - -// flushTelemetry returns Telemetry metrics to be flushed. It's its own function to ease testing. -func (t *telemetryClient) flush() []metric { - m := []metric{} - - // same as Count but without global namespace - telemetryCount := func(name string, value int64, tags []string) { - m = append(m, metric{metricType: count, name: name, ivalue: value, tags: tags, rate: 1}) - } - - tlm := t.getTelemetry() - t.setTags() - - // We send the diff between now and the previous telemetry flush. This keep the same telemetry behavior from V4 - // so users dashboard's aren't broken when upgrading to V5. It also allow to graph on the same dashboard a mix - // of V4 and V5 apps. - telemetryCount("datadog.dogstatsd.client.metrics", int64(tlm.TotalMetrics-t.lastSample.TotalMetrics), t.tags) - telemetryCount("datadog.dogstatsd.client.metrics_by_type", int64(tlm.TotalMetricsGauge-t.lastSample.TotalMetricsGauge), t.tagsByType[gauge]) - telemetryCount("datadog.dogstatsd.client.metrics_by_type", int64(tlm.TotalMetricsCount-t.lastSample.TotalMetricsCount), t.tagsByType[count]) - telemetryCount("datadog.dogstatsd.client.metrics_by_type", int64(tlm.TotalMetricsHistogram-t.lastSample.TotalMetricsHistogram), t.tagsByType[histogram]) - telemetryCount("datadog.dogstatsd.client.metrics_by_type", int64(tlm.TotalMetricsDistribution-t.lastSample.TotalMetricsDistribution), t.tagsByType[distribution]) - telemetryCount("datadog.dogstatsd.client.metrics_by_type", int64(tlm.TotalMetricsSet-t.lastSample.TotalMetricsSet), t.tagsByType[set]) - telemetryCount("datadog.dogstatsd.client.metrics_by_type", int64(tlm.TotalMetricsTiming-t.lastSample.TotalMetricsTiming), t.tagsByType[timing]) - telemetryCount("datadog.dogstatsd.client.events", int64(tlm.TotalEvents-t.lastSample.TotalEvents), t.tags) - telemetryCount("datadog.dogstatsd.client.service_checks", int64(tlm.TotalServiceChecks-t.lastSample.TotalServiceChecks), t.tags) - - telemetryCount("datadog.dogstatsd.client.metric_dropped_on_receive", int64(tlm.TotalDroppedOnReceive-t.lastSample.TotalDroppedOnReceive), t.tags) - - telemetryCount("datadog.dogstatsd.client.packets_sent", int64(tlm.TotalPayloadsSent-t.lastSample.TotalPayloadsSent), t.tags) - telemetryCount("datadog.dogstatsd.client.packets_dropped", int64(tlm.TotalPayloadsDropped-t.lastSample.TotalPayloadsDropped), t.tags) - telemetryCount("datadog.dogstatsd.client.packets_dropped_queue", int64(tlm.TotalPayloadsDroppedQueueFull-t.lastSample.TotalPayloadsDroppedQueueFull), t.tags) - telemetryCount("datadog.dogstatsd.client.packets_dropped_writer", int64(tlm.TotalPayloadsDroppedWriter-t.lastSample.TotalPayloadsDroppedWriter), t.tags) - - telemetryCount("datadog.dogstatsd.client.bytes_dropped", int64(tlm.TotalBytesDropped-t.lastSample.TotalBytesDropped), t.tags) - telemetryCount("datadog.dogstatsd.client.bytes_sent", int64(tlm.TotalBytesSent-t.lastSample.TotalBytesSent), t.tags) - telemetryCount("datadog.dogstatsd.client.bytes_dropped_queue", int64(tlm.TotalBytesDroppedQueueFull-t.lastSample.TotalBytesDroppedQueueFull), t.tags) - telemetryCount("datadog.dogstatsd.client.bytes_dropped_writer", int64(tlm.TotalBytesDroppedWriter-t.lastSample.TotalBytesDroppedWriter), t.tags) - - if t.aggEnabled { - telemetryCount("datadog.dogstatsd.client.aggregated_context", int64(tlm.AggregationNbContext-t.lastSample.AggregationNbContext), t.tags) - telemetryCount("datadog.dogstatsd.client.aggregated_context_by_type", int64(tlm.AggregationNbContextGauge-t.lastSample.AggregationNbContextGauge), t.tagsByType[gauge]) - telemetryCount("datadog.dogstatsd.client.aggregated_context_by_type", int64(tlm.AggregationNbContextSet-t.lastSample.AggregationNbContextSet), t.tagsByType[set]) - telemetryCount("datadog.dogstatsd.client.aggregated_context_by_type", int64(tlm.AggregationNbContextCount-t.lastSample.AggregationNbContextCount), t.tagsByType[count]) - telemetryCount("datadog.dogstatsd.client.aggregated_context_by_type", int64(tlm.AggregationNbContextHistogram-t.lastSample.AggregationNbContextHistogram), t.tagsByType[histogram]) - telemetryCount("datadog.dogstatsd.client.aggregated_context_by_type", int64(tlm.AggregationNbContextDistribution-t.lastSample.AggregationNbContextDistribution), t.tagsByType[distribution]) - telemetryCount("datadog.dogstatsd.client.aggregated_context_by_type", int64(tlm.AggregationNbContextTiming-t.lastSample.AggregationNbContextTiming), t.tagsByType[timing]) - } - - t.lastSample = tlm - - return m -} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/udp.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/udp.go deleted file mode 100644 index b90f7527..00000000 --- a/vendor/github.com/DataDog/datadog-go/v5/statsd/udp.go +++ /dev/null @@ -1,39 +0,0 @@ -package statsd - -import ( - "net" - "time" -) - -// udpWriter is an internal class wrapping around management of UDP connection -type udpWriter struct { - conn net.Conn -} - -// New returns a pointer to a new udpWriter given an addr in the format "hostname:port". -func newUDPWriter(addr string, _ time.Duration) (*udpWriter, error) { - udpAddr, err := net.ResolveUDPAddr("udp", addr) - if err != nil { - return nil, err - } - conn, err := net.DialUDP("udp", nil, udpAddr) - if err != nil { - return nil, err - } - writer := &udpWriter{conn: conn} - return writer, nil -} - -// Write data to the UDP connection with no error handling -func (w *udpWriter) Write(data []byte) (int, error) { - return w.conn.Write(data) -} - -func (w *udpWriter) Close() error { - return w.conn.Close() -} - -// GetTransportName returns the transport used by the sender -func (w *udpWriter) GetTransportName() string { - return writerNameUDP -} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/uds.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/uds.go deleted file mode 100644 index 09518992..00000000 --- a/vendor/github.com/DataDog/datadog-go/v5/statsd/uds.go +++ /dev/null @@ -1,167 +0,0 @@ -//go:build !windows -// +build !windows - -package statsd - -import ( - "encoding/binary" - "net" - "strings" - "sync" - "time" -) - -// udsWriter is an internal class wrapping around management of UDS connection -type udsWriter struct { - // Address to send metrics to, needed to allow reconnection on error - addr string - // Transport used - transport string - // Established connection object, or nil if not connected yet - conn net.Conn - // write timeout - writeTimeout time.Duration - // connect timeout - connectTimeout time.Duration - sync.RWMutex // used to lock conn / writer can replace it -} - -// newUDSWriter returns a pointer to a new udsWriter given a socket file path as addr. -func newUDSWriter(addr string, writeTimeout time.Duration, connectTimeout time.Duration, transport string) (*udsWriter, error) { - // Defer connection to first Write - writer := &udsWriter{addr: addr, transport: transport, conn: nil, writeTimeout: writeTimeout, connectTimeout: connectTimeout} - return writer, nil -} - -// GetTransportName returns the transport used by the writer -func (w *udsWriter) GetTransportName() string { - w.RLock() - defer w.RUnlock() - - if w.transport == "unix" { - return writerNameUDSStream - } else { - return writerNameUDS - } -} - -func (w *udsWriter) shouldCloseConnection(err error, partialWrite bool) bool { - if err != nil && partialWrite { - // We can't recover from a partial write - return true - } - if err, isNetworkErr := err.(net.Error); err != nil && (!isNetworkErr || !err.Timeout()) { - // Statsd server disconnected, retry connecting at next packet - return true - } - return false -} - -// Write data to the UDS connection with write timeout and minimal error handling: -// create the connection if nil, and destroy it if the statsd server has disconnected -func (w *udsWriter) Write(data []byte) (int, error) { - var n int - partialWrite := false - conn, err := w.ensureConnection() - if err != nil { - return 0, err - } - stream := conn.LocalAddr().Network() == "unix" - - // When using streams the deadline will only make us drop the packet if we can't write it at all, - // once we've started writing we need to finish. - conn.SetWriteDeadline(time.Now().Add(w.writeTimeout)) - - // When using streams, we append the length of the packet to the data - if stream { - bs := []byte{0, 0, 0, 0} - binary.LittleEndian.PutUint32(bs, uint32(len(data))) - _, err = w.conn.Write(bs) - - partialWrite = true - - // W need to be able to finish to write partially written packets once we have started. - // But we will reset the connection if we can't write anything at all for a long time. - w.conn.SetWriteDeadline(time.Now().Add(w.connectTimeout)) - - // Continue writing only if we've written the length of the packet - if err == nil { - n, err = w.conn.Write(data) - if err == nil { - partialWrite = false - } - } - } else { - n, err = w.conn.Write(data) - } - - if w.shouldCloseConnection(err, partialWrite) { - w.unsetConnection() - } - return n, err -} - -func (w *udsWriter) Close() error { - if w.conn != nil { - return w.conn.Close() - } - return nil -} - -func (w *udsWriter) tryToDial(network string) (net.Conn, error) { - udsAddr, err := net.ResolveUnixAddr(network, w.addr) - if err != nil { - return nil, err - } - newConn, err := net.DialTimeout(udsAddr.Network(), udsAddr.String(), w.connectTimeout) - if err != nil { - return nil, err - } - return newConn, nil -} - -func (w *udsWriter) ensureConnection() (net.Conn, error) { - // Check if we've already got a socket we can use - w.RLock() - currentConn := w.conn - w.RUnlock() - - if currentConn != nil { - return currentConn, nil - } - - // Looks like we might need to connect - try again with write locking. - w.Lock() - defer w.Unlock() - if w.conn != nil { - return w.conn, nil - } - - var newConn net.Conn - var err error - - // Try to guess the transport if not specified. - if w.transport == "" { - newConn, err = w.tryToDial("unixgram") - // try to connect with unixgram failed, try again with unix streams. - if err != nil && strings.Contains(err.Error(), "protocol wrong type for socket") { - newConn, err = w.tryToDial("unix") - } - } else { - newConn, err = w.tryToDial(w.transport) - } - - if err != nil { - return nil, err - } - w.conn = newConn - w.transport = newConn.RemoteAddr().Network() - return newConn, nil -} - -func (w *udsWriter) unsetConnection() { - w.Lock() - defer w.Unlock() - _ = w.conn.Close() - w.conn = nil -} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/uds_windows.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/uds_windows.go deleted file mode 100644 index 909f5a0a..00000000 --- a/vendor/github.com/DataDog/datadog-go/v5/statsd/uds_windows.go +++ /dev/null @@ -1,15 +0,0 @@ -//go:build windows -// +build windows - -package statsd - -import ( - "fmt" - "time" -) - -// newUDSWriter is disabled on Windows, SOCK_DGRAM are still unavailable but -// SOCK_STREAM should work once implemented in the agent (https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/) -func newUDSWriter(_ string, _ time.Duration, _ time.Duration, _ string) (Transport, error) { - return nil, fmt.Errorf("Unix socket is not available on Windows") -} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/utils.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/utils.go deleted file mode 100644 index 8c3ac842..00000000 --- a/vendor/github.com/DataDog/datadog-go/v5/statsd/utils.go +++ /dev/null @@ -1,32 +0,0 @@ -package statsd - -import ( - "math/rand" - "sync" -) - -func shouldSample(rate float64, r *rand.Rand, lock *sync.Mutex) bool { - if rate >= 1 { - return true - } - // sources created by rand.NewSource() (ie. w.random) are not thread safe. - // TODO: use defer once the lowest Go version we support is 1.14 (defer - // has an overhead before that). - lock.Lock() - if r.Float64() > rate { - lock.Unlock() - return false - } - lock.Unlock() - return true -} - -func copySlice(src []string) []string { - if src == nil { - return nil - } - - c := make([]string, len(src)) - copy(c, src) - return c -} diff --git a/vendor/github.com/DataDog/datadog-go/v5/statsd/worker.go b/vendor/github.com/DataDog/datadog-go/v5/statsd/worker.go deleted file mode 100644 index 19dccd33..00000000 --- a/vendor/github.com/DataDog/datadog-go/v5/statsd/worker.go +++ /dev/null @@ -1,158 +0,0 @@ -package statsd - -import ( - "math/rand" - "sync" - "time" -) - -type worker struct { - pool *bufferPool - buffer *statsdBuffer - sender *sender - random *rand.Rand - randomLock sync.Mutex - sync.Mutex - - inputMetrics chan metric - stop chan struct{} -} - -func newWorker(pool *bufferPool, sender *sender) *worker { - // Each worker uses its own random source and random lock to prevent - // workers in separate goroutines from contending for the lock on the - // "math/rand" package-global random source (e.g. calls like - // "rand.Float64()" must acquire a shared lock to get the next - // pseudorandom number). - // Note that calling "time.Now().UnixNano()" repeatedly quickly may return - // very similar values. That's fine for seeding the worker-specific random - // source because we just need an evenly distributed stream of float values. - // Do not use this random source for cryptographic randomness. - random := rand.New(rand.NewSource(time.Now().UnixNano())) - return &worker{ - pool: pool, - sender: sender, - buffer: pool.borrowBuffer(), - random: random, - stop: make(chan struct{}), - } -} - -func (w *worker) startReceivingMetric(bufferSize int) { - w.inputMetrics = make(chan metric, bufferSize) - go w.pullMetric() -} - -func (w *worker) stopReceivingMetric() { - w.stop <- struct{}{} -} - -func (w *worker) pullMetric() { - for { - select { - case m := <-w.inputMetrics: - w.processMetric(m) - case <-w.stop: - return - } - } -} - -func (w *worker) processMetric(m metric) error { - // Aggregated metrics are already sampled. - if m.metricType != distributionAggregated && m.metricType != histogramAggregated && m.metricType != timingAggregated { - if !shouldSample(m.rate, w.random, &w.randomLock) { - return nil - } - } - w.Lock() - var err error - if err = w.writeMetricUnsafe(m); err == errBufferFull { - w.flushUnsafe() - err = w.writeMetricUnsafe(m) - } - w.Unlock() - return err -} - -func (w *worker) writeAggregatedMetricUnsafe(m metric, metricSymbol []byte, precision int, rate float64) error { - globalPos := 0 - - // first check how much data we can write to the buffer: - // +3 + len(metricSymbol) because the message will include '||#' before the tags - // +1 for the potential line break at the start of the metric - extraSize := len(m.stags) + 4 + len(metricSymbol) - if m.rate < 1 { - // +2 for "|@" - // + the maximum size of a rate (https://en.wikipedia.org/wiki/IEEE_754-1985) - extraSize += 2 + 18 - } - for _, t := range m.globalTags { - extraSize += len(t) + 1 - } - - for { - pos, err := w.buffer.writeAggregated(metricSymbol, m.namespace, m.globalTags, m.name, m.fvalues[globalPos:], m.stags, extraSize, precision, rate) - if err == errPartialWrite { - // We successfully wrote part of the histogram metrics. - // We flush the current buffer and finish the histogram - // in a new one. - w.flushUnsafe() - globalPos += pos - } else { - return err - } - } -} - -func (w *worker) writeMetricUnsafe(m metric) error { - switch m.metricType { - case gauge: - return w.buffer.writeGauge(m.namespace, m.globalTags, m.name, m.fvalue, m.tags, m.rate, m.timestamp) - case count: - return w.buffer.writeCount(m.namespace, m.globalTags, m.name, m.ivalue, m.tags, m.rate, m.timestamp) - case histogram: - return w.buffer.writeHistogram(m.namespace, m.globalTags, m.name, m.fvalue, m.tags, m.rate) - case distribution: - return w.buffer.writeDistribution(m.namespace, m.globalTags, m.name, m.fvalue, m.tags, m.rate) - case set: - return w.buffer.writeSet(m.namespace, m.globalTags, m.name, m.svalue, m.tags, m.rate) - case timing: - return w.buffer.writeTiming(m.namespace, m.globalTags, m.name, m.fvalue, m.tags, m.rate) - case event: - return w.buffer.writeEvent(m.evalue, m.globalTags) - case serviceCheck: - return w.buffer.writeServiceCheck(m.scvalue, m.globalTags) - case histogramAggregated: - return w.writeAggregatedMetricUnsafe(m, histogramSymbol, -1, m.rate) - case distributionAggregated: - return w.writeAggregatedMetricUnsafe(m, distributionSymbol, -1, m.rate) - case timingAggregated: - return w.writeAggregatedMetricUnsafe(m, timingSymbol, 6, m.rate) - default: - return nil - } -} - -func (w *worker) flush() { - w.Lock() - w.flushUnsafe() - w.Unlock() -} - -func (w *worker) pause() { - w.Lock() -} - -func (w *worker) unpause() { - w.Unlock() -} - -// flush the current buffer. Lock must be held by caller. -// flushed buffer written to the network asynchronously. -func (w *worker) flushUnsafe() { - if len(w.buffer.bytes()) > 0 { - w.sender.send(w.buffer) - w.buffer = w.pool.borrowBuffer() - } -} diff --git a/vendor/github.com/DataDog/go-libddwaf/v3/.gitattributes b/vendor/github.com/DataDog/go-libddwaf/v3/.gitattributes deleted file mode 100644 index 003a8007..00000000 --- a/vendor/github.com/DataDog/go-libddwaf/v3/.gitattributes +++ /dev/null @@ -1,3 +0,0 @@ -*.dylib -diff -*.so -diff -*.a -diff diff --git a/vendor/github.com/DataDog/go-libddwaf/v3/.gitignore b/vendor/github.com/DataDog/go-libddwaf/v3/.gitignore deleted file mode 100644 index e9a06fb7..00000000 --- a/vendor/github.com/DataDog/go-libddwaf/v3/.gitignore +++ /dev/null @@ -1,23 +0,0 @@ -# Binaries for programs and plugins -*.exe -*.exe~ - -# Test binary, built with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out - -# Dependency directories (remove the comment below to include it) -# vendor/ - -.vscode/ -.idea/ - -# Swap files -*.swp - -## Ensure WAF static libraries are not excluded from vendor folders -!internal/lib/*.so.gz -!internal/lib/*.dylib.gz - diff --git a/vendor/github.com/DataDog/go-libddwaf/v3/CODEOWNERS b/vendor/github.com/DataDog/go-libddwaf/v3/CODEOWNERS deleted file mode 100644 index 2e4d479a..00000000 --- a/vendor/github.com/DataDog/go-libddwaf/v3/CODEOWNERS +++ /dev/null @@ -1,2 +0,0 @@ -# default owner -* @DataDog/asm-go diff --git a/vendor/github.com/DataDog/go-libddwaf/v3/LICENSE b/vendor/github.com/DataDog/go-libddwaf/v3/LICENSE deleted file mode 100644 index 9301dd7a..00000000 --- a/vendor/github.com/DataDog/go-libddwaf/v3/LICENSE +++ /dev/null @@ -1,200 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2016-present Datadog, Inc. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/DataDog/go-libddwaf/v3/README.md b/vendor/github.com/DataDog/go-libddwaf/v3/README.md deleted file mode 100644 index 013b663b..00000000 --- a/vendor/github.com/DataDog/go-libddwaf/v3/README.md +++ /dev/null @@ -1,151 +0,0 @@ -# go-libddwaf - -This project's goal is to produce a higher level API for the go bindings to [libddwaf](https://github.com/DataDog/libddwaf): DataDog in-app WAF. -It consists of 2 separate entities: the bindings for the calls to libddwaf, and the encoder which job is to convert _any_ go value to its libddwaf object representation. - -An example usage would be: - -```go -import waf "github.com/DataDog/go-libddwaf/v3" - -//go:embed -var ruleset []byte - -func main() { - var parsedRuleset any - - if err := json.Unmarshal(ruleset, &parsedRuleset); err != nil { - panic(err) - } - - wafHandle, err := waf.NewHandle(parsedRuleset, "", "") - if err != nil { - panic(err) - } - - defer wafHandle.Close() - - wafCtx := wafHandle.NewContext() - defer wafCtx.Close() - - matches, actions := wafCtx.Run(RunAddressData{ - Persistent: map[string]any{ - "server.request.path_params": "/rfiinc.txt", - }, - }) -} -``` - -The API documentation details can be found on [pkg.go.dev](https://pkg.go.dev/github.com/DataDog/go-libddwaf/v3). - -Originally this project was only here to provide CGO Wrappers to the calls to libddwaf. -But with the appearance of `ddwaf_object` tree like structure, -but also with the intention to build CGO-less bindings, this project size has grown to be a fully integrated brick in the DataDog tracer structure. -Which in turn made it necessary to document the project, to maintain it in an orderly fashion. - -## Supported platforms - -This library currently support the following platform doublets: - -| OS | Arch | -| ----- | ------- | -| Linux | amd64 | -| Linux | aarch64 | -| OSX | amd64 | -| OSX | arm64 | - -This means that when the platform is not supported, top-level functions will return a `WafDisabledError` error including the purpose of it. - -Note that: -* Linux support include for glibc and musl variants -* OSX under 10.9 is not supported -* A build tag named `datadog.no_waf` can be manually added to force the WAF to be disabled. - -## Design - -The WAF bindings have multiple moving parts that are necessary to understand: - -- Handle: a object wrapper over the pointer to the C WAF Handle -- Context: a object wrapper over a pointer to the C WAF Context -- Encoder: its goal is to construct a tree of Waf Objects to send to the WAF -- CGORefPool: Does all allocation operations for the construction of Waf Objects and keeps track of the equivalent go pointers -- Decoder: Transforms Waf Objects returned from the WAF to usual go objects (e.g. maps, arrays, ...) -- Library: The low-level go bindings to the C library, providing improved typing - -```mermaid -flowchart LR - - START:::hidden -->|NewHandle| Handle -->|NewContext| Context - - Context -->|Encode Inputs| Encoder - - Handle -->|Encode Ruleset| Encoder - Handle -->|Init WAF| Library - Context -->|Decode Result| Decoder - - Handle -->|Decode Init Errors| Decoder - - Context -->|Run| Library - Context -->|Store Go References| CGORefPool - - Encoder -->|Allocate Waf Objects| TempCGORefPool - - TempCGORefPool -->|Copy after each encoding| CGORefPool - - Library -->|Call C code| libddwaf - - classDef hidden display: none; -``` - -### CGO Reference Pool - -The cgoRefPool type is a pure Go pointer pool of `ddwaf_object` C values on the Go memory heap. -the `cgoRefPool` go type is a way to make sure we can safely send Go allocated data to the C side of the WAF -The main issue is the following: the `WafObject` uses a C union to store the tree structure of the full object, -union equivalent in go are interfaces and they are not compatible with C unions. The only way to be 100% sure -that the Go `WafObject` struct has the same layout as the C one is to only use primitive types. So the only way to -store a raw pointer is to use the `uintptr` type. But since `uintptr` do not have pointer semantics (and are just -basically integers), we need another method to store the value as Go pointer because the GC will delete our data if it -is not referenced by Go pointers. - -That's where the `cgoRefPool` object comes into play: all new `WafObject` elements are created via this API which is especially -built to make sure there is no gap for the Garbage Collector to exploit. From there, since underlying values of the -`wafObject` are either arrays of WafObjects (for maps, structs and arrays) or string (for all ints, booleans and strings), -we can store 2 slices of arrays and use `unsafe.KeepAlive` in each code path to protect them from the GC. - -All these objects stored in the reference pool need to live throughout the use of the associated Waf Context. - -### Typical call to Run() - -Here is an example of the flow of operations on a simple call to Run(): - -- Encode input data into WAF Objects and store references in the temporary pool -- Lock the context mutex until the end of the call -- Store references from the temporary pool into the context level pool -- Call `ddwaf_run` -- Decode the matches and actions - -### CGO-less C Bindings - -This library uses [purego](https://github.com/ebitengine/purego) to implement C bindings without requiring use of CGO at compilation time. The high-level workflow -is to embed the C shared library using `go:embed`, dump it into a file, open the library using `dlopen`, load the -symbols using `dlsym`, and finally call them. On Linux systems, using `memfd_create(2)` enables the library to be loaded without -writing to the filesystem. - -Another requirement of `libddwaf` is to have a FHS filesystem on your machine and, for Linux, to provide `libc.so.6`, -`libpthread.so.0`, and `libdl.so.2` as dynamic libraries. - -> :warning: Keep in mind that **purego only works on linux/darwin for amd64/arm64 and so does go-libddwaf.** - -## Contributing pitfalls - -- Cannot dlopen twice in the app lifetime on OSX. It messes with Thread Local Storage and usually finishes with a `std::bad_alloc()` -- `keepAlive()` calls are here to prevent the GC from destroying objects too early -- Since there is a stack switch between the Go code and the C code, usually the only C stacktrace you will ever get is from GDB -- If a segfault happens during a call to the C code, the goroutine stacktrace which has done the call is the one annotated with `[syscall]` -- [GoLand](https://www.jetbrains.com/go/) does not support `CGO_ENABLED=0` (as of June 2023) -- Keep in mind that we fully escape the type system. If you send the wrong data it will segfault in the best cases but not always! -- The structs in `ctypes.go` are here to reproduce the memory layout of the structs in `include/ddwaf.h` because pointers to these structs will be passed directly -- Do not use `uintptr` as function arguments or results types, coming from `unsafe.Pointer` casts of Go values, because they escape the pointer analysis which can create wrongly optimized code and crash. Pointer arithmetic is of course necessary in such a library but must be kept in the same function scope. -- GDB is available on arm64 but is not officially supported so it usually crashes pretty fast (as of June 2023) -- No pointer to variables on the stack shall be sent to the C code because Go stacks can be moved during the C call. More on this [here](https://medium.com/@trinad536/escape-analysis-in-golang-fc81b78f3550) diff --git a/vendor/github.com/DataDog/go-libddwaf/v3/cgo_ref_pool.go b/vendor/github.com/DataDog/go-libddwaf/v3/cgo_ref_pool.go deleted file mode 100644 index 9de4c2fb..00000000 --- a/vendor/github.com/DataDog/go-libddwaf/v3/cgo_ref_pool.go +++ /dev/null @@ -1,106 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package waf - -import ( - "strconv" - - "github.com/DataDog/go-libddwaf/v3/internal/bindings" - "github.com/DataDog/go-libddwaf/v3/internal/unsafe" -) - -// cgoRefPool is a way to make sure we can safely send go allocated data on the C side of the WAF -// The main issue is the following: the wafObject uses a C union to store the tree structure of the full object, -// union equivalent in go are interfaces and they are not compatible with C unions. The only way to be 100% sure -// that the Go wafObject struct have the same layout as the C one is to only use primitive types. So the only way to -// store a raw pointer is to use the uintptr type. But since uintptr do not have pointer semantics (and are just -// basically integers), we need another structure to store the value as Go pointer because the GC is lurking. That's -// where the cgoRefPool object comes into play: All new wafObject elements are created via this API whose especially -// built to make sure there is no gap for the Garbage Collector to exploit. From there, since underlying values of the -// wafObject are either arrays (for maps, structs and arrays) or string (for all ints, booleans and strings), -// we can store 2 slices of arrays and use runtime.KeepAlive in each code path to protect them from the GC. -type cgoRefPool struct { - stringRefs []string - arrayRefs [][]bindings.WafObject -} - -// This is used when passing empty Go strings to the WAF in order to avoid passing null string pointers, -// which are not handled by the WAF in all cases. -// FIXME: to be removed when the WAF handles null ptr strings in all expected places -var emptyWAFStringValue = unsafe.NativeStringUnwrap("\x00").Data - -func (refPool *cgoRefPool) append(newRefs cgoRefPool) { - refPool.stringRefs = append(refPool.stringRefs, newRefs.stringRefs...) - refPool.arrayRefs = append(refPool.arrayRefs, newRefs.arrayRefs...) -} - -// AllocCString is used in the rare cases where we need the WAF to receive standard null-terminated strings. -// All cases where strings a wrapped in wafObject are handled by AllocWafString -func (refPool *cgoRefPool) AllocCString(str string) uintptr { - if len(str) > 0 && str[len(str)-1] != '\x00' { - str = str + "\x00" - } - - refPool.stringRefs = append(refPool.stringRefs, str) - return unsafe.NativeStringUnwrap(str).Data -} - -// AllocWafString fills the obj parameter wafObject with all parameters needed for the WAF interpret it as a string. -// We take full advantage of the fact that the WAF can receive non-null-terminated strings by directly retrieving the -// underlying array in the string value using the nativeStringUnwrap function. Hence, removing any copy in the process -func (refPool *cgoRefPool) AllocWafString(obj *bindings.WafObject, str string) { - obj.Type = bindings.WafStringType - - if len(str) == 0 { - obj.NbEntries = 0 - // FIXME: use obj.Value = 0 when the WAF handles null string ptr in all expected places - obj.Value = emptyWAFStringValue - return - } - - refPool.stringRefs = append(refPool.stringRefs, str) - stringHeader := unsafe.NativeStringUnwrap(str) - obj.Value = stringHeader.Data - obj.NbEntries = uint64(stringHeader.Len) -} - -// AllocWafArray is used to create a tree-like structure since we allocate a wafObject array inside another wafOject. -// wafObject can also represent a map, in that case we use the AllocWafMapKey function to make the wafObject key-value-pair -// like objects. -func (refPool *cgoRefPool) AllocWafArray(obj *bindings.WafObject, typ bindings.WafObjectType, size uint64) []bindings.WafObject { - if typ != bindings.WafMapType && typ != bindings.WafArrayType { - panic("Cannot allocate this waf object data type as an array: " + strconv.Itoa(int(typ))) - } - - obj.Type = typ - obj.NbEntries = size - - // If the array size is zero no need to allocate anything - if size == 0 { - obj.Value = 0 - return nil - } - - goArray := make([]bindings.WafObject, size) - refPool.arrayRefs = append(refPool.arrayRefs, goArray) - - obj.Value = unsafe.SliceToUintptr(goArray) - return goArray -} - -// AllocWafMapKey is used to store a string map key in a wafObject. -// We take full advantage of the fact that the WAF can receive non-null-terminated strings by directly retrieving the -// underlying array in the string value using the nativeStringUnwrap function. Hence, removing any copy in the process -func (refPool *cgoRefPool) AllocWafMapKey(obj *bindings.WafObject, str string) { - if len(str) == 0 { - return - } - - refPool.stringRefs = append(refPool.stringRefs, str) - stringHeader := unsafe.NativeStringUnwrap(str) - obj.ParameterName = stringHeader.Data - obj.ParameterNameLength = uint64(stringHeader.Len) -} diff --git a/vendor/github.com/DataDog/go-libddwaf/v3/context.go b/vendor/github.com/DataDog/go-libddwaf/v3/context.go deleted file mode 100644 index 509f7f0c..00000000 --- a/vendor/github.com/DataDog/go-libddwaf/v3/context.go +++ /dev/null @@ -1,327 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package waf - -import ( - "sync" - "sync/atomic" - "time" - - "github.com/DataDog/go-libddwaf/v3/errors" - "github.com/DataDog/go-libddwaf/v3/internal/bindings" - "github.com/DataDog/go-libddwaf/v3/internal/unsafe" - "github.com/DataDog/go-libddwaf/v3/timer" -) - -// Context is a WAF execution context. It allows running the WAF incrementally -// when calling it multiple times to run its rules every time new addresses -// become available. Each request must have its own Context. -type Context struct { - handle *Handle // Instance of the WAF - - cgoRefs cgoRefPool // Used to retain go data referenced by WAF Objects the context holds - cContext bindings.WafContext // The C ddwaf_context pointer - - // timeoutCount count all calls which have timeout'ed by scope. Keys are fixed at creation time. - timeoutCount map[Scope]*atomic.Uint64 - - // mutex protecting the use of cContext which is not thread-safe and cgoRefs. - mutex sync.Mutex - - // timer registers the time spent in the WAF and go-libddwaf - timer timer.NodeTimer - - // metrics stores the cumulative time spent in various parts of the WAF - metrics metricsStore - - // truncations provides details about truncations that occurred while - // encoding address data for WAF execution. - truncations map[Scope]map[TruncationReason][]int -} - -// RunAddressData provides address data to the Context.Run method. If a given key is present in both -// RunAddressData.Persistent and RunAddressData.Ephemeral, the value from RunAddressData.Persistent will take precedence. -type RunAddressData struct { - // Persistent address data is scoped to the lifetime of a given Context, and subsquent calls to Context.Run with the - // same address name will be silently ignored. - Persistent map[string]any - // Ephemeral address data is scoped to a given Context.Run call and is not persisted across calls. This is used for - // protocols such as gRPC client/server streaming or GraphQL, where a single request can incur multiple subrequests. - Ephemeral map[string]any - // Scope is the way to classify the different runs in the same context in order to have different metrics - Scope Scope -} - -func (d RunAddressData) isEmpty() bool { - return len(d.Persistent) == 0 && len(d.Ephemeral) == 0 -} - -// Run encodes the given addressData values and runs them against the WAF rules within the given timeout value. If a -// given address is present both as persistent and ephemeral, the persistent value takes precedence. It returns the -// matches as a JSON string (usually opaquely used) along with the corresponding actions in any. In case of an error, -// matches and actions can still be returned, for instance in the case of a timeout error. Errors can be tested against -// the RunError type. -// Struct fields having the tag `ddwaf:"ignore"` will not be encoded and sent to the WAF -// if the output of TotalTime() exceeds the value of Timeout, the function will immediately return with errors.ErrTimeout -// The second parameter is deprecated and should be passed to NewContextWithBudget instead. -func (context *Context) Run(addressData RunAddressData) (res Result, err error) { - if addressData.isEmpty() { - return - } - - if addressData.Scope == "" { - addressData.Scope = DefaultScope - } - - defer func() { - if err == errors.ErrTimeout { - context.timeoutCount[addressData.Scope].Add(1) - } - }() - - // If the context has already timed out, we don't need to run the WAF again - if context.timer.SumExhausted() { - return Result{}, errors.ErrTimeout - } - - runTimer, err := context.timer.NewNode(wafRunTag, - timer.WithComponents( - wafEncodeTag, - wafDecodeTag, - wafDurationTag, - ), - ) - if err != nil { - return Result{}, err - } - - runTimer.Start() - defer func() { - context.metrics.add(addressData.Scope, wafRunTag, runTimer.Stop()) - context.metrics.merge(addressData.Scope, runTimer.Stats()) - }() - - wafEncodeTimer := runTimer.MustLeaf(wafEncodeTag) - wafEncodeTimer.Start() - persistentData, persistentEncoder, err := context.encodeOneAddressType(addressData.Scope, addressData.Persistent, wafEncodeTimer) - if err != nil { - wafEncodeTimer.Stop() - return res, err - } - - // The WAF releases ephemeral address data at the max of each run call, so we need not keep the Go values live beyond - // that in the same way we need for persistent data. We hence use a separate encoder. - ephemeralData, ephemeralEncoder, err := context.encodeOneAddressType(addressData.Scope, addressData.Ephemeral, wafEncodeTimer) - if err != nil { - wafEncodeTimer.Stop() - return res, err - } - - wafEncodeTimer.Stop() - - // ddwaf_run cannot run concurrently and we are going to mutate the context.cgoRefs, so we need to lock the context - context.mutex.Lock() - defer context.mutex.Unlock() - - if runTimer.SumExhausted() { - return res, errors.ErrTimeout - } - - // Save the Go pointer references to addressesToData that were referenced by the encoder - // into C ddwaf_objects. libddwaf's API requires to keep this data for the lifetime of the ddwaf_context. - defer context.cgoRefs.append(persistentEncoder.cgoRefs) - - wafDecodeTimer := runTimer.MustLeaf(wafDecodeTag) - res, err = context.run(persistentData, ephemeralData, wafDecodeTimer, runTimer.SumRemaining()) - - runTimer.AddTime(wafDurationTag, res.TimeSpent) - - // Ensure the ephemerals don't get optimized away by the compiler before the WAF had a chance to use them. - unsafe.KeepAlive(ephemeralEncoder.cgoRefs) - unsafe.KeepAlive(persistentEncoder.cgoRefs) - - return -} - -// merge merges two maps of slices into a single map of slices. The resulting map will contain all -// keys from both a and b, with the corresponding value from a and b concatenated (in this order) in -// a single slice. The implementation tries to minimize reallocations. -func merge[K comparable, V any](a, b map[K][]V) (merged map[K][]V) { - count := len(a) + len(b) - if count == 0 { - return - } - - keys := make(map[K]struct{}, count) - nothing := struct{}{} - totalCount := 0 - for _, m := range [2]map[K][]V{a, b} { - for k, v := range m { - keys[k] = nothing - totalCount += len(v) - } - } - - merged = make(map[K][]V, count) - values := make([]V, 0, totalCount) - - for k := range keys { - idxS := len(values) // Start index - values = append(values, a[k]...) - values = append(values, b[k]...) - idxE := len(values) // End index - - merged[k] = values[idxS:idxE] - } - - return -} - -// encodeOneAddressType encodes the given addressData values and returns the corresponding WAF object and its refs. -// If the addressData is empty, it returns nil for the WAF object and an empty ref pool. -// At this point, if the encoder does not timeout, the only error we can get is an error in case the top level object -// is a nil map, but this behaviour is expected since either persistent or ephemeral addresses are allowed to be null -// one at a time. In this case, Encode will return nil contrary to Encode which will return a nil wafObject, -// which is what we need to send to ddwaf_run to signal that the address data is empty. -func (context *Context) encodeOneAddressType(scope Scope, addressData map[string]any, timer timer.Timer) (*bindings.WafObject, encoder, error) { - encoder := newLimitedEncoder(timer) - if addressData == nil { - return nil, encoder, nil - } - - data, _ := encoder.Encode(addressData) - if len(encoder.truncations) > 0 { - context.mutex.Lock() - defer context.mutex.Unlock() - - context.truncations[scope] = merge(context.truncations[scope], encoder.truncations) - } - - if timer.Exhausted() { - return nil, encoder, errors.ErrTimeout - } - - return data, encoder, nil -} - -// run executes the ddwaf_run call with the provided data on this context. The caller is responsible for locking the -// context appropriately around this call. -func (context *Context) run(persistentData, ephemeralData *bindings.WafObject, wafDecodeTimer timer.Timer, timeBudget time.Duration) (Result, error) { - result := new(bindings.WafResult) - defer wafLib.WafResultFree(result) - - // The value of the timeout cannot exceed 2^55 - // cf. https://en.cppreference.com/w/cpp/chrono/duration - timeout := uint64(timeBudget.Microseconds()) & 0x008FFFFFFFFFFFFF - ret := wafLib.WafRun(context.cContext, persistentData, ephemeralData, result, timeout) - - wafDecodeTimer.Start() - defer wafDecodeTimer.Stop() - - return unwrapWafResult(ret, result) -} - -func unwrapWafResult(ret bindings.WafReturnCode, result *bindings.WafResult) (res Result, err error) { - if result.Timeout > 0 { - err = errors.ErrTimeout - } else { - // Derivatives can be generated even if no security event gets detected, so we decode them as long as the WAF - // didn't timeout - res.Derivatives, err = decodeMap(&result.Derivatives) - } - - res.TimeSpent = time.Duration(result.TotalRuntime) * time.Nanosecond - - if ret == bindings.WafOK { - return res, err - } - - if ret != bindings.WafMatch { - return res, goRunError(ret) - } - - res.Events, err = decodeArray(&result.Events) - if err != nil { - return res, err - } - if size := result.Actions.NbEntries; size > 0 { - res.Actions, err = decodeMap(&result.Actions) - if err != nil { - return res, err - } - } - - return res, err -} - -// Close the underlying `ddwaf_context` and releases the associated internal -// data. Also decreases the reference count of the `ddwaf_hadnle` which created -// this context, possibly releasing it completely (if this was the last context -// created from this handle & it was released by its creator). -func (context *Context) Close() { - context.mutex.Lock() - defer context.mutex.Unlock() - - wafLib.WafContextDestroy(context.cContext) - unsafe.KeepAlive(context.cgoRefs) // Keep the Go pointer references until the max of the context - defer context.handle.release() // Reduce the reference counter of the Handle. - - context.cgoRefs = cgoRefPool{} // The data in context.cgoRefs is no longer needed, explicitly release - context.cContext = 0 // Makes it easy to spot use-after-free/double-free issues -} - -// TotalRuntime returns the cumulated WAF runtime across various run calls within the same WAF context. -// Returned time is in nanoseconds. -// Deprecated: use Stats instead -func (context *Context) TotalRuntime() (uint64, uint64) { - return uint64(context.metrics.get(DefaultScope, wafRunTag)), uint64(context.metrics.get(DefaultScope, wafDurationTag)) -} - -// TotalTimeouts returns the cumulated amount of WAF timeouts across various run calls within the same WAF context. -// Deprecated: use Stats instead -func (context *Context) TotalTimeouts() uint64 { - return context.timeoutCount[DefaultScope].Load() -} - -// Stats returns the cumulative time spent in various parts of the WAF, all in nanoseconds -// and the timeout value used -func (context *Context) Stats() Stats { - context.mutex.Lock() - defer context.mutex.Unlock() - - truncations := make(map[TruncationReason][]int, len(context.truncations[DefaultScope])) - for reason, counts := range context.truncations[DefaultScope] { - truncations[reason] = make([]int, len(counts)) - copy(truncations[reason], counts) - } - - raspTruncations := make(map[TruncationReason][]int, len(context.truncations[RASPScope])) - for reason, counts := range context.truncations[RASPScope] { - raspTruncations[reason] = make([]int, len(counts)) - copy(raspTruncations[reason], counts) - } - - var ( - timeoutDefault uint64 - timeoutRASP uint64 - ) - - if atomic, ok := context.timeoutCount[DefaultScope]; ok { - timeoutDefault = atomic.Load() - } - - if atomic, ok := context.timeoutCount[RASPScope]; ok { - timeoutRASP = atomic.Load() - } - - return Stats{ - Timers: context.metrics.timers(), - TimeoutCount: timeoutDefault, - TimeoutRASPCount: timeoutRASP, - Truncations: truncations, - TruncationsRASP: raspTruncations, - } -} diff --git a/vendor/github.com/DataDog/go-libddwaf/v3/decoder.go b/vendor/github.com/DataDog/go-libddwaf/v3/decoder.go deleted file mode 100644 index 330412c1..00000000 --- a/vendor/github.com/DataDog/go-libddwaf/v3/decoder.go +++ /dev/null @@ -1,253 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package waf - -import ( - "github.com/DataDog/go-libddwaf/v3/errors" - "github.com/DataDog/go-libddwaf/v3/internal/bindings" - "github.com/DataDog/go-libddwaf/v3/internal/unsafe" -) - -// decodeErrors transforms the wafObject received by the wafRulesetInfo after the call to wafDl.wafInit to a map where -// keys are the error message and the value is a array of all the rule ids which triggered this specific error -func decodeErrors(obj *bindings.WafObject) (map[string][]string, error) { - if !obj.IsMap() { - return nil, errors.ErrInvalidObjectType - } - - if obj.Value == 0 && obj.NbEntries > 0 { - return nil, errors.ErrNilObjectPtr - } - - wafErrors := map[string][]string{} - for i := uint64(0); i < obj.NbEntries; i++ { - objElem := unsafe.CastWithOffset[bindings.WafObject](obj.Value, i) - - errorMessage := unsafe.GostringSized(unsafe.Cast[byte](objElem.ParameterName), objElem.ParameterNameLength) - ruleIds, err := decodeStringArray(objElem) - if err != nil { - return nil, err - } - - wafErrors[errorMessage] = ruleIds - } - - return wafErrors, nil -} - -func decodeDiagnostics(obj *bindings.WafObject) (Diagnostics, error) { - if !obj.IsMap() { - return Diagnostics{}, errors.ErrInvalidObjectType - } - if obj.Value == 0 && obj.NbEntries > 0 { - return Diagnostics{}, errors.ErrNilObjectPtr - } - - var ( - diags Diagnostics - err error - ) - for i := uint64(0); i < obj.NbEntries; i++ { - objElem := unsafe.CastWithOffset[bindings.WafObject](obj.Value, i) - key := unsafe.GostringSized(unsafe.Cast[byte](objElem.ParameterName), objElem.ParameterNameLength) - switch key { - case "actions": - diags.Actions, err = decodeDiagnosticsEntry(objElem) - case "custom_rules": - diags.CustomRules, err = decodeDiagnosticsEntry(objElem) - case "exclusions": - diags.Exclusions, err = decodeDiagnosticsEntry(objElem) - case "rules": - diags.Rules, err = decodeDiagnosticsEntry(objElem) - case "rules_data": - diags.RulesData, err = decodeDiagnosticsEntry(objElem) - case "exclusion_data": - diags.RulesData, err = decodeDiagnosticsEntry(objElem) - case "rules_override": - diags.RulesOverrides, err = decodeDiagnosticsEntry(objElem) - case "processors": - diags.Processors, err = decodeDiagnosticsEntry(objElem) - case "scanners": - diags.Scanners, err = decodeDiagnosticsEntry(objElem) - case "ruleset_version": - diags.Version = unsafe.GostringSized(unsafe.Cast[byte](objElem.Value), objElem.NbEntries) - default: - // ignore? - } - if err != nil { - return Diagnostics{}, err - } - } - - return diags, nil -} - -func decodeDiagnosticsEntry(obj *bindings.WafObject) (*DiagnosticEntry, error) { - if !obj.IsMap() { - return nil, errors.ErrInvalidObjectType - } - if obj.Value == 0 && obj.NbEntries > 0 { - return nil, errors.ErrNilObjectPtr - } - var entry DiagnosticEntry - var err error - - for i := uint64(0); i < obj.NbEntries; i++ { - objElem := unsafe.CastWithOffset[bindings.WafObject](obj.Value, i) - key := unsafe.GostringSized(unsafe.Cast[byte](objElem.ParameterName), objElem.ParameterNameLength) - switch key { - case "addresses": - entry.Addresses, err = decodeDiagnosticAddresses(objElem) - case "error": - entry.Error = unsafe.GostringSized(unsafe.Cast[byte](objElem.Value), objElem.NbEntries) - case "errors": - entry.Errors, err = decodeErrors(objElem) - case "failed": - entry.Failed, err = decodeStringArray(objElem) - case "loaded": - entry.Loaded, err = decodeStringArray(objElem) - case "skipped": - entry.Skipped, err = decodeStringArray(objElem) - default: - return nil, errors.ErrUnsupportedValue - } - - if err != nil { - return nil, err - } - } - - return &entry, nil -} - -func decodeDiagnosticAddresses(obj *bindings.WafObject) (*DiagnosticAddresses, error) { - if !obj.IsMap() { - return nil, errors.ErrInvalidObjectType - } - if obj.Value == 0 && obj.NbEntries > 0 { - return nil, errors.ErrNilObjectPtr - } - - addrs := &DiagnosticAddresses{} - - var err error - for i := uint64(0); i < obj.NbEntries; i++ { - objElem := unsafe.CastWithOffset[bindings.WafObject](obj.Value, i) - key := unsafe.GostringSized(unsafe.Cast[byte](objElem.ParameterName), objElem.ParameterNameLength) - switch key { - case "required": - addrs.Required, err = decodeStringArray(objElem) - if err != nil { - return nil, err - } - case "optional": - addrs.Optional, err = decodeStringArray(objElem) - if err != nil { - return nil, err - } - default: - return nil, errors.ErrUnsupportedValue - } - } - - return addrs, nil -} - -func decodeStringArray(obj *bindings.WafObject) ([]string, error) { - // We consider that nil is an empty array - if obj.IsNil() { - return nil, nil - } - - if !obj.IsArray() { - return nil, errors.ErrInvalidObjectType - } - - if obj.Value == 0 && obj.NbEntries > 0 { - return nil, errors.ErrNilObjectPtr - } - - var strArr []string - for i := uint64(0); i < obj.NbEntries; i++ { - objElem := unsafe.CastWithOffset[bindings.WafObject](obj.Value, i) - if objElem.Type != bindings.WafStringType { - return nil, errors.ErrInvalidObjectType - } - - strArr = append(strArr, unsafe.GostringSized(unsafe.Cast[byte](objElem.Value), objElem.NbEntries)) - } - - return strArr, nil -} - -func decodeObject(obj *bindings.WafObject) (any, error) { - switch obj.Type { - case bindings.WafMapType: - return decodeMap(obj) - case bindings.WafArrayType: - return decodeArray(obj) - case bindings.WafStringType: - return unsafe.GostringSized(unsafe.Cast[byte](obj.Value), obj.NbEntries), nil - case bindings.WafIntType: - return int64(obj.Value), nil - case bindings.WafUintType: - return uint64(obj.Value), nil - case bindings.WafFloatType: - return unsafe.UintptrToNative[float64](obj.Value), nil - case bindings.WafBoolType: - return unsafe.UintptrToNative[bool](obj.Value), nil - case bindings.WafNilType: - return nil, nil - default: - return nil, errors.ErrUnsupportedValue - } -} - -func decodeArray(obj *bindings.WafObject) ([]any, error) { - if obj.IsNil() { - return nil, nil - } - - if !obj.IsArray() { - return nil, errors.ErrInvalidObjectType - } - - events := make([]any, obj.NbEntries) - - for i := uint64(0); i < obj.NbEntries; i++ { - objElem := unsafe.CastWithOffset[bindings.WafObject](obj.Value, i) - val, err := decodeObject(objElem) - if err != nil { - return nil, err - } - events[i] = val - } - - return events, nil -} - -func decodeMap(obj *bindings.WafObject) (map[string]any, error) { - if obj.IsNil() { - return nil, nil - } - - if !obj.IsMap() { - return nil, errors.ErrInvalidObjectType - } - - result := make(map[string]any, obj.NbEntries) - for i := uint64(0); i < obj.NbEntries; i++ { - objElem := unsafe.CastWithOffset[bindings.WafObject](obj.Value, i) - key := unsafe.GostringSized(unsafe.Cast[byte](objElem.ParameterName), objElem.ParameterNameLength) - val, err := decodeObject(objElem) - if err != nil { - return nil, err - } - result[key] = val - } - - return result, nil -} diff --git a/vendor/github.com/DataDog/go-libddwaf/v3/encoder.go b/vendor/github.com/DataDog/go-libddwaf/v3/encoder.go deleted file mode 100644 index dcf6b488..00000000 --- a/vendor/github.com/DataDog/go-libddwaf/v3/encoder.go +++ /dev/null @@ -1,507 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package waf - -import ( - "context" - "fmt" - "math" - "reflect" - "strings" - "time" - "unicode" - - "github.com/DataDog/go-libddwaf/v3/errors" - "github.com/DataDog/go-libddwaf/v3/internal/bindings" - "github.com/DataDog/go-libddwaf/v3/internal/unsafe" - "github.com/DataDog/go-libddwaf/v3/timer" -) - -// Encode Go values into wafObjects. Only the subset of Go types representable into wafObjects -// will be encoded while ignoring the rest of it. -// The encoder allocates the memory required for new wafObjects into the Go memory, which must be kept -// referenced for their lifetime in the C world. This lifetime depends on the ddwaf function being used with. -// the encoded result. The Go references of the allocated wafObjects, along with every Go pointer they may -// reference now or in the future, are stored and referenced in the `cgoRefs` field. The user MUST leverage -// `keepAlive()` with it according to its ddwaf use-case. -type encoder struct { - // timer makes sure the encoder doesn't spend too much time doing its job. - timer timer.Timer - - // For each TruncationReason, holds the size that is required to avoid truncation for each truncation that happened. - truncations map[TruncationReason][]int - - cgoRefs cgoRefPool - containerMaxSize int - stringMaxSize int - objectMaxDepth int -} - -// TruncationReason is a flag representing reasons why some input was not encoded in full. -type TruncationReason uint8 - -const ( - // StringTooLong indicates a string exceeded the maximum string length configured. The truncation - // values indicate the actual length of truncated strings. - StringTooLong TruncationReason = 1 << iota - // ContainerTooLarge indicates a container (list, map, struct) exceeded the maximum number of - // elements configured. The truncation values indicate the actual number of elements in the - // truncated container. - ContainerTooLarge - // ObjectTooDeep indicates an overall object exceeded the maximum encoding depths configured. The - // truncation values indicate an estimated actual depth of the truncated object. The value is - // guaranteed to be less than or equal to the actual depth (it may not be more). - ObjectTooDeep -) - -func (reason TruncationReason) String() string { - switch reason { - case ObjectTooDeep: - return "depth" - case ContainerTooLarge: - return "container-size" - case StringTooLong: - return "string-size" - default: - return fmt.Sprintf("TruncationReason(%v)", int(reason)) - } -} - -const ( - AppsecFieldTag = "ddwaf" - AppsecFieldTagValueIgnore = "ignore" -) - -type native interface { - int64 | uint64 | uintptr -} - -func newLimitedEncoder(timer timer.Timer) encoder { - return encoder{ - timer: timer, - containerMaxSize: bindings.WafMaxContainerSize, - stringMaxSize: bindings.WafMaxStringLength, - objectMaxDepth: bindings.WafMaxContainerDepth, - } -} - -func newMaxEncoder() encoder { - timer, _ := timer.NewTimer(timer.WithUnlimitedBudget()) - return encoder{ - timer: timer, - containerMaxSize: math.MaxInt, - stringMaxSize: math.MaxInt, - objectMaxDepth: math.MaxInt, - } -} - -// Encode takes a Go value and returns a wafObject pointer and an error. -// The returned wafObject is the root of the tree of nested wafObjects representing the Go value. -// The only error case is if the top-level object is "Unusable" which means that the data is nil or a non-data type -// like a function or a channel. -func (encoder *encoder) Encode(data any) (wo *bindings.WafObject, err error) { - value := reflect.ValueOf(data) - wo = &bindings.WafObject{} - - err = encoder.encode(value, wo, encoder.objectMaxDepth) - - if len(encoder.truncations[ObjectTooDeep]) != 0 && !encoder.timer.Exhausted() { - encoder.measureObjectDepth(value, encoder.timer.Remaining()) - } - - return -} - -// Truncations returns all truncations that happened since the last call to `Truncations()`, and clears the internal -// list. This is a map from truncation reason to the list of un-truncated value sizes. -func (encoder *encoder) Truncations() map[TruncationReason][]int { - result := encoder.truncations - encoder.truncations = nil - return result -} - -func encodeNative[T native](val T, t bindings.WafObjectType, obj *bindings.WafObject) { - obj.Type = t - obj.Value = (uintptr)(val) -} - -var nullableTypeKinds = map[reflect.Kind]struct{}{ - reflect.Interface: {}, - reflect.Pointer: {}, - reflect.UnsafePointer: {}, - reflect.Map: {}, - reflect.Slice: {}, - reflect.Func: {}, - reflect.Chan: {}, -} - -// isValueNil check if the value is nullable and if it is actually nil -// we cannot directly use value.IsNil() because it panics on non-pointer values -func isValueNil(value reflect.Value) bool { - _, nullable := nullableTypeKinds[value.Kind()] - return nullable && value.IsNil() -} - -func (encoder *encoder) encode(value reflect.Value, obj *bindings.WafObject, depth int) error { - if encoder.timer.Exhausted() { - return errors.ErrTimeout - } - - value, kind := resolvePointer(value) - if (kind == reflect.Interface || kind == reflect.Pointer) && !value.IsNil() { - // resolvePointer failed to resolve to something that's not a pointer, it - // has indirected too many times... - return errors.ErrTooManyIndirections - } - - // Measure-only runs for leaves - if obj == nil && kind != reflect.Array && kind != reflect.Slice && kind != reflect.Map && kind != reflect.Struct { - // Nothing to do, we were only here to measure object depth! - return nil - } - - switch { - // Terminal cases (leaves of the tree) - // Is invalid type: nil interfaces for example, cannot be used to run any reflect method or it's susceptible to panic - case !value.IsValid() || kind == reflect.Invalid: - return errors.ErrUnsupportedValue - // Is nullable type: nil pointers, channels, maps or functions - case isValueNil(value): - encodeNative[uintptr](0, bindings.WafNilType, obj) - - // Booleans - case kind == reflect.Bool: - encodeNative(unsafe.NativeToUintptr(value.Bool()), bindings.WafBoolType, obj) - - // Numbers - case value.CanInt(): // any int type or alias - encodeNative(value.Int(), bindings.WafIntType, obj) - case value.CanUint(): // any Uint type or alias - encodeNative(value.Uint(), bindings.WafUintType, obj) - case value.CanFloat(): // any float type or alias - encodeNative(unsafe.NativeToUintptr(value.Float()), bindings.WafFloatType, obj) - - // Strings - case kind == reflect.String: // string type - encoder.encodeString(value.String(), obj) - - case (kind == reflect.Array || kind == reflect.Slice) && value.Type().Elem().Kind() == reflect.Uint8: - // Byte Arrays are skipped voluntarily because they are often used - // to do partial parsing which leads to false positives - return nil - - // Containers (internal nodes of the tree) - - // All recursive cases can only execute if the depth is superior to 0. - case depth <= 0: - // Record that there was a truncation; we will try to measure the actual depth of the object afterwards. - encoder.addTruncation(ObjectTooDeep, -1) - return errors.ErrMaxDepthExceeded - - // Either an array or a slice of an array - case kind == reflect.Array || kind == reflect.Slice: - encoder.encodeArray(value, obj, depth-1) - case kind == reflect.Map: - encoder.encodeMap(value, obj, depth-1) - case kind == reflect.Struct: - encoder.encodeStruct(value, obj, depth-1) - - default: - return errors.ErrUnsupportedValue - } - - return nil -} - -func (encoder *encoder) encodeString(str string, obj *bindings.WafObject) { - size := len(str) - if size > encoder.stringMaxSize { - str = str[:encoder.stringMaxSize] - encoder.addTruncation(StringTooLong, size) - } - encoder.cgoRefs.AllocWafString(obj, str) -} - -func getFieldNameFromType(field reflect.StructField) (string, bool) { - fieldName := field.Name - - // Private and synthetics fields - if len(fieldName) < 1 || unicode.IsLower(rune(fieldName[0])) { - return "", false - } - - // Use the json tag name as field name if present - if tag, ok := field.Tag.Lookup("json"); ok { - if i := strings.IndexByte(tag, byte(',')); i > 0 { - tag = tag[:i] - } - if len(tag) > 0 { - fieldName = tag - } - } - - return fieldName, true -} - -// encodeStruct takes a reflect.Value and a wafObject pointer and iterates on the struct field to build -// a wafObject map of type wafMapType. The specificities are the following: -// - It will only take the first encoder.containerMaxSize elements of the struct -// - If the field has a json tag it will become the field name -// - Private fields and also values producing an error at encoding will be skipped -// - Even if the element values are invalid or null we still keep them to report the field name -func (encoder *encoder) encodeStruct(value reflect.Value, obj *bindings.WafObject, depth int) { - if encoder.timer.Exhausted() { - return - } - - typ := value.Type() - nbFields := typ.NumField() - - capacity := nbFields - length := 0 - if capacity > encoder.containerMaxSize { - capacity = encoder.containerMaxSize - } - - objArray := encoder.cgoRefs.AllocWafArray(obj, bindings.WafMapType, uint64(capacity)) - for i := 0; i < nbFields; i++ { - if encoder.timer.Exhausted() { - return - } - - if length == capacity { - encoder.addTruncation(ContainerTooLarge, nbFields) - break - } - - fieldType := typ.Field(i) - fieldName, usable := getFieldNameFromType(fieldType) - if tag, ok := fieldType.Tag.Lookup(AppsecFieldTag); !usable || ok && tag == AppsecFieldTagValueIgnore { - // Either the struct field is ignored by json marshaling so can we, - // or the field was explicitly set with `ddwaf:ignore` - continue - } - - objElem := &objArray[length] - // If the Map key is of unsupported type, skip it - encoder.encodeMapKeyFromString(fieldName, objElem) - - if err := encoder.encode(value.Field(i), objElem, depth); err != nil { - // We still need to keep the map key, so we can't discard the full object, instead, we make the value a noop - encodeNative[uintptr](0, bindings.WafInvalidType, objElem) - } - - length++ - } - - // Set the length to the final number of successfully encoded elements - obj.NbEntries = uint64(length) -} - -// encodeMap takes a reflect.Value and a wafObject pointer and iterates on the map elements and returns -// a wafObject map of type wafMapType. The specificities are the following: -// - It will only take the first encoder.containerMaxSize elements of the map -// - Even if the element values are invalid or null we still keep them to report the map key -func (encoder *encoder) encodeMap(value reflect.Value, obj *bindings.WafObject, depth int) { - capacity := value.Len() - if capacity > encoder.containerMaxSize { - capacity = encoder.containerMaxSize - } - - objArray := encoder.cgoRefs.AllocWafArray(obj, bindings.WafMapType, uint64(capacity)) - - length := 0 - for iter := value.MapRange(); iter.Next(); { - if encoder.timer.Exhausted() { - return - } - - if length == capacity { - encoder.addTruncation(ContainerTooLarge, value.Len()) - break - } - - objElem := &objArray[length] - if err := encoder.encodeMapKey(iter.Key(), objElem); err != nil { - continue - } - - if err := encoder.encode(iter.Value(), objElem, depth); err != nil { - // We still need to keep the map key, so we can't discard the full object, instead, we make the value a noop - encodeNative[uintptr](0, bindings.WafInvalidType, objElem) - } - - length++ - } - - // Fix the size because we skipped map entries - obj.NbEntries = uint64(length) -} - -// encodeMapKey takes a reflect.Value and a wafObject and returns a wafObject ready to be considered a map entry. We use -// the function cgoRefPool.AllocWafMapKey to store the key in the wafObject. But first we need to grab the real -// underlying value by recursing through the pointer and interface values. -func (encoder *encoder) encodeMapKey(value reflect.Value, obj *bindings.WafObject) error { - value, kind := resolvePointer(value) - - var keyStr string - switch { - case kind == reflect.Invalid: - return errors.ErrInvalidMapKey - case kind == reflect.String: - keyStr = value.String() - case value.Type() == reflect.TypeOf([]byte(nil)): - keyStr = string(value.Bytes()) - default: - return errors.ErrInvalidMapKey - } - - encoder.encodeMapKeyFromString(keyStr, obj) - return nil -} - -// encodeMapKeyFromString takes a string and a wafObject and sets the map key attribute on the wafObject to the supplied -// string. The key may be truncated if it exceeds the maximum string size allowed by the encoder. -func (encoder *encoder) encodeMapKeyFromString(keyStr string, obj *bindings.WafObject) { - size := len(keyStr) - if size > encoder.stringMaxSize { - keyStr = keyStr[:encoder.stringMaxSize] - encoder.addTruncation(StringTooLong, size) - } - - encoder.cgoRefs.AllocWafMapKey(obj, keyStr) -} - -// encodeArray takes a reflect.Value and a wafObject pointer and iterates on the elements and returns -// a wafObject array of type wafArrayType. The specificities are the following: -// - It will only take the first encoder.containerMaxSize elements of the array -// - Elements producing an error at encoding or null values will be skipped -func (encoder *encoder) encodeArray(value reflect.Value, obj *bindings.WafObject, depth int) { - length := value.Len() - - capacity := length - if capacity > encoder.containerMaxSize { - capacity = encoder.containerMaxSize - } - - currIndex := 0 - - objArray := encoder.cgoRefs.AllocWafArray(obj, bindings.WafArrayType, uint64(capacity)) - - for i := 0; i < length; i++ { - if encoder.timer.Exhausted() { - return - } - if currIndex == capacity { - encoder.addTruncation(ContainerTooLarge, length) - break - } - - objElem := &objArray[currIndex] - if err := encoder.encode(value.Index(i), objElem, depth); err != nil { - continue - } - - // If the element is null or invalid it has no impact on the waf execution, therefore we can skip its - // encoding. In this specific case we just overwrite it at the next loop iteration. - if objElem == nil || objElem.IsUnusable() { - continue - } - - currIndex++ - } - - // Fix the size because we skipped map entries - obj.NbEntries = uint64(currIndex) -} - -func (encoder *encoder) addTruncation(reason TruncationReason, size int) { - if encoder.truncations == nil { - encoder.truncations = make(map[TruncationReason][]int, 3) - } - encoder.truncations[reason] = append(encoder.truncations[reason], size) -} - -// mesureObjectDepth traverses the provided object recursively to try and obtain -// the real object depth, but limits itself to about 1ms of time budget, past -// which it'll stop and return whatever it has go to so far. -func (encoder *encoder) measureObjectDepth(obj reflect.Value, timeout time.Duration) { - ctx, cancelCtx := context.WithTimeout(context.Background(), timeout) - defer cancelCtx() - - depth, _ := depthOf(ctx, obj) - encoder.truncations[ObjectTooDeep] = []int{depth} -} - -// depthOf returns the depth of the provided object. This is 0 for scalar values, -// such as strings. -func depthOf(ctx context.Context, obj reflect.Value) (depth int, err error) { - if err = ctx.Err(); err != nil { - // Timed out, won't go any deeper - return 0, err - } - - obj, kind := resolvePointer(obj) - - var itemDepth int - switch kind { - case reflect.Array, reflect.Slice: - if obj.Type() == reflect.TypeOf([]byte(nil)) { - // We treat byte slices as strings - return 0, nil - } - for i := 0; i < obj.Len(); i++ { - itemDepth, err = depthOf(ctx, obj.Index(i)) - depth = max(depth, itemDepth) - if err != nil { - break - } - } - return depth + 1, err - case reflect.Map: - for iter := obj.MapRange(); iter.Next(); { - itemDepth, err = depthOf(ctx, iter.Value()) - depth = max(depth, itemDepth) - if err != nil { - break - } - } - return depth + 1, err - case reflect.Struct: - typ := obj.Type() - for i := 0; i < obj.NumField(); i++ { - fieldType := typ.Field(i) - _, usable := getFieldNameFromType(fieldType) - if !usable { - continue - } - - itemDepth, err = depthOf(ctx, obj.Field(i)) - depth = max(depth, itemDepth) - if err != nil { - break - } - } - return depth + 1, err - default: - return 0, nil - } -} - -// resovlePointer attempts to resolve a pointer while limiting the pointer depth -// to be traversed, so that this is not susceptible to an infinite loop when -// provided a self-referencing pointer. -func resolvePointer(obj reflect.Value) (reflect.Value, reflect.Kind) { - kind := obj.Kind() - for limit := 8; limit > 0 && kind == reflect.Pointer || kind == reflect.Interface; limit-- { - if obj.IsNil() { - return obj, kind - } - obj = obj.Elem() - kind = obj.Kind() - } - return obj, kind -} diff --git a/vendor/github.com/DataDog/go-libddwaf/v3/errors/support.go b/vendor/github.com/DataDog/go-libddwaf/v3/errors/support.go deleted file mode 100644 index 79fbe1da..00000000 --- a/vendor/github.com/DataDog/go-libddwaf/v3/errors/support.go +++ /dev/null @@ -1,45 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package errors - -import ( - "fmt" - "runtime" -) - -// UnsupportedOSArchError is a wrapper error type helping to handle the error -// case of trying to execute this package when the OS or architecture is not supported. -type UnsupportedOSArchError struct { - Os string - Arch string -} - -func (e UnsupportedOSArchError) Error() string { - return fmt.Sprintf("unsupported OS/Arch: %s/%s", e.Os, e.Arch) -} - -// UnsupportedGoVersionError is a wrapper error type helping to handle the error -// case of trying to execute this package when the Go version is not supported. -type UnsupportedGoVersionError struct{} - -func (e UnsupportedGoVersionError) Error() string { - return fmt.Sprintf("unsupported Go version: %s", runtime.Version()) -} - -type CgoDisabledError struct{} - -func (e CgoDisabledError) Error() string { - return "go-libddwaf is disabled when cgo is disabled unless you compile with the go build tag `appsec`. It will require libdl.so.2. libpthread.so.0 and libc.so.6 shared libraries at run time on linux" -} - -// ManuallyDisabledError is a wrapper error type helping to handle the error -// case of trying to execute this package when the WAF has been manually disabled with -// the `datadog.no_waf` go build tag. -type ManuallyDisabledError struct{} - -func (e ManuallyDisabledError) Error() string { - return "the WAF has been manually disabled using the `datadog.no_waf` go build tag" -} diff --git a/vendor/github.com/DataDog/go-libddwaf/v3/errors/waf.go b/vendor/github.com/DataDog/go-libddwaf/v3/errors/waf.go deleted file mode 100644 index edc77455..00000000 --- a/vendor/github.com/DataDog/go-libddwaf/v3/errors/waf.go +++ /dev/null @@ -1,76 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package errors - -import ( - "errors" - "fmt" -) - -// Encoder/Decoder errors -var ( - ErrMaxDepthExceeded = errors.New("max depth exceeded") - ErrUnsupportedValue = errors.New("unsupported Go value") - ErrInvalidMapKey = errors.New("invalid WAF object map key") - ErrNilObjectPtr = errors.New("nil WAF object pointer") - ErrInvalidObjectType = errors.New("invalid type encountered when decoding") - ErrTooManyIndirections = errors.New("too many indirections") -) - -// RunError the WAF can return when running it. -type RunError int - -// Errors the WAF can return when running it. -const ( - ErrInternal RunError = iota + 1 - ErrInvalidObject - ErrInvalidArgument - ErrTimeout - ErrOutOfMemory - ErrEmptyRuleAddresses -) - -var errorStrMap = map[RunError]string{ - ErrInternal: "internal waf error", - ErrInvalidObject: "invalid waf object", - ErrInvalidArgument: "invalid waf argument", - ErrTimeout: "waf timeout", - ErrOutOfMemory: "out of memory", - ErrEmptyRuleAddresses: "empty rule addresses", -} - -// Error returns the string representation of the RunError. -func (e RunError) Error() string { - description, ok := errorStrMap[e] - if !ok { - return fmt.Sprintf("unknown waf error %d", e) - } - - return description -} - -// PanicError is an error type wrapping a recovered panic value that happened -// during a function call. Such error must be considered unrecoverable and be -// used to try to gracefully abort. Keeping using this package after such an -// error is unreliable and the caller must rather stop using the library. -// Examples include safety checks errors. -type PanicError struct { - // The recovered panic error while executing the function `in`. - Err error - // The function symbol name that was given to `tryCall()`. - In string -} - -// Unwrap the error and return it. -// Required by errors.Is and errors.As functions. -func (e *PanicError) Unwrap() error { - return e.Err -} - -// Error returns the error string representation. -func (e *PanicError) Error() string { - return fmt.Sprintf("panic while executing %s: %#+v", e.In, e.Err) -} diff --git a/vendor/github.com/DataDog/go-libddwaf/v3/handle.go b/vendor/github.com/DataDog/go-libddwaf/v3/handle.go deleted file mode 100644 index 799c847f..00000000 --- a/vendor/github.com/DataDog/go-libddwaf/v3/handle.go +++ /dev/null @@ -1,258 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package waf - -import ( - "errors" - "fmt" - "sync/atomic" - "time" - - wafErrors "github.com/DataDog/go-libddwaf/v3/errors" - "github.com/DataDog/go-libddwaf/v3/internal/bindings" - "github.com/DataDog/go-libddwaf/v3/internal/unsafe" - "github.com/DataDog/go-libddwaf/v3/timer" -) - -// Handle represents an instance of the WAF for a given ruleset. -type Handle struct { - // diagnostics holds information about rules initialization - diagnostics Diagnostics - - // Lock-less reference counter avoiding blocking calls to the Close() method - // while WAF contexts are still using the WAF handle. Instead, we let the - // release actually happen only when the reference counter reaches 0. - // This can happen either from a request handler calling its WAF context's - // Close() method, or either from the appsec instance calling the WAF - // handle's Close() method when creating a new WAF handle with new rules. - // Note that this means several instances of the WAF can exist at the same - // time with their own set of rules. This choice was done to be able to - // efficiently update the security rules concurrently, without having to - // block the request handlers for the time of the security rules update. - refCounter atomic.Int32 - - // Instance of the WAF - cHandle bindings.WafHandle -} - -// NewHandle creates and returns a new instance of the WAF with the given security rules and configuration -// of the sensitive data obfuscator. The returned handle is nil in case of an error. -// Rules-related metrics, including errors, are accessible with the `RulesetInfo()` method. -func NewHandle(rules any, keyObfuscatorRegex string, valueObfuscatorRegex string) (*Handle, error) { - // The order of action is the following: - // - Open the ddwaf C library - // - Encode the security rules as a ddwaf_object - // - Create a ddwaf_config object and fill the values - // - Run ddwaf_init to create a new handle based on the given rules and config - // - Check for errors and streamline the ddwaf_ruleset_info returned - - if ok, err := Load(); !ok { - return nil, err - // The case where ok == true && err != nil is ignored on purpose, as - // this is out of the scope of NewHandle which only requires a properly - // loaded libddwaf in order to use it - } - - encoder := newMaxEncoder() - obj, err := encoder.Encode(rules) - if err != nil { - return nil, fmt.Errorf("could not encode the WAF ruleset into a WAF object: %w", err) - } - - config := newConfig(&encoder.cgoRefs, keyObfuscatorRegex, valueObfuscatorRegex) - diagnosticsWafObj := new(bindings.WafObject) - defer wafLib.WafObjectFree(diagnosticsWafObj) - - cHandle := wafLib.WafInit(obj, config, diagnosticsWafObj) - unsafe.KeepAlive(encoder.cgoRefs) // Keep this AFTER the call to wafLib.WafInit - - return newHandle(cHandle, diagnosticsWafObj) -} - -// newHandle creates a new Handle from a C handle (nullable) and a diagnostics object. -// and it handles the multiple ways a WAF initialization can fail. -func newHandle(cHandle bindings.WafHandle, diagnosticsWafObj *bindings.WafObject) (*Handle, error) { - diags, diagsErr := decodeDiagnostics(diagnosticsWafObj) - if cHandle == 0 && diagsErr != nil { // WAF Failed initialization and we manage to decode the diagnostics, return the diagnostics error - if err := diags.TopLevelError(); err != nil { - return nil, fmt.Errorf("could not instantiate the WAF: %w", err) - } - } - - if cHandle == 0 { - // WAF Failed initialization, report the best possible error... - return nil, errors.New("could not instantiate the WAF") - } - - // The WAF successfully initialized at this stage but if the diagnostics decoding failed, we still need to cleanup - if diagsErr != nil { - wafLib.WafDestroy(cHandle) - return nil, fmt.Errorf("could not decode the WAF diagnostics: %w", diagsErr) - } - - handle := &Handle{ - cHandle: cHandle, - diagnostics: diags, - } - - handle.refCounter.Store(1) // We count the handle itself in the counter - return handle, nil -} - -// NewContext returns a new WAF context for the given WAF handle. -// A nil value is returned when the WAF handle was released or when the -// WAF context couldn't be created. -func (handle *Handle) NewContext() (*Context, error) { - return handle.NewContextWithBudget(timer.UnlimitedBudget) -} - -// NewContextWithBudget returns a new WAF context for the given WAF handle. -// A nil value is returned when the WAF handle was released or when the -// WAF context couldn't be created. -func (handle *Handle) NewContextWithBudget(budget time.Duration) (*Context, error) { - // Handle has been released - if !handle.retain() { - return nil, fmt.Errorf("handle was released") - } - - cContext := wafLib.WafContextInit(handle.cHandle) - if cContext == 0 { - handle.release() // We couldn't get a context, so we no longer have an implicit reference to the Handle in it... - return nil, fmt.Errorf("could not get C context") - } - - timer, err := timer.NewTreeTimer(timer.WithBudget(budget), timer.WithComponents(wafRunTag)) - if err != nil { - return nil, err - } - - return &Context{ - handle: handle, - cContext: cContext, - timer: timer, - metrics: metricsStore{data: make(map[metricKey]time.Duration, 5)}, - truncations: make(map[Scope]map[TruncationReason][]int, 2), - timeoutCount: map[Scope]*atomic.Uint64{ - DefaultScope: new(atomic.Uint64), - RASPScope: new(atomic.Uint64), - }, - }, nil -} - -// Diagnostics returns the rules initialization metrics for the current WAF handle -func (handle *Handle) Diagnostics() Diagnostics { - return handle.diagnostics -} - -// Addresses returns the list of addresses the WAF has been configured to monitor based on the input ruleset -func (handle *Handle) Addresses() []string { - return wafLib.WafKnownAddresses(handle.cHandle) -} - -// Actions returns the list of actions the WAF has been configured to monitor based on the input ruleset -func (handle *Handle) Actions() []string { - return wafLib.WafKnownActions(handle.cHandle) -} - -// Update the ruleset of a WAF instance into a new handle on its own -// the previous handle still needs to be closed manually -func (handle *Handle) Update(newRules any) (*Handle, error) { - encoder := newMaxEncoder() - obj, err := encoder.Encode(newRules) - if err != nil { - return nil, fmt.Errorf("could not encode the WAF ruleset into a WAF object: %w", err) - } - - diagnosticsWafObj := new(bindings.WafObject) - defer wafLib.WafObjectFree(diagnosticsWafObj) - - return newHandle(wafLib.WafUpdate(handle.cHandle, obj, diagnosticsWafObj), diagnosticsWafObj) -} - -// Close puts the handle in termination state, when all the contexts are closed the handle will be destroyed -func (handle *Handle) Close() { - if handle.addRefCounter(-1) != 0 { - // Either the counter is still positive (this Handle is still referenced), or it had previously - // reached 0 and some other call has done the cleanup already. - return - } - - wafLib.WafDestroy(handle.cHandle) - handle.diagnostics = Diagnostics{} // Data in diagnostics may no longer be valid (e.g: strings from libddwaf) - handle.cHandle = 0 // Makes it easy to spot use-after-free/double-free issues -} - -// retain increments the reference counter of this Handle. Returns true if the -// Handle is still valid, false if it is no longer usable. Calls to retain() -// must be balanced with calls to release() in order to avoid leaking Handles. -func (handle *Handle) retain() bool { - return handle.addRefCounter(1) > 0 -} - -// release decrements the reference counter of this Handle, possibly causing it -// to be completely closed if no other reference to it exist. -func (handle *Handle) release() { - handle.Close() -} - -// addRefCounter adds x to Handle.refCounter. The return valid indicates whether the refCounter reached 0 as part of -// this call or not, which can be used to perform "only-once" activities: -// - result > 0 => the Handle is still usable -// - result == 0 => the handle is no longer usable, ref counter reached 0 as part of this call -// - result == -1 => the handle is no longer usable, ref counter was already 0 previously -func (handle *Handle) addRefCounter(x int32) int32 { - // We use a CAS loop to avoid setting the refCounter to a negative value. - for { - current := handle.refCounter.Load() - if current <= 0 { - // The object had already been released - return -1 - } - - next := current + x - if swapped := handle.refCounter.CompareAndSwap(current, next); swapped { - if next < 0 { - // TODO(romain.marcadier): somehow signal unexpected behavior to the - // caller (panic? error?). We currently clamp to 0 in order to avoid - // causing a customer program crash, but this is the symptom of a bug - // and should be investigated (however this clamping hides the issue). - return 0 - } - return next - } - } -} - -func newConfig(cgoRefs *cgoRefPool, keyObfuscatorRegex string, valueObfuscatorRegex string) *bindings.WafConfig { - config := new(bindings.WafConfig) - *config = bindings.WafConfig{ - Limits: bindings.WafConfigLimits{ - MaxContainerDepth: bindings.WafMaxContainerDepth, - MaxContainerSize: bindings.WafMaxContainerSize, - MaxStringLength: bindings.WafMaxStringLength, - }, - Obfuscator: bindings.WafConfigObfuscator{ - KeyRegex: cgoRefs.AllocCString(keyObfuscatorRegex), - ValueRegex: cgoRefs.AllocCString(valueObfuscatorRegex), - }, - // Prevent libddwaf from freeing our Go-memory-allocated ddwaf_objects - FreeFn: 0, - } - return config -} - -func goRunError(rc bindings.WafReturnCode) error { - switch rc { - case bindings.WafErrInternal: - return wafErrors.ErrInternal - case bindings.WafErrInvalidObject: - return wafErrors.ErrInvalidObject - case bindings.WafErrInvalidArgument: - return wafErrors.ErrInvalidArgument - default: - return fmt.Errorf("unknown waf return code %d", int(rc)) - } -} diff --git a/vendor/github.com/DataDog/go-libddwaf/v3/internal/bindings/ctypes.go b/vendor/github.com/DataDog/go-libddwaf/v3/internal/bindings/ctypes.go deleted file mode 100644 index ba21f902..00000000 --- a/vendor/github.com/DataDog/go-libddwaf/v3/internal/bindings/ctypes.go +++ /dev/null @@ -1,113 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package bindings - -const ( - WafMaxStringLength = 4096 - WafMaxContainerDepth = 20 - WafMaxContainerSize = 256 - WafRunTimeout = 5000 -) - -type WafReturnCode int32 - -const ( - WafErrInternal WafReturnCode = iota - 3 - WafErrInvalidObject - WafErrInvalidArgument - WafOK - WafMatch -) - -// wafObjectType is an enum in C which has the size of DWORD. -// But DWORD is 4 bytes in amd64 and arm64 so uint32 it is. -type WafObjectType uint32 - -const WafInvalidType WafObjectType = 0 -const ( - WafIntType WafObjectType = 1 << iota - WafUintType - WafStringType - WafArrayType - WafMapType - WafBoolType - WafFloatType - WafNilType -) - -type WafObject struct { - ParameterName uintptr - ParameterNameLength uint64 - Value uintptr - NbEntries uint64 - Type WafObjectType - _ [4]byte - // Forced padding - // We only support 2 archs and cgo generated the same padding to both. - // We don't want the C struct to be packed because actually go will do the same padding itself, - // we just add it explicitly to not take any chance. - // And we cannot pack a struct in go so it will get tricky if the struct is - // packed (apart from breaking all tracers of course) -} - -// isInvalid determines whether this WAF Object has the invalid type (which is the 0-value). -func (w *WafObject) IsInvalid() bool { - return w.Type == WafInvalidType -} - -// isNil determines whether this WAF Object is nil or not. -func (w *WafObject) IsNil() bool { - return w.Type == WafNilType -} - -// isArray determines whether this WAF Object is an array or not. -func (w *WafObject) IsArray() bool { - return w.Type == WafArrayType -} - -// isMap determines whether this WAF Object is a map or not. -func (w *WafObject) IsMap() bool { - return w.Type == WafMapType -} - -// IsUnusable returns true if the wafObject has no impact on the WAF execution -// But we still need this kind of objects to forward map keys in case the value of the map is invalid -func (wo *WafObject) IsUnusable() bool { - return wo.Type == WafInvalidType || wo.Type == WafNilType -} - -type WafConfig struct { - Limits WafConfigLimits - Obfuscator WafConfigObfuscator - FreeFn uintptr -} - -type WafConfigLimits struct { - MaxContainerSize uint32 - MaxContainerDepth uint32 - MaxStringLength uint32 -} - -type WafConfigObfuscator struct { - KeyRegex uintptr // char * - ValueRegex uintptr // char * -} - -type WafResult struct { - Timeout byte - Events WafObject - Actions WafObject - Derivatives WafObject - TotalRuntime uint64 -} - -// wafHandle is a forward declaration in ddwaf.h header -// We basically don't need to modify it, only to give it to the waf -type WafHandle uintptr - -// wafContext is a forward declaration in ddwaf.h header -// We basically don't need to modify it, only to give it to the waf -type WafContext uintptr diff --git a/vendor/github.com/DataDog/go-libddwaf/v3/internal/bindings/safe.go b/vendor/github.com/DataDog/go-libddwaf/v3/internal/bindings/safe.go deleted file mode 100644 index 5b2559c6..00000000 --- a/vendor/github.com/DataDog/go-libddwaf/v3/internal/bindings/safe.go +++ /dev/null @@ -1,48 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -package bindings - -import ( - wafErrors "github.com/DataDog/go-libddwaf/v3/errors" - - "fmt" - "reflect" - "runtime" - - "github.com/pkg/errors" -) - -func newPanicError(in any, err error) *wafErrors.PanicError { - return &wafErrors.PanicError{ - In: runtime.FuncForPC(reflect.ValueOf(in).Pointer()).Name(), - Err: err, - } -} - -// tryCall calls function `f` and recovers from any panic occurring while it -// executes, returning it in a `PanicError` object type. -func tryCall[T any](f func() T) (res T, err error) { - defer func() { - r := recover() - if r == nil { - // Note that panic(nil) matches this case and cannot be really tested for. - return - } - - switch actual := r.(type) { - case error: - err = errors.WithStack(actual) - case string: - err = errors.New(actual) - default: - err = fmt.Errorf("%v", r) - } - - err = newPanicError(f, err) - }() - res = f() - return -} diff --git a/vendor/github.com/DataDog/go-libddwaf/v3/internal/bindings/waf_dl.go b/vendor/github.com/DataDog/go-libddwaf/v3/internal/bindings/waf_dl.go deleted file mode 100644 index a8b96925..00000000 --- a/vendor/github.com/DataDog/go-libddwaf/v3/internal/bindings/waf_dl.go +++ /dev/null @@ -1,238 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -//go:build (linux || darwin) && (amd64 || arm64) && !go1.24 && !datadog.no_waf && (cgo || appsec) - -package bindings - -import ( - "errors" - "fmt" - "os" - - "github.com/DataDog/go-libddwaf/v3/internal/lib" - "github.com/DataDog/go-libddwaf/v3/internal/log" - "github.com/DataDog/go-libddwaf/v3/internal/unsafe" - "github.com/ebitengine/purego" -) - -// WafDl is the type wrapper for all C calls to the waf -// It uses `libwaf` to make C calls -// All calls must go through this one-liner to be type safe -// since purego calls are not type safe -type WafDl struct { - wafSymbols - handle uintptr -} - -type wafSymbols struct { - init uintptr - update uintptr - destroy uintptr - knownAddresses uintptr - knownActions uintptr - getVersion uintptr - contextInit uintptr - contextDestroy uintptr - objectFree uintptr - resultFree uintptr - run uintptr -} - -// NewWafDl loads the libddwaf shared library and resolves all tge relevant symbols. -// The caller is responsible for calling wafDl.Close on the returned object once they -// are done with it so that associated resources can be released. -func NewWafDl() (dl *WafDl, err error) { - path, closer, err := lib.DumpEmbeddedWAF() - if err != nil { - return nil, fmt.Errorf("dump embedded WAF: %w", err) - } - defer func() { - if rmErr := closer(); rmErr != nil { - err = errors.Join(err, fmt.Errorf("error removing %s: %w", path, rmErr)) - } - }() - - var handle uintptr - if handle, err = purego.Dlopen(path, purego.RTLD_GLOBAL|purego.RTLD_NOW); err != nil { - return nil, fmt.Errorf("load a dynamic library file: %w", err) - } - - var symbols wafSymbols - if symbols, err = resolveWafSymbols(handle); err != nil { - if closeErr := purego.Dlclose(handle); closeErr != nil { - err = errors.Join(err, fmt.Errorf("error released the shared libddwaf library: %w", closeErr)) - } - return - } - - dl = &WafDl{symbols, handle} - - // Try calling the waf to make sure everything is fine - if _, err = tryCall(dl.WafGetVersion); err != nil { - if closeErr := purego.Dlclose(handle); closeErr != nil { - err = errors.Join(err, fmt.Errorf("error released the shared libddwaf library: %w", closeErr)) - } - return - } - - if val := os.Getenv(log.EnvVarLogLevel); val != "" { - setLogSym, symErr := purego.Dlsym(handle, "ddwaf_set_log_cb") - if symErr != nil { - return nil, fmt.Errorf("get symbol: %w", symErr) - } - logLevel := log.LevelNamed(val) - dl.syscall(setLogSym, log.CallbackFunctionPointer(), uintptr(logLevel)) - } - - return -} - -func (waf *WafDl) Close() error { - return purego.Dlclose(waf.handle) -} - -// WafGetVersion returned string is a static string so we do not need to free it -func (waf *WafDl) WafGetVersion() string { - return unsafe.Gostring(unsafe.Cast[byte](waf.syscall(waf.getVersion))) -} - -// WafInit initializes a new WAF with the provided ruleset, configuration and info objects. A -// cgoRefPool ensures that the provided input values are not moved or garbage collected by the Go -// runtime during the WAF call. -func (waf *WafDl) WafInit(ruleset *WafObject, config *WafConfig, info *WafObject) WafHandle { - handle := WafHandle(waf.syscall(waf.init, unsafe.PtrToUintptr(ruleset), unsafe.PtrToUintptr(config), unsafe.PtrToUintptr(info))) - unsafe.KeepAlive(ruleset) - unsafe.KeepAlive(config) - unsafe.KeepAlive(info) - return handle -} - -func (waf *WafDl) WafUpdate(handle WafHandle, ruleset *WafObject, info *WafObject) WafHandle { - newHandle := WafHandle(waf.syscall(waf.update, uintptr(handle), unsafe.PtrToUintptr(ruleset), unsafe.PtrToUintptr(info))) - unsafe.KeepAlive(ruleset) - unsafe.KeepAlive(info) - return newHandle -} - -func (waf *WafDl) WafDestroy(handle WafHandle) { - waf.syscall(waf.destroy, uintptr(handle)) - unsafe.KeepAlive(handle) -} - -func (waf *WafDl) wafKnownX(handle WafHandle, symbol uintptr) []string { - var nbAddresses uint32 - - arrayVoidC := waf.syscall(symbol, uintptr(handle), unsafe.PtrToUintptr(&nbAddresses)) - if arrayVoidC == 0 { - return nil - } - - // These C strings are static strings so we do not need to free them - addresses := make([]string, int(nbAddresses)) - for i := 0; i < int(nbAddresses); i++ { - addresses[i] = unsafe.Gostring(*unsafe.CastWithOffset[*byte](arrayVoidC, uint64(i))) - } - - unsafe.KeepAlive(&nbAddresses) - unsafe.KeepAlive(handle) - - return addresses -} - -func (waf *WafDl) WafKnownAddresses(handle WafHandle) []string { - return waf.wafKnownX(handle, waf.knownAddresses) -} - -func (waf *WafDl) WafKnownActions(handle WafHandle) []string { - return waf.wafKnownX(handle, waf.knownActions) -} - -func (waf *WafDl) WafContextInit(handle WafHandle) WafContext { - ctx := WafContext(waf.syscall(waf.contextInit, uintptr(handle))) - unsafe.KeepAlive(handle) - return ctx -} - -func (waf *WafDl) WafContextDestroy(context WafContext) { - waf.syscall(waf.contextDestroy, uintptr(context)) - unsafe.KeepAlive(context) -} - -func (waf *WafDl) WafResultFree(result *WafResult) { - waf.syscall(waf.resultFree, unsafe.PtrToUintptr(result)) - unsafe.KeepAlive(result) -} - -func (waf *WafDl) WafObjectFree(obj *WafObject) { - waf.syscall(waf.objectFree, unsafe.PtrToUintptr(obj)) - unsafe.KeepAlive(obj) -} - -func (waf *WafDl) WafRun(context WafContext, persistentData, ephemeralData *WafObject, result *WafResult, timeout uint64) WafReturnCode { - rc := WafReturnCode(waf.syscall(waf.run, uintptr(context), unsafe.PtrToUintptr(persistentData), unsafe.PtrToUintptr(ephemeralData), unsafe.PtrToUintptr(result), uintptr(timeout))) - unsafe.KeepAlive(context) - unsafe.KeepAlive(persistentData) - unsafe.KeepAlive(ephemeralData) - unsafe.KeepAlive(result) - unsafe.KeepAlive(timeout) - return rc -} - -func (waf *WafDl) Handle() uintptr { - return waf.handle -} - -// syscall is the only way to make C calls with this interface. -// purego implementation limits the number of arguments to 9, it will panic if more are provided -// Note: `purego.SyscallN` has 3 return values: these are the following: -// -// 1st - The return value is a pointer or a int of any type -// 2nd - The return value is a float -// 3rd - The value of `errno` at the end of the call -func (waf *WafDl) syscall(fn uintptr, args ...uintptr) uintptr { - ret, _, _ := purego.SyscallN(fn, args...) - return ret -} - -// resolveWafSymbols resolves relevant symbols from the libddwaf shared library using the provided -// purego.Dlopen handle. -func resolveWafSymbols(handle uintptr) (symbols wafSymbols, err error) { - if symbols.init, err = purego.Dlsym(handle, "ddwaf_init"); err != nil { - return - } - if symbols.update, err = purego.Dlsym(handle, "ddwaf_update"); err != nil { - return - } - if symbols.destroy, err = purego.Dlsym(handle, "ddwaf_destroy"); err != nil { - return - } - if symbols.knownAddresses, err = purego.Dlsym(handle, "ddwaf_known_addresses"); err != nil { - return - } - if symbols.knownActions, err = purego.Dlsym(handle, "ddwaf_known_actions"); err != nil { - return - } - if symbols.getVersion, err = purego.Dlsym(handle, "ddwaf_get_version"); err != nil { - return - } - if symbols.contextInit, err = purego.Dlsym(handle, "ddwaf_context_init"); err != nil { - return - } - if symbols.contextDestroy, err = purego.Dlsym(handle, "ddwaf_context_destroy"); err != nil { - return - } - if symbols.resultFree, err = purego.Dlsym(handle, "ddwaf_result_free"); err != nil { - return - } - if symbols.objectFree, err = purego.Dlsym(handle, "ddwaf_object_free"); err != nil { - return - } - if symbols.run, err = purego.Dlsym(handle, "ddwaf_run"); err != nil { - return - } - - return -} diff --git a/vendor/github.com/DataDog/go-libddwaf/v3/internal/bindings/waf_dl_unsupported.go b/vendor/github.com/DataDog/go-libddwaf/v3/internal/bindings/waf_dl_unsupported.go deleted file mode 100644 index 9745bef1..00000000 --- a/vendor/github.com/DataDog/go-libddwaf/v3/internal/bindings/waf_dl_unsupported.go +++ /dev/null @@ -1,55 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -// Build when the target OS or architecture are not supported -//go:build (!linux && !darwin) || (!amd64 && !arm64) || go1.24 || datadog.no_waf || (!cgo && !appsec) - -package bindings - -type WafDl struct{} - -func NewWafDl() (dl *WafDl, err error) { - return nil, nil -} - -func (waf *WafDl) WafGetVersion() string { - return "" -} - -func (waf *WafDl) WafInit(obj *WafObject, config *WafConfig, info *WafObject) WafHandle { - return 0 -} - -func (waf *WafDl) WafUpdate(handle WafHandle, ruleset *WafObject, info *WafObject) WafHandle { - return 0 -} - -func (waf *WafDl) WafDestroy(handle WafHandle) { -} - -func (waf *WafDl) WafKnownAddresses(handle WafHandle) []string { - return nil -} - -func (waf *WafDl) WafKnownActions(handle WafHandle) []string { - return nil -} - -func (waf *WafDl) WafContextInit(handle WafHandle) WafContext { - return 0 -} - -func (waf *WafDl) WafContextDestroy(context WafContext) { -} - -func (waf *WafDl) WafResultFree(result *WafResult) { -} - -func (waf *WafDl) WafObjectFree(obj *WafObject) { -} - -func (waf *WafDl) WafRun(context WafContext, persistentData, ephemeralData *WafObject, result *WafResult, timeout uint64) WafReturnCode { - return WafErrInternal -} diff --git a/vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/.version b/vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/.version deleted file mode 100644 index 1acb46a4..00000000 --- a/vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/.version +++ /dev/null @@ -1 +0,0 @@ -1.20.1 \ No newline at end of file diff --git a/vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/README.md b/vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/README.md deleted file mode 100644 index 010d41bf..00000000 --- a/vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/README.md +++ /dev/null @@ -1,21 +0,0 @@ -## Embedded WAF libraries - -This directory contains Datadog's WAF static libraries taken from the releases -of https://github.com/DataDog/libddwaf - -### Updating - -From the root of the repository, run: - -```console -./_tools/libddwaf-updater/update.sh -Will upgrade from v1.14.0 to v1.15.0 -... downloaded /Datadog/go-libddwaf/include/ddwaf.h -... downloaded /Datadog/go-libddwaf/lib/darwin-arm64/libddwaf.dylib -... downloaded /Datadog/go-libddwaf/lib/darwin-amd64/libddwaf.dylib -... downloaded /Datadog/go-libddwaf/lib/linux-arm64/libddwaf.so -... downloaded /Datadog/go-libddwaf/lib/linux-amd64/libddwaf.so -... downloaded /Datadog/go-libddwaf/lib/linux-armv7/libddwaf.so -... downloaded /Datadog/go-libddwaf/lib/linux-i386/libddwaf.so -All done! Don't forget to check in changes to include/ and lib/, check the libddwaf upgrade guide to update bindings! -``` diff --git a/vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/doc.go b/vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/doc.go deleted file mode 100644 index 5f44fb80..00000000 --- a/vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/doc.go +++ /dev/null @@ -1,7 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -// Package lib provides a built-in WAF library version for the relevant runtime platform. -package lib diff --git a/vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/dump_waf_darwin.go b/vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/dump_waf_darwin.go deleted file mode 100644 index b0ec8e10..00000000 --- a/vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/dump_waf_darwin.go +++ /dev/null @@ -1,57 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -//go:build darwin && (amd64 || arm64) && !go1.24 && !datadog.no_waf && (cgo || appsec) - -package lib - -import ( - "bytes" - "compress/gzip" - _ "embed" - "errors" - "fmt" - "io" - "os" -) - -// DumpEmbeddedWAF for darwin platform. -// DumpEmbeddedWAF creates a temporary file with the embedded WAF library content and returns the path to the file, -// a closer function and an error. This is the only way to make all implementations of DumpEmbeddedWAF consistent -// across all platforms. -func DumpEmbeddedWAF() (path string, closer func() error, err error) { - file, err := os.CreateTemp("", "libddwaf-*.dylib") - if err != nil { - return "", nil, fmt.Errorf("error creating temp file: %w", err) - } - - defer func() { - if err != nil { - if closeErr := file.Close(); closeErr != nil { - err = errors.Join(err, fmt.Errorf("error closing file: %w", closeErr)) - } - if rmErr := os.Remove(file.Name()); rmErr != nil { - err = errors.Join(err, fmt.Errorf("error removing file: %w", rmErr)) - } - } - }() - - gr, err := gzip.NewReader(bytes.NewReader(libddwaf)) - if err != nil { - return "", nil, fmt.Errorf("error creating gzip reader: %w", err) - } - - if _, err := io.Copy(file, gr); err != nil { - return "", nil, fmt.Errorf("error copying gzip content to file: %w", err) - } - - if err := gr.Close(); err != nil { - return "", nil, fmt.Errorf("error closing gzip reader: %w", err) - } - - return file.Name(), func() error { - return errors.Join(file.Close(), os.Remove(file.Name())) - }, nil -} diff --git a/vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/dump_waf_linux.go b/vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/dump_waf_linux.go deleted file mode 100644 index c2767fba..00000000 --- a/vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/dump_waf_linux.go +++ /dev/null @@ -1,58 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -//go:build linux && (amd64 || arm64) && !go1.24 && !datadog.no_waf && (cgo || appsec) - -package lib - -import ( - "bytes" - "compress/gzip" - "errors" - "fmt" - "io" - "os" - - "golang.org/x/sys/unix" -) - -// DumpEmbeddedWAF for linux systems. -// It creates a memfd and writes the embedded WAF library to it. Then it returns the path the /proc/self/fd/ path -// to the file. This trick makes us able to load the library without having to write it to disk. -// Hence, making go-libddwaf work on full read-only filesystems. -func DumpEmbeddedWAF() (path string, closer func() error, err error) { - fd, err := unix.MemfdCreate("libddwaf", 0) - if err != nil { - return "", nil, fmt.Errorf("error creating memfd: %w", err) - } - - file := os.NewFile(uintptr(fd), fmt.Sprintf("/proc/self/fd/%d", fd)) - if file == nil { - return "", nil, errors.New("error creating file from fd") - } - - defer func() { - if file != nil && err != nil { - if closeErr := file.Close(); closeErr != nil { - err = errors.Join(err, fmt.Errorf("error closing file: %w", closeErr)) - } - } - }() - - gr, err := gzip.NewReader(bytes.NewReader(libddwaf)) - if err != nil { - return "", nil, fmt.Errorf("error creating gzip reader: %w", err) - } - - if _, err := io.Copy(file, gr); err != nil { - return "", nil, fmt.Errorf("error copying gzip content to memfd: %w", err) - } - - if err := gr.Close(); err != nil { - return "", nil, fmt.Errorf("error closing gzip reader: %w", err) - } - - return file.Name(), file.Close, nil -} diff --git a/vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/lib_darwin_amd64.go b/vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/lib_darwin_amd64.go deleted file mode 100644 index 16868569..00000000 --- a/vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/lib_darwin_amd64.go +++ /dev/null @@ -1,15 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -//go:build darwin && amd64 && !go1.24 && !datadog.no_waf && (cgo || appsec) - -package lib - -// THIS FILE IS AUTOGENERATED. DO NOT EDIT. - -import _ "embed" // Needed for go:embed - -//go:embed libddwaf-darwin-amd64.dylib.gz -var libddwaf []byte diff --git a/vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/lib_darwin_arm64.go b/vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/lib_darwin_arm64.go deleted file mode 100644 index eca7b655..00000000 --- a/vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/lib_darwin_arm64.go +++ /dev/null @@ -1,15 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -//go:build darwin && arm64 && !go1.24 && !datadog.no_waf && (cgo || appsec) - -package lib - -// THIS FILE IS AUTOGENERATED. DO NOT EDIT. - -import _ "embed" // Needed for go:embed - -//go:embed libddwaf-darwin-arm64.dylib.gz -var libddwaf []byte diff --git a/vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/lib_linux_amd64.go b/vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/lib_linux_amd64.go deleted file mode 100644 index 97d24c62..00000000 --- a/vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/lib_linux_amd64.go +++ /dev/null @@ -1,15 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -//go:build linux && amd64 && !go1.24 && !datadog.no_waf && (cgo || appsec) - -package lib - -// THIS FILE IS AUTOGENERATED. DO NOT EDIT. - -import _ "embed" // Needed for go:embed - -//go:embed libddwaf-linux-amd64.so.gz -var libddwaf []byte diff --git a/vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/lib_linux_arm64.go b/vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/lib_linux_arm64.go deleted file mode 100644 index 1f2e50af..00000000 --- a/vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/lib_linux_arm64.go +++ /dev/null @@ -1,15 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016-present Datadog, Inc. - -//go:build linux && arm64 && !go1.24 && !datadog.no_waf && (cgo || appsec) - -package lib - -// THIS FILE IS AUTOGENERATED. DO NOT EDIT. - -import _ "embed" // Needed for go:embed - -//go:embed libddwaf-linux-arm64.so.gz -var libddwaf []byte diff --git a/vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/libddwaf-darwin-amd64.dylib.gz b/vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/libddwaf-darwin-amd64.dylib.gz deleted file mode 100644 index 8c8a5bd8b1b23b9813814443b105eba1a9b6daa8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 706738 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 xy{o!D^3xnaVpK)K!*WVu6^;O2c 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�X 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%0DJ8IujWYfm|lLBQy};6n}d1r zA50}NWx0t^sEA6U3#%Hpf+R5ys~YDbNi4vs)?{5DfmN-+x;{ptK5-)Z4`VGyB)09% zrQ$RJ+ag#A&N<5>Ud!p+3%A^4ZCY#Rq+cQK54paHX76C!P)F1m`AwMK(&Ry6X?_FB z^)$fjG_cv>Sv~5E{2->c1mTV_%JqcVrTv)RvL9{@vs?G`c@<0ZTT!m3mEF;X=`C$= zM=QId%?ekTksqtQC5Dwy1JP#WH!$nUeEtpt}s9WkUw1khV4XNdu|rpILWx4yBmwpf?ddv!)igQ)Y{7}fV$`B@gdOG_+z6SYb( zUQMarUR5tqe}i69*aIc5DP)v*j>9Uy0O-2z!OHwEA*=Y9DxOpi;2$8jiX$J&s$fC_~l zWB1<5K};YQ?!sD58&*Ow$^8j>{C+#LHILb`(vq~xCPg+98a_?v&UnNM4(vcR zUqJBa$QV|d+a&rvRzB&%9q$(f(d<2tzbck)YxN*e+Q!z_4D0_^l$+Cxa!Z@r;D#XF z5P_fg|3Q>1HMg=mm;hnRub2OCxMP2Gc`qn97X+1@17K5t%uXz<`z}w@xO3tf_brzv zl=(D#*c636;XFu-r*>VQ=8vDo8<>^`hx^SBxmUlZ=lB0G-Jj2&&r5s$@BI0?o}OQq z{(N^}T2!5!nDIR={aTUWO4{L@Gwg7-!JwLGo3*q2c(_xDe$Zxee7(}z zVhEk1puZBOxj-uRhf&R$D4<^JLoPdQ61tu3>dcbftDpD(koPCxQB>LgID9+lPP#%u zRUkl6(4avR*Px(j1xZ6Xxh>U-3xYbhjDo0xAao;(fncX4MOn(IXk5^^FrtnEGZKRi z+7U?2-0cx(a%Ax2(M!il-k&_e#RSETnd75{x&Rpht)c^(%%bI%t4&r$V(R>x8rl3 z9i>EgD3Qo?hQEMkN6UoUXAqfe(^+6^3MadU?DklGb5#x>02w~Zg7bUQ1T$n3#*nFz ztOKw=XyJwBja04&v0QkE^b7o%`)hf??m88Q%=s~ z&e4)!xVIeAW7&p+JL(N8hU*%L^1QH=Nb%+?<>VzsJX^9wi)VvSwrqY-BX%@-9ZDEQ z>%Se_A)XC0-_iUR?`mwaIX?eISLu`6d_to1$wPrKIxJc;tmyp7@%b-4gZvlp&L*1w zf*0E4oE##-!9aQK1|#|!13@;>OI20nWk`N;tXa!_F+M8y1=UXjdK`qsU8)DT;lK}b zMpJqbzKhL(adC`1o;W@Z2Y#5nj(pqJ%yLpSoMu`I3~~
  • 36_X|$2QJ$XhtmTpjo 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

    $mcQ(9 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

    s%9)A735?cxE1gdovI_nCNbxnGs+6DNy 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"~K$1WxVN=A6}@8DlEg&QbR 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

    O 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 UB>w(?00030|FW`-*jRQQ0B#ZGMgRZ+ diff --git a/vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/libddwaf-darwin-arm64.dylib.gz b/vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/libddwaf-darwin-arm64.dylib.gz deleted file mode 100644 index eb3ce103df20820b0951a1ea5573cbdd792aeaa5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 651209 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%0A64K|eWg3#}pd+@kABp16f70rIU* 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 diff --git a/vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/libddwaf-linux-amd64.so.gz b/vendor/github.com/DataDog/go-libddwaf/v3/internal/lib/libddwaf-linux-amd64.so.gz deleted file mode 100644 index 4dd8d5f66ba0ca4904501ab4798310bd226dd47b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 880887 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

    PRKJPAl=JWn}yXydri#n*fgYvfX zz?JiM^8rtczaH?4i(06v6djJWunBMpOlipX$llwLuKmyCC>^zgSS5RFmx}RKYWWZ2KukT>M z@D%;Nlz#4}pD!_BxcKkx($0VPukQjX*K$2n-Am>A{O^$K6JB!7^^$9LAXKFdK;I9z zaM81UF|K=m2d>+_a832bg`g@J!0;o0;kyCodo0x>%p`goa{vi*eCRvLrSA-K-_-|@ z5X87+>IJ@ngMv}>z~Q^dZlWgTOOeD%b#)o zd@kv)7sfd2e@22betnB-{F?JKwx#nN+uE)nV_VyQc8_hTW$>O48SMP|%4P6ZFBu44 zGI-5P25bGu;3Y2^tfn$}J4g)awl7;tL;isr9p8DCnR=DH;q3zG(qPot< zar`;=vdj#NF$@miG9ZnDW@#F?NwD0JB(90=I4Pz{1ohpYC??jJG@?;PX%djccH&Lu z6KDg(G;*&otvW<8CV;qrYrr*4`*F~;y)a1{0dbDX+~4cmbBCFM!I)3p-@jmH&hnh+ zJo|ahb4~+3i9jC)e%juw(#o6wy0wk>)9p*Gh@Y?i_JR6$Q9#?=pZVL4Zbkeb)Zgst z-^W7G;w+VJry!~u#*c#^O5-1^ zxcK;j|8DiwI>5Uw+`8^nQwlu~hzdbNTSMTl_QL-={{GMpf2IBK_u2(o|HOyCqCotq zHB$)w*7d_*fr`HuhePoBWYQq#hKa$rTcYA_$slyJFa#c6`Vn||tREg`_QS&?{qSHO z1P>4O!^3114-?~p@sNAxAZKbrgYj^eiif)f!Gkdb9wz<>JVf=wLu5ZZu>J5LpAU@( zd_EWtSI-B_6dxXvb)oUV^^+@?S&E0t=Y#Rk#85o^^SmO5Cy};fF0y_;#QI|beS0); z{m0JJ^`GsPC;m484~NbNK{olg=UjmGg)v-|@2S zyt<0o(8~M&DorUdCj{2Y%{iXBL24ejR&cm`72xO3)4CSP=MXO!p_Wi@&imfQZ;J%% zVv*QR`a}V4O9iE-)zvS(j$}mZk{!I{b@Z=)AQvHfJ)3hb_gR|bxC?;K0nlG%LCn;^ z$|^)<`Tv|pJcQXSPoGz7(X(;l$@7Rea{koHG?9TCJ%GMP{p|n?)@!L??$i#3S%kUb~99b?{gH5Cai1vkUQHa1SY#KwyS=MjH#*~BRifX(8=)6sI- z5eGI)$}2DX^QkVZRq~e}JdgM!0DaRmuqP;UB#8R+h`+{ysA0{!div%tsB;VxbI&7Q zUN$Lc4l?&2{^3>TSvWCZo^y1b3?*jW>x<$X9bBOOeN9ZeFEIy0)>HEA6xe>K=&kYxP*G34vMacdymJz>V zkqBSG3KxrZXusQLY0rXMSq4EK0=TUR?3Yu)&VbFb@1pGJ8qVR}2x?q$9G2rKA2pmq zeDB&vh3>hJ2y!E(HM0MooI`vU;U}-`e1Y(-w_d5MnfGqJNh8aX2!H1e`>+e zv5nP>(Ev*Qkg9Li&R6nVzaV=MC)SYVXJTW2O{+#4gnO6DIH#^JOuR2qL}-D$E%tIr|6iHUP-K~t)M_|ke7tR1XYJhpj( zXZ9PTJjWt9JUbllF&&3zYXM(e55h$q;EPP0Qp0e|y_~RV3<$+Kz=dkvn-@aVD&qRd z(YXwjqjS$uIa;EQaayU_6DRhrohEe8H48o2jn$8yL;Aqa1Sg{z;5|9}g`R9AbkAjk z-nFdI+er5$?tM-uWVG%B0M^3wAQb8V=Pd$zaRlJUi2mt9y9i$1VmQ2vi4Usj_^WkM z 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 LR)`7I5>@b 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