diff --git a/.snyk b/.snyk index 98c5cf7f..7e121b51 100644 --- a/.snyk +++ b/.snyk @@ -33,7 +33,7 @@ ignore: SNYK-GOLANG-GOLANGORGXIMAGETIFF-7268348: - '*': reason: No fix available yet - expires: 2025-01-11T00:00:00.000Z + expires: 2025-03-01T00:00:00.000Z created: 2024-07-11T23:07:11.176Z SNYK-GOLANG-K8SIOCLIENTGOTRANSPORT-7538822: - '*': @@ -64,6 +64,13 @@ ignore: volume/volumeMount to their deployment expires: 2200-01-01T00:00:00.000Z created: 2024-07-23T00:43:23.074Z + SNYK-GOLANG-K8SIOAPIMACHINERYPKGUTILRUNTIME-8367153: + - '*': + reason: >- + When bumping this dependency to the recommended version several + critical vulnerabilities are introduced. Ignoring for 60 days. + expires: 2025-02-13T00:00:00.000Z + created: 2024-11-13T23:09:26.278Z SNYK-ALPINE320-OPENSSL-8235201: - '*': reason: >- @@ -71,11 +78,9 @@ ignore: temporarily until patch version is ready expires: 2024-11-30T00:00:00.000Z created: 2024-10-30T18:01:47.217Z - SNYK-GOLANG-K8SIOAPIMACHINERYPKGUTILRUNTIME-8367153: + SNYK-GOLANG-GITHUBCOMGOLANGJWTJWT-8341243: - '*': - reason: >- - Ignoring vulnerability for 30 days as newer versions of k8s.io - contain several critical vulnerabilities and are still in alpha - expires: 2025-01-01T00:00:00.000Z - created: 2024-11-13T23:30:00.999Z + reason: No fix available + expires: 2025-03-01T00:00:00.000Z + created: 2025-01-16T21:14:33.951Z patch: {} diff --git a/README.md b/README.md index b6994daa..8f4979c6 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ Cloudability Metrics Agent currently does not support Rancher or On Prem cluster | Environment Variable | Description | |------------------------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:| -| CLOUDABILITY_API_KEY | Required: Cloudability api key | +| CLOUDABILITY_API_KEY | Required/Optional: Cloudability api key. Optional only if using Custom S3 upload or Custom Azure blob upload. | | CLOUDABILITY_CLUSTER_NAME | Required: The cluster name to be used for the cluster the agent is running in. | | CLOUDABILITY_POLL_INTERVAL | Optional: The interval (Seconds) to poll metrics. Default: 180 | | CLOUDABILITY_OUTBOUND_PROXY | Optional: The URL of an outbound HTTP/HTTPS proxy for the agent to use (eg: http://x.x.x.x:8080). The URL must contain the scheme prefix (http:// or https://) | @@ -59,6 +59,11 @@ Cloudability Metrics Agent currently does not support Rancher or On Prem cluster | CLOUDABILITY_UPLOAD_REGION | Optional: The region the metrics-agent will upload data to. Default `us-west-2`. Supported values: `us-west-2`, `eu-central-1`, `ap-southeast-2`, `me-central-1`, `us-gov-west-1` | | CLOUDABILITY_CUSTOM_S3_BUCKET | Optional: A custom S3 bucket the metrics-agent will upload data to. If set, the metrics-agent will ONLY upload to this custom location. CLOUDABILITY_CUSTOM_S3_REGION is REQUIRED if this is set. | | CLOUDABILITY_CUSTOM_S3_REGION | Optional: The AWS region that the custom s3 bucket is in. This will initialize the correct region for the s3 client. CLOUDABILITY_CUSTOM_S3_BUCKET is REQUIRED if this is set. | +| CLOUDABILITY_CUSTOM_AZURE_BLOB_CONTAINER_NAME | Optional: A custom Azure blob container name the metrics-agent will upload data to. If set, the metrics-agent will ONLY upload to this custom location. | +| CLOUDABILITY_CUSTOM_AZURE_BLOB_URL | Optional: The Azure storage account's URL. This will be used to initialize the Azure client. | +| CLOUDABILITY_CUSTOM_AZURE_TENANT_ID | Optional: The Azure Service account's Tenant ID. This will be used to initialize the Azure client. All CUSTOM_AZURE ENV vars are REQUIRED if this is set | +| CLOUDABILITY_CUSTOM_AZURE_CLIENT_ID | Optional: The Azure Service account's Client ID. This will be used to initialize the Azure client. All CUSTOM_AZURE ENV vars are REQUIRED if this is set | +| CLOUDABILITY_CUSTOM_AZURE_CLIENT_SECRET | Optional: The Azure Service account's Client Secret. This will be used to initialize the Azure client. All CUSTOM_AZURE ENV vars are REQUIRED if this is set | ```sh @@ -90,6 +95,11 @@ Flags: --upload_region The region the metrics-agent will upload data to. (default `us-west-2`) --custom_s3_bucket string A custom S3 bucket the metrics-agent will upload data to. - Optional --custom_s3_region The AWS region that the custom s3 bucket is created. + --custom_azure_blob_container_name string A custom Azure blob container name the metrics-agent will upload data to. - Optional + --custom_azure_blob_url A custom Azure blob url metrics-agent uses to create the Azure client. - Optional + --custom_azure_tenant_id A custom Azure Service principal tenant id the metrics-agent uses to create the Azure client. - Optional + --custom_azure_client_id A custom Azure Service Principal client id the metrics-agent uses to create the Azure client. - Optional + --custom_azure_client_secret A custom Azure Service Principal client secret the metrics-agent uses to create the Azure client. - Optional Global Flags: --log_format string Format for log output (JSON,PLAIN) (default "PLAIN") --log_level string Log level to run the agent at (INFO,WARN,DEBUG) (default "INFO") diff --git a/charts/metrics-agent/Chart.yaml b/charts/metrics-agent/Chart.yaml index b982d0a2..c76816dc 100644 --- a/charts/metrics-agent/Chart.yaml +++ b/charts/metrics-agent/Chart.yaml @@ -14,8 +14,8 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. -version: 2.11.36 +version: 2.11.37 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. -appVersion: 2.11.36 \ No newline at end of file +appVersion: 2.11.37 diff --git a/charts/metrics-agent/values.yaml b/charts/metrics-agent/values.yaml index 5d5450f8..708d8d87 100644 --- a/charts/metrics-agent/values.yaml +++ b/charts/metrics-agent/values.yaml @@ -24,7 +24,7 @@ pollInterval: 180 image: name: cloudability/metrics-agent - tag: 2.11.36 + tag: 2.11.37 pullPolicy: Always imagePullSecrets: [] diff --git a/cmd/kubernetesCmd.go b/cmd/kubernetesCmd.go index 1dcb109a..86f33fc4 100644 --- a/cmd/kubernetesCmd.go +++ b/cmd/kubernetesCmd.go @@ -150,6 +150,36 @@ func init() { "", "The AWS region that the custom s3 bucket is in", ) + kubernetesCmd.PersistentFlags().StringVar( + &config.CustomAzureUploadBlobContainerName, + "custom_azure_blob_container_name", + "", + "The Azure blob container name the metrics-agent will upload data to.", + ) + kubernetesCmd.PersistentFlags().StringVar( + &config.CustomAzureBlobURL, + "custom_azure_blob_url", + "", + "The Azure blob url the metrics-agent will upload data to.", + ) + kubernetesCmd.PersistentFlags().StringVar( + &config.CustomAzureTenantID, + "custom_azure_tenant_id", + "", + "The Azure tenant id the metrics-agent uses when connecting to the azure blob.", + ) + kubernetesCmd.PersistentFlags().StringVar( + &config.CustomAzureClientID, + "custom_azure_client_id", + "", + "The Azure client id the metrics-agent uses when connecting to the azure blob.", + ) + kubernetesCmd.PersistentFlags().StringVar( + &config.CustomAzureClientSecret, + "custom_azure_client_secret", + "", + "The Azure client secret the metrics-agent uses when connecting to the azure blob.", + ) //nolint gas _ = viper.BindPFlag("api_key", kubernetesCmd.PersistentFlags().Lookup("api_key")) @@ -177,32 +207,43 @@ func init() { _ = viper.BindPFlag("upload_region", kubernetesCmd.PersistentFlags().Lookup("upload_region")) _ = viper.BindPFlag("custom_s3_bucket", kubernetesCmd.PersistentFlags().Lookup("custom_s3_bucket")) _ = viper.BindPFlag("custom_s3_region", kubernetesCmd.PersistentFlags().Lookup("custom_s3_region")) + _ = viper.BindPFlag("custom_azure_blob_container_name", kubernetesCmd.PersistentFlags().Lookup( + "custom_azure_blob_container_name")) + _ = viper.BindPFlag("custom_azure_blob_url", kubernetesCmd.PersistentFlags().Lookup("custom_azure_blob_url")) + _ = viper.BindPFlag("custom_azure_tenant_id", kubernetesCmd.PersistentFlags().Lookup("custom_azure_tenant_id")) + _ = viper.BindPFlag("custom_azure_client_id", kubernetesCmd.PersistentFlags().Lookup("custom_azure_client_id")) + _ = viper.BindPFlag("custom_azure_client_secret", kubernetesCmd.PersistentFlags().Lookup("custom_azure_client_secret")) viper.SetEnvPrefix("cloudability") viper.AutomaticEnv() RootCmd.AddCommand(kubernetesCmd) config = kubernetes.KubeAgentConfig{ - APIKey: viper.GetString("api_key"), - ClusterName: viper.GetString("cluster_name"), - PollInterval: viper.GetInt("poll_interval"), - CollectionRetryLimit: viper.GetUint("collection_retry_limit"), - OutboundProxy: viper.GetString("outbound_proxy"), - OutboundProxyAuth: viper.GetString("outbound_proxy_auth"), - OutboundProxyInsecure: viper.GetBool("outbound_proxy_insecure"), - Insecure: viper.GetBool("insecure"), - Cert: viper.GetString("certificate_file"), - Key: viper.GetString("key_file"), - ConcurrentPollers: viper.GetInt("number_of_concurrent_node_pollers"), - ForceKubeProxy: viper.GetBool("force_kube_proxy"), - Namespace: viper.GetString("namespace"), - ScratchDir: viper.GetString("scratch_dir"), - InformerResyncInterval: viper.GetInt("informer_resync_interval"), - ParseMetricData: viper.GetBool("parse_metric_data"), - HTTPSTimeout: viper.GetInt("https_client_timeout"), - UploadRegion: viper.GetString("upload_region"), - CustomS3UploadBucket: viper.GetString("custom_s3_bucket"), - CustomS3Region: viper.GetString("custom_s3_region"), + APIKey: viper.GetString("api_key"), + ClusterName: viper.GetString("cluster_name"), + PollInterval: viper.GetInt("poll_interval"), + CollectionRetryLimit: viper.GetUint("collection_retry_limit"), + OutboundProxy: viper.GetString("outbound_proxy"), + OutboundProxyAuth: viper.GetString("outbound_proxy_auth"), + OutboundProxyInsecure: viper.GetBool("outbound_proxy_insecure"), + Insecure: viper.GetBool("insecure"), + Cert: viper.GetString("certificate_file"), + Key: viper.GetString("key_file"), + ConcurrentPollers: viper.GetInt("number_of_concurrent_node_pollers"), + ForceKubeProxy: viper.GetBool("force_kube_proxy"), + Namespace: viper.GetString("namespace"), + ScratchDir: viper.GetString("scratch_dir"), + InformerResyncInterval: viper.GetInt("informer_resync_interval"), + ParseMetricData: viper.GetBool("parse_metric_data"), + HTTPSTimeout: viper.GetInt("https_client_timeout"), + UploadRegion: viper.GetString("upload_region"), + CustomS3UploadBucket: viper.GetString("custom_s3_bucket"), + CustomS3Region: viper.GetString("custom_s3_region"), + CustomAzureUploadBlobContainerName: viper.GetString("custom_azure_blob_container_name"), + CustomAzureBlobURL: viper.GetString("custom_azure_blob_url"), + CustomAzureTenantID: viper.GetString("custom_azure_tenant_id"), + CustomAzureClientID: viper.GetString("custom_azure_client_id"), + CustomAzureClientSecret: viper.GetString("custom_azure_client_secret"), } } diff --git a/go.mod b/go.mod index 58d0b2b0..11441494 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,9 @@ module github.com/cloudability/metrics-agent go 1.22 require ( + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.16.0 + github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0 + github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.5.0 github.com/aws/aws-sdk-go v1.40.27 github.com/google/cadvisor v0.48.1 github.com/googleapis/gnostic v0.5.5 @@ -21,6 +24,8 @@ require ( ) require ( + github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect + github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect github.com/BurntSushi/toml v1.2.1 // indirect github.com/alessio/shellescape v1.4.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect @@ -33,18 +38,20 @@ require ( github.com/go-openapi/jsonreference v0.20.1 // indirect github.com/go-openapi/swag v0.22.3 // indirect github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang-jwt/jwt/v5 v5.2.1 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/google/gnostic v0.6.9 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/safetext v0.0.0-20220905092116-b49f7bc46da2 // indirect - github.com/google/uuid v1.3.0 // indirect + github.com/google/uuid v1.6.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/imdario/mergo v0.3.13 // indirect github.com/inconshreveable/mousetrap v1.0.1 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/kylelemons/godebug v1.1.0 // indirect github.com/magiconair/properties v1.8.6 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-isatty v0.0.16 // indirect @@ -56,6 +63,7 @@ require ( github.com/nxadm/tail v1.4.8 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.0.5 // indirect + github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/pkg/errors v0.9.1 // indirect github.com/prometheus/client_model v0.3.0 // indirect github.com/spf13/afero v1.9.2 // indirect @@ -63,7 +71,8 @@ require ( github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/subosito/gotenv v1.4.1 // indirect - golang.org/x/net v0.25.0 // indirect + golang.org/x/crypto v0.31.0 // indirect + golang.org/x/net v0.33.0 // indirect golang.org/x/oauth2 v0.7.0 // indirect golang.org/x/sys v0.28.0 // indirect golang.org/x/term v0.27.0 // indirect @@ -94,7 +103,7 @@ replace ( github.com/opencontainers/runc => github.com/opencontainers/runc v1.1.14 golang.org/x/crypto => golang.org/x/crypto v0.31.0 golang.org/x/image => golang.org/x/image v0.10.0 - golang.org/x/net => golang.org/x/net v0.23.0 + golang.org/x/net => golang.org/x/net v0.33.0 google.golang.org/grpc => google.golang.org/grpc v1.56.3 google.golang.org/protobuf => google.golang.org/protobuf v1.33.0 ) diff --git a/go.sum b/go.sum index 9892573f..5c321a70 100644 --- a/go.sum +++ b/go.sum @@ -593,6 +593,22 @@ cloud.google.com/go/workflows v1.10.0/go.mod h1:fZ8LmRmZQWacon9UCX1r/g/DfAXx5VcP dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8= git.sr.ht/~sbinet/gg v0.3.1/go.mod h1:KGYtlADtqsqANL9ueOFkWymvzUvLMQllU5Ixo+8v3pc= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.16.0 h1:JZg6HRh6W6U4OLl6lk7BZ7BLisIzM9dG1R50zUk9C/M= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.16.0/go.mod h1:YL1xnZ6QejvQHWJrX/AvhFl4WW4rqHVoKspWNVwFk0M= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0 h1:B/dfvscEQtew9dVuoxqxrUKKv8Ih2f55PydknDamU+g= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0/go.mod h1:fiPSssYvltE08HJchL04dOy+RD4hgrjph0cwGGMntdI= +github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.0 h1:+m0M/LFxN43KvULkDNfdXOgrjtg6UYJPFBJyuEcRCAw= +github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.0/go.mod h1:PwOyop78lveYMRs6oCxjiVyBdyCgIYH6XHIVZO9/SFQ= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 h1:ywEEhmNahHBihViHepv3xPBn1663uRv2t2q/ESv9seY= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0/go.mod h1:iZDifYGJTIgIIkYRNWPENUnqx6bJ2xnSDFI2tjwZNuY= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.6.0 h1:PiSrjRPpkQNjrM8H0WwKMnZUdu1RGMtd/LdGKUrOo+c= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.6.0/go.mod h1:oDrbWx4ewMylP7xHivfgixbfGBT6APAwsSoHRKotnIc= +github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.5.0 h1:mlmW46Q0B79I+Aj4azKC6xDMFN9a9SyZWESlGWYXbFs= +github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.5.0/go.mod h1:PXe2h+LKcWTX9afWdZoHyODqR4fBa5boUM/8uJfZ0Jo= +github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1 h1:WJTmL004Abzc5wDB5VtZG2PJk5ndYDgVacGqfirKxjM= +github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1/go.mod h1:tCcJZ0uHAmvjsVYzEFivsRTN00oz5BEsRgQHu5JZ9WE= +github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 h1:XHOnouVk1mxXfQidrMEnLlPk9UMeRtyBTnEFtxkV0kU= +github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.0.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= @@ -627,6 +643,8 @@ github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0/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/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= @@ -644,6 +662,8 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +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/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/emicklei/go-restful/v3 v3.10.0 h1:X4gma4HM7hFm6WMeAsTfqA0GOfdNoCzBIkHGoRLGXuM= @@ -701,6 +721,8 @@ github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MG 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/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= +github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= @@ -784,8 +806,9 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4 github.com/google/safetext v0.0.0-20220905092116-b49f7bc46da2 h1:SJ+NtwL6QaZ21U+IrK7d0gGgpjGGvd2kz+FzTHVzdqI= github.com/google/safetext v0.0.0-20220905092116-b49f7bc46da2/go.mod h1:Tv1PlzqC9t8wNnpPdctvtSUOPUUg4SHeE6vR1Ir2hmg= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/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.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= @@ -838,6 +861,8 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= +github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6 h1:IsMZxCuZqKuao2vNdfD82fjjgPLfyHLpR41Z88viRWs= +github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6/go.mod h1:3VeWNIJaW+O5xpRQbPp0Ybqu1vJd/pm7s2F473HRrkw= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/asmfmt v1.3.2/go.mod h1:AG8TuvYojzulgDAMCnYn50l/5QV3Bs/tp6j0HLHbNSE= @@ -850,12 +875,15 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= github.com/lyft/protoc-gen-star v0.6.1/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= github.com/lyft/protoc-gen-star/v2 v2.0.1/go.mod h1:RcCdONR2ScXaYnQC5tUzxzlpA3WVYF7/opLeUgcQs/o= @@ -907,6 +935,8 @@ github.com/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2 github.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= github.com/phpdave11/gofpdi v1.0.13/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= +github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -933,13 +963,15 @@ github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/prom2json v1.3.0 h1:BlqrtbT9lLH3ZsOVhXPsHzFrApCTKRifB7gjJuypu6Y= github.com/prometheus/prom2json v1.3.0/go.mod h1:rMN7m0ApCowcoDlypBHlkNbp5eJQf/+1isKykIP5ZnM= +github.com/redis/go-redis/v9 v9.6.1 h1:HHDteefn6ZkTtY5fGUE8tj8uy85AHk6zP7CpzIAM0y4= +github.com/redis/go-redis/v9 v9.6.1/go.mod h1:0C0c6ycQsdpVNQpxb1njEQIqkx5UcsM8FJCQLgE9+RA= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w= github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245/go.mod h1:pQAZKsJ8yyVxGRWYNEm9oFB8ieLgKFnamEyDmSA0BRk= @@ -976,8 +1008,9 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 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.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs= github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= @@ -1003,6 +1036,7 @@ go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1051,8 +1085,8 @@ golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 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/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1171,6 +1205,7 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1178,12 +1213,10 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.18.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 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1202,7 +1235,6 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/kubernetes/kubernetes.go b/kubernetes/kubernetes.go index 4cb46f43..cbf38362 100644 --- a/kubernetes/kubernetes.go +++ b/kubernetes/kubernetes.go @@ -10,6 +10,9 @@ import ( "encoding/json" "errors" "fmt" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/aws/aws-sdk-go/aws" "io" "net/http" "net/url" @@ -21,7 +24,8 @@ import ( "strings" "time" - "github.com/aws/aws-sdk-go/aws" + "github.com/Azure/azure-sdk-for-go/sdk/azidentity" + "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/s3" "github.com/aws/aws-sdk-go/service/s3/s3manager" @@ -49,46 +53,51 @@ type ClusterVersion struct { // KubeAgentConfig K8s agent configuration type KubeAgentConfig struct { - APIKey string - BearerToken string - BearerTokenPath string - Cert string - ClusterName string - ClusterHostURL string - clusterUID string - HeapsterURL string - Key string - OutboundProxyAuth string - OutboundProxy string - provisioningID string - ForceKubeProxy bool - Insecure bool - OutboundProxyInsecure bool - UseInClusterConfig bool - PollInterval int - ConcurrentPollers int - CollectionRetryLimit uint - failedNodeList map[string]error - AgentStartTime time.Time - Clientset kubernetes.Interface - ClusterVersion ClusterVersion - HeapsterProxyURL url.URL - OutboundProxyURL url.URL - HTTPClient http.Client - NodeClient raw.Client - InClusterClient raw.Client - msExportDirectory *os.File - TLSClientConfig rest.TLSClientConfig - Namespace string - ScratchDir string - NodeMetrics EndpointMask - Informers map[string]*cache.SharedIndexInformer - InformerResyncInterval int - ParseMetricData bool - HTTPSTimeout int - UploadRegion string - CustomS3UploadBucket string - CustomS3Region string + APIKey string + BearerToken string + BearerTokenPath string + Cert string + ClusterName string + ClusterHostURL string + clusterUID string + HeapsterURL string + Key string + OutboundProxyAuth string + OutboundProxy string + provisioningID string + ForceKubeProxy bool + Insecure bool + OutboundProxyInsecure bool + UseInClusterConfig bool + PollInterval int + ConcurrentPollers int + CollectionRetryLimit uint + failedNodeList map[string]error + AgentStartTime time.Time + Clientset kubernetes.Interface + ClusterVersion ClusterVersion + HeapsterProxyURL url.URL + OutboundProxyURL url.URL + HTTPClient http.Client + NodeClient raw.Client + InClusterClient raw.Client + msExportDirectory *os.File + TLSClientConfig rest.TLSClientConfig + Namespace string + ScratchDir string + NodeMetrics EndpointMask + Informers map[string]*cache.SharedIndexInformer + InformerResyncInterval int + ParseMetricData bool + HTTPSTimeout int + UploadRegion string + CustomS3UploadBucket string + CustomS3Region string + CustomAzureUploadBlobContainerName string + CustomAzureBlobURL string + CustomAzureTenantID string + CustomAzureClientID string + CustomAzureClientSecret string } const uploadInterval time.Duration = 10 @@ -96,6 +105,11 @@ const retryCount uint = 10 const DefaultCollectionRetry = 1 const DefaultInformerResync = 24 +const ( + azureProvider = "azure" + awsProvider = "aws" +) + // node connection methods const proxy = "proxy" const direct = "direct" @@ -134,8 +148,7 @@ func CollectKubeMetrics(config KubeAgentConfig) { // Create k8s agent kubeAgent := newKubeAgent(ctx, config) - - customS3Mode := isCustomS3UploadEnvsSet(&kubeAgent) + customMode, agentProvider := isCustomUploadEnvsSet(&kubeAgent) // Log start time kubeAgent.AgentStartTime = time.Now() @@ -174,12 +187,14 @@ func CollectKubeMetrics(config KubeAgentConfig) { log.Warnf("Warning: Non-fatal error occurred retrieving baseline metrics: %s", err) } - if !customS3Mode { + if !customMode { err = performConnectionChecks(&kubeAgent) if err != nil { log.Warnf("WARNING: failed to retrieve S3 URL in connectivity test, agent will fail to "+ "upload metrics to Cloudability with error: %v", err) } + } else { + performCustomUploadTestConnection(&kubeAgent, agentProvider) } log.Info("Cloudability Metrics Agent successfully started.") @@ -201,7 +216,7 @@ func CollectKubeMetrics(config KubeAgentConfig) { } } // Send metric sample - kubeAgent.sendMetricsBasedOnUploadMode(customS3Mode, metricSample) + kubeAgent.sendMetricsBasedOnUploadMode(ctx, agentProvider, metricSample) case <-pollChan.C: err := kubeAgent.collectMetrics(ctx, kubeAgent, kubeAgent.Clientset, clientSetNodeSource) @@ -217,14 +232,28 @@ func CollectKubeMetrics(config KubeAgentConfig) { } +// isCustomUploadEnvsSet checks the KubeAgentConfig for custom upload ENVs and returns true/false and the provider mode +// Currently supported: AWS and Azure, the goal is to add more support with this function later +func isCustomUploadEnvsSet(ka *KubeAgentConfig) (bool, string) { + if ka.APIKey == "" { + isCustomS3Upload := isCustomS3UploadEnvsSet(ka) + if isCustomS3Upload { + return isCustomS3Upload, awsProvider + } + isCustomBlobUpload := isCustomAzureUploadEnvsSet(ka) + if isCustomBlobUpload { + return isCustomBlobUpload, azureProvider + } + log.Fatalf("Invalid agent configuration. CLOUDABILITY_API_KEY is required " + + "when not using CLOUDABILITY_CUSTOM_S3 or CLOUDABILITY_CUSTOM_AZURE_BLOB env vars.") + } + return false, "" +} + // isCustomS3UploadEnvsSet checks to see if the agent has a custom S3 location and S3 region to upload to // if both these variables are not set, default upload to Apptio S3 func isCustomS3UploadEnvsSet(ka *KubeAgentConfig) bool { if ka.CustomS3Region == "" && ka.CustomS3UploadBucket == "" { - if ka.APIKey == "" { - log.Fatalf("Invalid agent configuration. CLOUDABILITY_API_KEY is required " + - "when not using CLOUDABILITY_CUSTOM_S3_BUCKET & CLOUDABILITY_CUSTOM_S3_REGION") - } return false } if ka.CustomS3UploadBucket == "" || ka.CustomS3Region == "" { @@ -237,8 +266,24 @@ func isCustomS3UploadEnvsSet(ka *KubeAgentConfig) bool { return true } -func performConnectionChecks(ka *KubeAgentConfig) error { +// isCustomAzureUploadEnvsSet checks to see if the agent has custom Azure credentials needed for uploads +// if these vars are found, set the env vars needed for the azure client. If not set, default upload to Apptio S3 +func isCustomAzureUploadEnvsSet(ka *KubeAgentConfig) bool { + if ka.CustomAzureUploadBlobContainerName == "" && ka.CustomAzureBlobURL == "" && ka.CustomAzureClientID == "" && + ka.CustomAzureClientSecret == "" && ka.CustomAzureTenantID == "" { + return false + } + if ka.CustomAzureUploadBlobContainerName == "" || ka.CustomAzureBlobURL == "" { + log.Fatalf("Invalid agent configuration. CLOUDABILITY_CUSTOM_AZURE_BLOB_CONTAINER_NAME is set to %s. "+ + "CLOUDABILITY_CUSTOM_AZURE_BLOB_URL is set to %s.", ka.CustomAzureUploadBlobContainerName, + ka.CustomAzureBlobURL) + } + log.Infof("Detected custom Azure blob configuration, "+ + "Will upload collected metrics to %s", ka.CustomAzureUploadBlobContainerName) + return true +} +func performConnectionChecks(ka *KubeAgentConfig) error { log.Info("Performing connectivity checks. Checking that the agent can retrieve S3 URL") cldyMetricClient, err := client.NewHTTPMetricClient(client.Configuration{ @@ -275,6 +320,27 @@ func performConnectionChecks(ka *KubeAgentConfig) error { return nil } +func performCustomUploadTestConnection(ka *KubeAgentConfig, provider string) { + log.Info("Performing Performing connectivity checks for custom upload.") + if provider == azureProvider { + azureTestConnection(ka) + } else { + log.Info("Checking that the agent can start aws client using custom s3" + + " configuration.") + ka.customS3AWSClient() + } +} + +func azureTestConnection(ka *KubeAgentConfig) { + if ka.CustomAzureTenantID == "" && ka.CustomAzureClientID == "" { + log.Info("Checking that the agent can start azure client using managed identity.") + ka.customBlobManagedIdentityClient() + } else { + log.Info("Checking that the agent can start azure client using service principal.") + ka.customBlobServicePrincipalClient() + } +} + func newKubeAgent(ctx context.Context, config KubeAgentConfig) KubeAgentConfig { config, err := createClusterConfig(config) if err != nil { @@ -443,17 +509,31 @@ func (ka KubeAgentConfig) sendMetrics(metricSample *os.File) { } } -func (ka KubeAgentConfig) sendMetricsBasedOnUploadMode(customS3Mode bool, metricSample *os.File) { - if customS3Mode { +// sendMetricsBasedOnUploadMode checks the agentProvider for a custom upload config. If none are found it will use the +// default upload mode. This will allow for more custom provider upload options in the future. +func (ka KubeAgentConfig) sendMetricsBasedOnUploadMode(ctx context.Context, agentProvider string, + metricSample *os.File) { + switch agentProvider { + case awsProvider: log.Infof("Uploading Metrics to Custom S3 Bucket %s", ka.CustomS3UploadBucket) go ka.sendMetricsToCustomS3(metricSample) - } else { + case azureProvider: + if ka.CustomAzureTenantID == "" && ka.CustomAzureClientID == "" { + log.Infof("Uploading Metrics to Custom Azure Blob %s with managed identity", + ka.CustomAzureUploadBlobContainerName) + go ka.sendMetricsToCustomBlobManagedIdentity(ctx, metricSample) + } else { + log.Infof("Uploading Metrics to Custom Azure Blob %s", ka.CustomAzureUploadBlobContainerName) + go ka.sendMetricsToCustomBlob(ctx, metricSample) + } + + default: log.Info("Uploading Metrics") go ka.sendMetrics(metricSample) } } -func (ka KubeAgentConfig) sendMetricsToCustomS3(metricSample *os.File) { +func (ka KubeAgentConfig) customS3AWSClient() *session.Session { sess, err := session.NewSession(&aws.Config{ Region: aws.String(ka.CustomS3Region), MaxRetries: aws.Int(3)}, @@ -462,6 +542,11 @@ func (ka KubeAgentConfig) sendMetricsToCustomS3(metricSample *os.File) { log.Fatalf("Could not establish AWS Session, "+ "ensure AWS environment variables are set correctly: %s", err) } + return sess +} + +func (ka KubeAgentConfig) sendMetricsToCustomS3(metricSample *os.File) { + sess := ka.customS3AWSClient() svc := s3.New(sess) uploader := s3manager.NewUploaderWithClient(svc) @@ -469,9 +554,7 @@ func (ka KubeAgentConfig) sendMetricsToCustomS3(metricSample *os.File) { if err != nil { log.Fatalf("Unable to open metric sample file %v", err) } - defer fileReader.Close() - - key := generateSampleKey(ka.clusterUID) + key := generateSampleKey(ka.clusterUID, awsProvider) sampleToUpload := &s3manager.UploadInput{ Bucket: aws.String(ka.CustomS3UploadBucket), Key: aws.String(key), @@ -486,21 +569,87 @@ func (ka KubeAgentConfig) sendMetricsToCustomS3(metricSample *os.File) { log.Infof("Exported metric sample %s to custom S3 bucket: %s", strings.TrimSuffix(sn[len(sn)-1], ".tgz"), ka.CustomS3UploadBucket) } - err = os.Remove(metricSample.Name()) + util.SafeCloseLogger(fileReader) +} + +func (ka KubeAgentConfig) customBlobServicePrincipalClient() *azblob.Client { + cred, err := azidentity.NewClientSecretCredential(ka.CustomAzureTenantID, ka.CustomAzureClientID, + ka.CustomAzureClientSecret, nil) + if err != nil { + log.Fatalf("Could not establish Azure credentials, "+ + "ensure all Azure environment variables are set correctly: %s", err) + } + retryConfig := azblob.ClientOptions{ + ClientOptions: azcore.ClientOptions{ + Retry: policy.RetryOptions{ + MaxRetries: 3, + }, + }, + } + azureClient, err := azblob.NewClient(ka.CustomAzureBlobURL, cred, &retryConfig) + if err != nil { + log.Fatalf("Could not establish Azure Client, "+ + "ensure all Azure environment variables are set correctly: %s", err) + } + return azureClient +} + +func (ka KubeAgentConfig) sendMetricsToCustomBlob(ctx context.Context, metricSample *os.File) { + azureClient := ka.customBlobServicePrincipalClient() + ka.uploadBlob(ctx, azureClient, metricSample) +} + +func (ka KubeAgentConfig) customBlobManagedIdentityClient() *azblob.Client { + cred, err := azidentity.NewDefaultAzureCredential(nil) + if err != nil { + log.Fatalf("Could not establish Azure credentials with managed identity, "+ + "ensure Azure environment variables are set correctly: %s", err) + } + azureClient, err := azblob.NewClient(ka.CustomAzureBlobURL, cred, nil) if err != nil { - log.Warnf("Warning: Unable to cleanup after metric sample upload: %v", err) + log.Fatalf("Could not establish Azure Client with managed identity, "+ + "ensure Azure environment variables are set correctly: %s", err) } + return azureClient } -// generateSampleKey creates a key (location) for s3 to upload the sample to. Example of s3 location format +func (ka KubeAgentConfig) sendMetricsToCustomBlobManagedIdentity(ctx context.Context, metricSample *os.File) { + azureClient := ka.customBlobManagedIdentityClient() + ka.uploadBlob(ctx, azureClient, metricSample) +} + +func (ka KubeAgentConfig) uploadBlob(ctx context.Context, client *azblob.Client, metricSample *os.File) { + file, err := os.Open(metricSample.Name()) + if err != nil { + log.Fatalf("Unable to open metric sample file %v", err) + } + key := generateSampleKey(ka.clusterUID, azureProvider) + _, err = client.UploadFile(ctx, ka.CustomAzureUploadBlobContainerName, key, file, nil) + if err != nil { + log.Fatalf("Failed to put Object to custom Azure blob with error: %s", err) + } + + sn := strings.Split(metricSample.Name(), "/") + log.Infof("Exported metric sample %s to custom Azure blob: %s", + strings.TrimSuffix(sn[len(sn)-1], ".tgz"), ka.CustomAzureUploadBlobContainerName) + util.SafeCloseLogger(file) +} + +// generateSampleKey creates a key (location) for s3 or azure to upload the sample to. Example of s3 location format // /production/data/metrics-agent///
//---.tgz -func generateSampleKey(clusterUID string) string { - currentTime := time.Now() +// example of azure location format +// production/data/metrics-agent///
//---.tgz +func generateSampleKey(clusterUID, provider string) string { + currentTime := time.Now().UTC() year, month, day := currentTime.Date() hour := currentTime.Hour() minute := currentTime.Minute() - return fmt.Sprintf("/production/data/metrics-agent/%d/%02d/%02d/%s/%s-%s-%02d-%02d.tgz", year, + key := fmt.Sprintf("production/data/metrics-agent/%d/%02d/%02d/%s/%s-%s-%02d-%02d.tgz", year, int(month), day, clusterUID, clusterUID, currentTime.Format("20060102"), hour, minute) + if provider == azureProvider { + return key + } + return "/" + key } func handleError(err error, region string) string { @@ -833,6 +982,7 @@ func createAgentStatusMetric(workDir *os.File, config KubeAgentConfig, sampleSta m.Values["upload_region"] = config.UploadRegion m.Values["custom_s3_bucket"] = config.CustomS3UploadBucket m.Values["custom_s3_region"] = config.CustomS3Region + m.Values["custom_azure_blob_container_name"] = config.CustomAzureUploadBlobContainerName if len(config.OutboundProxyAuth) > 0 { m.Values["outbound_proxy_auth"] = "true" } else { diff --git a/util/util.go b/util/util.go index 36ba613d..cd846e64 100644 --- a/util/util.go +++ b/util/util.go @@ -288,6 +288,18 @@ func SafeClose(closer func() error, err *error) { } } +// SafeCloseLogger takes a file and closes then removes it. Used for custom agent uploads +func SafeCloseLogger(file *os.File) { + err := file.Close() + if err != nil { + log.Warnf("Warning: Unable to close metric sample: %v", err) + } + err = os.Remove(file.Name()) + if err != nil { + log.Warnf("Warning: Unable to cleanup after metric sample upload: %v", err) + } +} + // MatchOneFile returns the name of one file based on a given directory and pattern // returning an error if more or less than one match is found. The syntax of patterns is the same // as in filepath.Glob & Match. diff --git a/version/version.go b/version/version.go index 0df8b9bb..2fbc28b5 100644 --- a/version/version.go +++ b/version/version.go @@ -1,4 +1,4 @@ package version // VERSION is the current version of the agent -var VERSION = "2.11.36" +var VERSION = "2.11.37"