From 4a172fae97f4927ed80bb437021f453d871033be Mon Sep 17 00:00:00 2001 From: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com> Date: Wed, 14 Jun 2023 12:36:48 -0700 Subject: [PATCH] Pass Client IP address to MinIO on x-forwarded-for header (#2864) --- cluster/cluster.go | 76 ------------- cluster/config.go | 83 -------------- cluster/const.go | 23 ---- cmd/console/app_commands.go | 5 +- go.mod | 39 +------ go.sum | 102 +----------------- pkg/utils/utils.go | 12 +++ restapi/admin_arns.go | 2 +- restapi/admin_config.go | 12 +-- restapi/admin_groups.go | 10 +- restapi/admin_health_info.go | 8 +- restapi/admin_idp.go | 12 +-- restapi/admin_info.go | 23 ++-- restapi/admin_info_test.go | 6 +- restapi/admin_inspect.go | 2 +- restapi/admin_kms.go | 38 +++---- restapi/admin_nodes.go | 2 +- restapi/admin_notification_endpoints.go | 4 +- restapi/admin_policies.go | 32 +++--- restapi/admin_releases.go | 10 +- restapi/admin_remote_buckets.go | 53 +++++---- restapi/admin_remote_buckets_test.go | 7 +- restapi/admin_replication_status.go | 2 +- restapi/admin_service.go | 2 +- restapi/admin_site_replication.go | 8 +- restapi/admin_subnet.go | 28 ++--- restapi/admin_tiers.go | 8 +- restapi/admin_users.go | 20 ++-- restapi/client-admin.go | 73 +++++++------ restapi/client.go | 25 ++--- restapi/configure_console.go | 9 +- restapi/consts.go | 1 + restapi/license.go | 2 +- ...counts.go => service_accounts_handlers.go} | 19 ++-- ...t.go => service_accounts_handlers_test.go} | 0 restapi/tls.go | 23 +++- restapi/user_account.go | 6 +- restapi/user_bucket_quota.go | 4 +- restapi/user_buckets.go | 50 ++++----- restapi/user_buckets_events.go | 6 +- restapi/user_buckets_lifecycle.go | 10 +- restapi/user_buckets_test.go | 6 +- restapi/user_log_search.go | 6 +- restapi/user_log_search_test.go | 2 +- restapi/user_login.go | 12 ++- restapi/user_objects.go | 29 ++--- restapi/user_session.go | 3 +- restapi/user_session_test.go | 4 +- restapi/user_support.go | 4 +- restapi/user_version.go | 2 +- restapi/ws_handle.go | 39 +++++-- restapi/ws_handle_test.go | 4 + restapi/ws_objects.go | 4 +- 53 files changed, 382 insertions(+), 590 deletions(-) delete mode 100644 cluster/cluster.go delete mode 100644 cluster/config.go delete mode 100644 cluster/const.go rename restapi/{user_service_accounts.go => service_accounts_handlers.go} (96%) rename restapi/{user_service_accounts_test.go => service_accounts_handlers_test.go} (100%) diff --git a/cluster/cluster.go b/cluster/cluster.go deleted file mode 100644 index 00d7f94e2..000000000 --- a/cluster/cluster.go +++ /dev/null @@ -1,76 +0,0 @@ -// This file is part of MinIO Console Server -// Copyright (c) 2021 MinIO, Inc. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package cluster - -import ( - directpvclient "github.com/minio/directpv/pkg/client" - operator "github.com/minio/operator/pkg/client/clientset/versioned" - "k8s.io/client-go/kubernetes" - "k8s.io/client-go/rest" - certutil "k8s.io/client-go/util/cert" -) - -// getTLSClientConfig will return the right TLS configuration for the K8S client based on the configured TLS certificate -func getTLSClientConfig() rest.TLSClientConfig { - defaultRootCAFile := "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt" - customRootCAFile := getK8sAPIServerTLSRootCA() - tlsClientConfig := rest.TLSClientConfig{} - // if console is running inside k8s by default he will have access to the CA Cert from the k8s local authority - if _, err := certutil.NewPool(defaultRootCAFile); err == nil { - tlsClientConfig.CAFile = defaultRootCAFile - } - // if the user explicitly define a custom CA certificate, instead, we will use that - if customRootCAFile != "" { - if _, err := certutil.NewPool(customRootCAFile); err == nil { - tlsClientConfig.CAFile = customRootCAFile - } - } - return tlsClientConfig -} - -// This operation will run only once at console startup -var tlsClientConfig = getTLSClientConfig() - -func GetK8sConfig(token string) *rest.Config { - config := &rest.Config{ - Host: GetK8sAPIServer(), - TLSClientConfig: tlsClientConfig, - APIPath: "/", - BearerToken: token, - } - return config -} - -// OperatorClient returns an operator client using GetK8sConfig for its config -func OperatorClient(token string) (*operator.Clientset, error) { - return operator.NewForConfig(GetK8sConfig(token)) -} - -// K8sClient returns kubernetes client using GetK8sConfig for its config -func K8sClient(token string) (*kubernetes.Clientset, error) { - return kubernetes.NewForConfig(GetK8sConfig(token)) -} - -// DirectPV interfaces required to fetch information - -func DirectPVDriveInterface(token string) (*directpvclient.DirectCSIDriveInterface, error) { - return directpvclient.DirectCSIDriveInterfaceForConfig(GetK8sConfig(token)) -} - -func DirectPVVolumeInterface(token string) (*directpvclient.DirectCSIVolumeInterface, error) { - return directpvclient.DirectCSIVolumeInterfaceForConfig(GetK8sConfig(token)) -} diff --git a/cluster/config.go b/cluster/config.go deleted file mode 100644 index edd155b25..000000000 --- a/cluster/config.go +++ /dev/null @@ -1,83 +0,0 @@ -// This file is part of MinIO Console Server -// Copyright (c) 2021 MinIO, Inc. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package cluster - -import ( - "io/ioutil" - "net" - "strings" - "time" - - xhttp "github.com/minio/console/pkg/http" - "github.com/minio/console/restapi" - - "github.com/minio/console/pkg/utils" - - "github.com/minio/pkg/env" -) - -func GetK8sAPIServer() string { - // if console is running inside a k8s pod KUBERNETES_SERVICE_HOST and KUBERNETES_SERVICE_PORT will contain the k8s api server apiServerAddress - // if console is not running inside k8s by default will look for the k8s api server on localhost:8001 (kubectl proxy) - // NOTE: using kubectl proxy is for local development only, since every request send to localhost:8001 will bypass service account authentication - // more info here: https://kubernetes.io/docs/tasks/access-application-cluster/access-cluster/#directly-accessing-the-rest-api - // you can override this using CONSOLE_K8S_API_SERVER, ie use the k8s cluster from `kubectl config view` - host, port := env.Get("KUBERNETES_SERVICE_HOST", ""), env.Get("KUBERNETES_SERVICE_PORT", "") - apiServerAddress := "http://localhost:8001" - if host != "" && port != "" { - apiServerAddress = "https://" + net.JoinHostPort(host, port) - } - return env.Get(ConsoleK8sAPIServer, apiServerAddress) -} - -// If CONSOLE_K8S_API_SERVER_TLS_ROOT_CA is true console will load the certificate into the -// http.client rootCAs pool, this is useful for testing an k8s ApiServer or when working with self-signed certificates -func getK8sAPIServerTLSRootCA() string { - return strings.TrimSpace(env.Get(ConsoleK8SAPIServerTLSRootCA, "")) -} - -// GetNsFromFile assumes console is running inside a k8s pod and extract the current namespace from the -// /var/run/secrets/kubernetes.io/serviceaccount/namespace file -func GetNsFromFile() string { - dat, err := ioutil.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/namespace") - if err != nil { - return "default" - } - return string(dat) -} - -// GetMinioImage returns the image URL to be used when deploying a MinIO instance, if there is -// a preferred image to be used (configured via ENVIRONMENT VARIABLES) GetMinioImage will return that -// if not, GetMinioImage will try to obtain the image URL for the latest version of MinIO and return that -func GetMinioImage() (*string, error) { - image := strings.TrimSpace(env.Get(ConsoleMinioImage, "")) - // if there is a preferred image configured by the user we'll always return that - if image != "" { - return &image, nil - } - client := restapi.GetConsoleHTTPClient("") - client.Timeout = 5 * time.Second - latestMinIOImage, errLatestMinIOImage := utils.GetLatestMinIOImage( - &xhttp.Client{ - Client: client, - }) - - if errLatestMinIOImage != nil { - return nil, errLatestMinIOImage - } - return latestMinIOImage, nil -} diff --git a/cluster/const.go b/cluster/const.go deleted file mode 100644 index b0f82bf0b..000000000 --- a/cluster/const.go +++ /dev/null @@ -1,23 +0,0 @@ -// This file is part of MinIO Console Server -// Copyright (c) 2021 MinIO, Inc. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package cluster - -const ( - ConsoleK8sAPIServer = "CONSOLE_K8S_API_SERVER" - ConsoleK8SAPIServerTLSRootCA = "CONSOLE_K8S_API_SERVER_TLS_ROOT_CA" - ConsoleMinioImage = "CONSOLE_MINIO_IMAGE" -) diff --git a/cmd/console/app_commands.go b/cmd/console/app_commands.go index 459c5f045..cacd728a0 100644 --- a/cmd/console/app_commands.go +++ b/cmd/console/app_commands.go @@ -41,8 +41,9 @@ func StartServer(ctx *cli.Context) error { } xctx := context.Background() - transport := restapi.PrepareSTSClientTransport(false) - if err := logger.InitializeLogger(xctx, transport); err != nil { + + transport := restapi.PrepareSTSClientTransport(false, restapi.LocalAddress) + if err := logger.InitializeLogger(xctx, transport.Transport); err != nil { fmt.Println("error InitializeLogger", err) logger.CriticalIf(xctx, err) } diff --git a/go.mod b/go.mod index d6afd8881..0bc05f2c9 100644 --- a/go.mod +++ b/go.mod @@ -19,13 +19,11 @@ require ( github.com/jessevdk/go-flags v1.5.0 github.com/klauspost/compress v1.16.5 github.com/minio/cli v1.24.2 - github.com/minio/directpv v1.4.4-0.20220805090942-948ca4731651 github.com/minio/highwayhash v1.0.2 github.com/minio/kes v0.22.3 github.com/minio/madmin-go/v2 v2.2.0 github.com/minio/mc v0.0.0-20230526175537-0fac0e006eae github.com/minio/minio-go/v7 v7.0.55-0.20230525060734-b7836f021bfb - github.com/minio/operator v0.0.0-20230228004026-ad024a9dffe5 github.com/minio/pkg v1.6.5 github.com/minio/selfupdate v0.6.0 github.com/minio/websocket v1.6.0 @@ -42,10 +40,6 @@ require ( // https://github.com/golang/go/issues/56152 golang.org/x/text v0.9.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - k8s.io/api v0.27.1 // indirect - k8s.io/apimachinery v0.27.1 // indirect - k8s.io/client-go v0.27.1 - k8s.io/utils v0.0.0-20230313181309-38a27ef9d749 // indirect ) require ( @@ -66,30 +60,19 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect github.com/docker/go-units v0.5.0 // indirect - github.com/emicklei/go-restful/v3 v3.10.2 // indirect - github.com/evanphx/json-patch v5.6.0+incompatible // indirect github.com/fatih/structs v1.1.0 // indirect - github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/gdamore/encoding v1.0.0 // indirect github.com/gdamore/tcell/v2 v2.6.0 // indirect - github.com/go-logr/logr v1.2.3 // indirect github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-openapi/analysis v0.21.4 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/goccy/go-json v0.10.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang-jwt/jwt v3.2.2+incompatible // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect - github.com/google/gnostic v0.6.9 // indirect - github.com/google/go-cmp v0.5.9 // indirect - github.com/google/gofuzz v1.2.0 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/hcl v1.0.0 // indirect - github.com/imdario/mergo v0.3.15 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jedib0t/go-pretty/v6 v6.4.6 // indirect github.com/josharian/intern v1.0.0 // indirect @@ -104,7 +87,6 @@ require ( github.com/lestrrat-go/option v1.0.1 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/lufia/plan9stats v0.0.0-20230326075908-cb1d2100619a // indirect - github.com/magiconair/properties v1.8.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-ieproxy v0.0.1 // indirect @@ -112,8 +94,6 @@ require ( github.com/mattn/go-localereader v0.0.1 // indirect github.com/mattn/go-runewidth v0.0.14 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect - github.com/mb0/glob v0.0.0-20160210091149-1eb79d2de6c4 // indirect - github.com/miekg/dns v1.1.52 // indirect github.com/minio/colorjson v1.0.4 // indirect github.com/minio/filepath v1.0.0 // indirect github.com/minio/md5-simd v1.1.2 // indirect @@ -126,11 +106,9 @@ require ( github.com/muesli/cancelreader v0.2.2 // indirect github.com/muesli/reflow v0.3.0 // indirect github.com/muesli/termenv v0.15.1 // indirect - github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/navidys/tvxwidgets v0.3.0 // indirect github.com/oklog/ulid v1.3.1 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect - github.com/pelletier/go-toml/v2 v2.0.7 // indirect github.com/philhofer/fwd v1.1.2 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pkg/xattr v0.4.9 // indirect @@ -145,15 +123,10 @@ require ( github.com/rivo/tview v0.0.0-20230406072732-e22ce9588bb4 // indirect github.com/rivo/uniseg v0.4.4 // indirect github.com/rjeczalik/notify v0.9.3 // indirect + github.com/rogpeppe/go-internal v1.10.0 // indirect github.com/shirou/gopsutil/v3 v3.23.3 // indirect github.com/shoenig/go-m1cpu v0.1.5 // indirect github.com/sirupsen/logrus v1.9.2 // indirect - github.com/spf13/afero v1.9.5 // indirect - github.com/spf13/cast v1.5.0 // indirect - github.com/spf13/jwalterweatherman v1.1.0 // indirect - github.com/spf13/pflag v1.0.5 // indirect - github.com/spf13/viper v1.15.0 // indirect - github.com/subosito/gotenv v1.4.2 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect github.com/tinylib/msgp v1.1.8 // indirect @@ -167,24 +140,14 @@ require ( go.uber.org/atomic v1.10.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.24.0 // indirect - golang.org/x/mod v0.9.0 // indirect golang.org/x/sync v0.1.0 // indirect golang.org/x/sys v0.8.0 // indirect golang.org/x/term v0.8.0 // indirect - golang.org/x/time v0.3.0 // indirect - golang.org/x/tools v0.7.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230403163135-c38d8f061ccd // indirect google.golang.org/grpc v1.54.0 // indirect google.golang.org/protobuf v1.30.0 // indirect gopkg.in/h2non/filetype.v1 v1.0.5 // indirect - gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/apiextensions-apiserver v0.26.3 // indirect - k8s.io/klog/v2 v2.90.1 // indirect - k8s.io/kube-openapi v0.0.0-20230327201221-f5883ff37f0c // indirect - sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect - sigs.k8s.io/yaml v1.3.0 // indirect ) diff --git a/go.sum b/go.sum index 8d8caaa6c..6d86bb8c5 100644 --- a/go.sum +++ b/go.sum @@ -7,7 +7,6 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= @@ -20,7 +19,6 @@ cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOY cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= -cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= @@ -165,7 +163,6 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc= cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw= @@ -216,7 +213,6 @@ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kB github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= -github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -268,12 +264,9 @@ github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1 github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -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/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/emicklei/go-restful/v3 v3.10.2 h1:hIovbnmBTLjHXkqEBUz3HGpXZdM7ZrE9fJIZIqlJLqE= -github.com/emicklei/go-restful/v3 v3.10.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -284,8 +277,6 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.m github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= -github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= @@ -293,11 +284,7 @@ github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= -github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0= -github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko= github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg= github.com/gdamore/tcell/v2 v2.6.0 h1:OKbluoP9VYmJwZwq/iLb4BxwKcwGthaa1YNBJIyCySg= @@ -314,9 +301,6 @@ github.com/go-ldap/ldap/v3 v3.4.4/go.mod h1:fe1MsuN5eJJ1FeLT/LEBVdWfNWKh459R7aXg github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= -github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= @@ -358,7 +342,6 @@ github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+ github.com/go-openapi/validate v0.22.1 h1:G+c2ub6q47kfX1sOBLwIQwzBVt8qmOAARyo/9Fqs9NU= github.com/go-openapi/validate v0.22.1/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= @@ -391,16 +374,12 @@ github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5x 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 v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= -github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= @@ -433,8 +412,6 @@ github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/gnostic v0.6.9 h1:ZK/5VhkoX835RikCHpSUJV9a+S3e1zLh59YnyWeBW+0= -github.com/google/gnostic v0.6.9/go.mod h1:Nm8234We1lq6iB9OmlgNv3nH91XLLVZHCDayfA3xq+E= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -452,8 +429,6 @@ github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= -github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -467,12 +442,10 @@ github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= @@ -492,7 +465,6 @@ github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99 github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo= github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= -github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20220104163920-15ed2e8cf2bd/go.mod h1:cz9oNYuRUWGdHmLF2IodMLkAhcPtXeULvcBNagUrxTI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= @@ -517,7 +489,6 @@ github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= @@ -525,8 +496,6 @@ github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2p github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM= -github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= 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= @@ -570,7 +539,6 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxv github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= 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/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -600,8 +568,6 @@ github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c/go.mod h1:JKx41uQ github.com/lufia/plan9stats v0.0.0-20230326075908-cb1d2100619a h1:N9zuLhTvBSRt0gWSiJswwQ2HqDmtX/ZCDJURnKUt1Ik= github.com/lufia/plan9stats v0.0.0-20230326075908-cb1d2100619a/go.mod h1:JKx41uQRwqlTZabZc+kILPrO/3jlKnQ2Z8b7YiVw5cE= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= -github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= -github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= @@ -637,17 +603,11 @@ github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh 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/mb0/glob v0.0.0-20160210091149-1eb79d2de6c4 h1:NK3O7S5FRD/wj7ORQ5C3Mx1STpyEMuFe+/F0Lakd1Nk= -github.com/mb0/glob v0.0.0-20160210091149-1eb79d2de6c4/go.mod h1:FqD3ES5hx6zpzDainDaHgkTIqrPaI9uX4CVWqYZoQjY= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/dns v1.1.52 h1:Bmlc/qsNNULOe6bpXcUTsuOajd0DzRHwup6D9k1An0c= -github.com/miekg/dns v1.1.52/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= github.com/minio/cli v1.24.2 h1:J+fCUh9mhPLjN3Lj/YhklXvxj8mnyE/D6FpFduXJ2jg= github.com/minio/cli v1.24.2/go.mod h1:bYxnK0uS629N3Bq+AOZZ+6lwF77Sodk4+UL9vNuXhOY= github.com/minio/colorjson v1.0.4 h1:sNJYTb2uNswdqmGARg9wrogCX8+GRZzEacYbJT86e00= github.com/minio/colorjson v1.0.4/go.mod h1:ZgE8vYon4xC4yfBPclP/2gqMRYw+p+xRsBbLMDKdb9M= -github.com/minio/directpv v1.4.4-0.20220805090942-948ca4731651 h1:Uy3Fq5glAYPM0JeeleFQIxwCzMdVZMUmyEuyIQHN3ls= -github.com/minio/directpv v1.4.4-0.20220805090942-948ca4731651/go.mod h1:+qCuP3Vlkg+NRMmPb9WQmSctE6Vv3Zz3/uXgNIRpNmg= github.com/minio/filepath v1.0.0 h1:fvkJu1+6X+ECRA6G3+JJETj4QeAYO9sV43I79H8ubDY= github.com/minio/filepath v1.0.0/go.mod h1:/nRZA2ldl5z6jT9/KQuvZcQlxZIMQoFFQPvEXx9T/Bw= github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= @@ -665,8 +625,6 @@ github.com/minio/minio-go/v7 v7.0.41/go.mod h1:nCrRzjoSUQh8hgKKtu3Y708OLvRLtuASM github.com/minio/minio-go/v7 v7.0.55-0.20230525060734-b7836f021bfb h1:oW9owq24i06IMYrfufzdjLH5S4rcOc9M1f7Cak+Ya5I= github.com/minio/minio-go/v7 v7.0.55-0.20230525060734-b7836f021bfb/go.mod h1:NUDy4A4oXPq1l2yK6LTSvCEzAMeIcoz9lcj5dbzSrRE= github.com/minio/mux v1.9.0 h1:dWafQFyEfGhJvK6AwLOt83bIG5bxKxKJnKMCi0XAaoA= -github.com/minio/operator v0.0.0-20230228004026-ad024a9dffe5 h1:frrQ0bi+le6CW7KMBBizqZMwx/2fyuglbOo8cN985RM= -github.com/minio/operator v0.0.0-20230228004026-ad024a9dffe5/go.mod h1:ZU+W2i3O3qCnpD88VHvBb7jg4I94pccmQELvbrqDjzc= github.com/minio/pkg v1.5.4/go.mod h1:2MOaRFdmFKULD+uOLc3qHLGTQTuxCNPKNPfLBTxC8CA= github.com/minio/pkg v1.6.5 h1:T9cRNcCLJTFFgQGH0Rzr1CtAWLAIchTsbE0lSztCf40= github.com/minio/pkg v1.6.5/go.mod h1:0iX1IuJGSCnMvIvrEJauk1GgQSX9JdU6Kh0P3EQRGkI= @@ -714,8 +672,6 @@ github.com/muesli/termenv v0.13.0/go.mod h1:sP1+uffeLaEYpyOTb8pLCUctGcGLnoFjSn4Y github.com/muesli/termenv v0.14.0/go.mod h1:kG/pF1E7fh949Xhe156crRUrHNyK221IuGO7Ez60Uc8= github.com/muesli/termenv v0.15.1 h1:UzuTb/+hhlBugQz28rpzey4ZuKcZ03MeKsoG7IJZIxs= github.com/muesli/termenv v0.15.1/go.mod h1:HeAQPTzpfs016yGtA4g00CsdYnVLJvxsS4ANqrZs2sQ= -github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= -github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/navidys/tvxwidgets v0.3.0 h1:n04eW19PyUpnEochKGn15ZvCmKkcpzA188vH6XBnOMA= @@ -727,13 +683,9 @@ github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= -github.com/onsi/ginkgo/v2 v2.9.1 h1:zie5Ly042PD3bsCvsSOPvRnFwyo3rKe64TJlD6nu0mk= -github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/pelletier/go-toml/v2 v2.0.7 h1:muncTPStnKRos5dpVKULv2FVd4bMOhNePj9CjgDb8Us= -github.com/pelletier/go-toml/v2 v2.0.7/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/philhofer/fwd v1.1.2-0.20210722190033-5c56ac6d0bb9/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/philhofer/fwd v1.1.2 h1:bnDivRJ1EWPjUIRXV5KfORO897HTbpFAQddBdE8t7Gw= @@ -744,7 +696,6 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.6.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= -github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pkg/xattr v0.4.9 h1:5883YPCtkSd8LFbs13nXplj9g9tlrwoJRjgpgMu1/fE= github.com/pkg/xattr v0.4.9/go.mod h1:di8WF84zAKk8jzR1UBTEWh9AUlIZZ7M/JNt8e9B6ktU= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -799,6 +750,7 @@ github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= @@ -833,22 +785,13 @@ github.com/smartystreets/assertions v1.1.1/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYl github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= -github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= -github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= -github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= -github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= -github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU= -github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA= -github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -867,8 +810,6 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= -github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM= github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= @@ -895,9 +836,6 @@ github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+ github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -956,7 +894,6 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U 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-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= @@ -1003,8 +940,6 @@ golang.org/x/mod v0.4.1/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.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs= -golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1040,14 +975,12 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= @@ -1158,7 +1091,6 @@ golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210228012217-479acdf4ea46/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1167,7 +1099,6 @@ golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/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-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1199,7 +1130,6 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221010170243-090e33056c14/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= @@ -1232,8 +1162,6 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -1288,7 +1216,6 @@ golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= @@ -1297,8 +1224,6 @@ golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= -golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= -golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1397,9 +1322,7 @@ google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= @@ -1425,7 +1348,6 @@ google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ6 google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= @@ -1532,8 +1454,6 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EV gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/h2non/filetype.v1 v1.0.5 h1:CC1jjJjoEhNVbMhXYalmGBhOBK2V70Q1N850wt/98/Y= gopkg.in/h2non/filetype.v1 v1.0.5/go.mod h1:M0yem4rwSX5lLVrkEuRRp2/NinFMD5vgJ4DlAhZcfNo= -gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= -gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.66.6/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= @@ -1561,27 +1481,7 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -k8s.io/api v0.27.1 h1:Z6zUGQ1Vd10tJ+gHcNNNgkV5emCyW+v2XTmn+CLjSd0= -k8s.io/api v0.27.1/go.mod h1:z5g/BpAiD+f6AArpqNjkY+cji8ueZDU/WV1jcj5Jk4E= -k8s.io/apiextensions-apiserver v0.26.3 h1:5PGMm3oEzdB1W/FTMgGIDmm100vn7IaUP5er36dB+YE= -k8s.io/apiextensions-apiserver v0.26.3/go.mod h1:jdA5MdjNWGP+njw1EKMZc64xAT5fIhN6VJrElV3sfpQ= -k8s.io/apimachinery v0.27.1 h1:EGuZiLI95UQQcClhanryclaQE6xjg1Bts6/L3cD7zyc= -k8s.io/apimachinery v0.27.1/go.mod h1:5ikh59fK3AJ287GUvpUsryoMFtH9zj/ARfWCo3AyXTM= -k8s.io/client-go v0.27.1 h1:oXsfhW/qncM1wDmWBIuDzRHNS2tLhK3BZv512Nc59W8= -k8s.io/client-go v0.27.1/go.mod h1:f8LHMUkVb3b9N8bWturc+EDtVVVwZ7ueTVquFAJb2vA= -k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw= -k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/kube-openapi v0.0.0-20230327201221-f5883ff37f0c h1:EFfsozyzZ/pggw5qNx7ftTVZdp7WZl+3ih89GEjYEK8= -k8s.io/kube-openapi v0.0.0-20230327201221-f5883ff37f0c/go.mod h1:byini6yhqGC14c3ebc/QwanvYwhuMWF6yz2F8uwW8eg= -k8s.io/utils v0.0.0-20230313181309-38a27ef9d749 h1:xMMXJlJbsU8w3V5N2FLDQ8YgU8s1EoULdbQBcAeNJkY= -k8s.io/utils v0.0.0-20230313181309-38a27ef9d749/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= -sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= -sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= -sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= -sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index c4dabdc45..6e42b3465 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -17,6 +17,7 @@ package utils import ( + "context" "encoding/base64" "github.com/google/uuid" @@ -51,4 +52,15 @@ const ( ContextRequestHost = key("request-host") ContextRequestRemoteAddr = key("request-remote-addr") ContextAuditKey = key("request-audit-entry") + ContextClientIP = key("client-ip") ) + +// ClientIPFromContext attempts to get the Client IP from a context, if it's not present, it returns +// 127.0.0.1 +func ClientIPFromContext(ctx context.Context) string { + val := ctx.Value(ContextClientIP) + if val != nil { + return val.(string) + } + return "127.0.0.1" +} diff --git a/restapi/admin_arns.go b/restapi/admin_arns.go index d90076a6c..d4920f8e1 100644 --- a/restapi/admin_arns.go +++ b/restapi/admin_arns.go @@ -53,7 +53,7 @@ func getArns(ctx context.Context, client MinioAdmin) (*models.ArnsResponse, erro func getArnsResponse(session *models.Principal, params systemApi.ArnListParams) (*models.ArnsResponse, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } diff --git a/restapi/admin_config.go b/restapi/admin_config.go index 266eeb746..12d6043f6 100644 --- a/restapi/admin_config.go +++ b/restapi/admin_config.go @@ -104,7 +104,7 @@ func listConfig(client MinioAdmin) ([]*models.ConfigDescription, error) { func getListConfigResponse(session *models.Principal, params cfgApi.ListConfigParams) (*models.ListConfigResponse, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -169,7 +169,7 @@ func getConfig(ctx context.Context, client MinioAdmin, name string) ([]*models.C func getConfigResponse(session *models.Principal, params cfgApi.ConfigInfoParams) ([]*models.Configuration, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -234,7 +234,7 @@ func setConfigResponse(session *models.Principal, params cfgApi.SetConfigParams) ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -260,7 +260,7 @@ func resetConfigResponse(session *models.Principal, params cfgApi.ResetConfigPar ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -281,7 +281,7 @@ func exportConfigResponse(session *models.Principal, params cfgApi.ExportConfigP ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -299,7 +299,7 @@ func exportConfigResponse(session *models.Principal, params cfgApi.ExportConfigP func importConfigResponse(session *models.Principal, params cfgApi.PostConfigsImportParams) (*cfgApi.PostConfigsImportDefault, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } diff --git a/restapi/admin_groups.go b/restapi/admin_groups.go index 336b71294..a93d951f4 100644 --- a/restapi/admin_groups.go +++ b/restapi/admin_groups.go @@ -75,7 +75,7 @@ func registerGroupsHandlers(api *operations.ConsoleAPI) { func getListGroupsResponse(session *models.Principal, params groupApi.ListGroupsParams) (*models.ListGroupsResponse, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -110,7 +110,7 @@ func groupInfo(ctx context.Context, client MinioAdmin, group string) (*madmin.Gr func getGroupInfoResponse(session *models.Principal, params groupApi.GroupInfoParams) (*models.Group, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -161,7 +161,7 @@ func getAddGroupResponse(session *models.Principal, params groupApi.AddGroupPara return ErrorWithContext(ctx, ErrGroupBodyNotInRequest) } groupRequest := params.Body - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return ErrorWithContext(ctx, err) } @@ -204,7 +204,7 @@ func getRemoveGroupResponse(session *models.Principal, params groupApi.RemoveGro if params.Name == "" { return ErrorWithContext(ctx, ErrGroupNameNotInRequest) } - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return ErrorWithContext(ctx, err) } @@ -298,7 +298,7 @@ func getUpdateGroupResponse(session *models.Principal, params groupApi.UpdateGro return nil, ErrorWithContext(ctx, err) } - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } diff --git a/restapi/admin_health_info.go b/restapi/admin_health_info.go index f68b52f7d..b3afe0594 100644 --- a/restapi/admin_health_info.go +++ b/restapi/admin_health_info.go @@ -27,6 +27,8 @@ import ( "strings" "time" + "github.com/minio/console/pkg/utils" + "github.com/klauspost/compress/gzip" xhttp "github.com/minio/console/pkg/http" subnet "github.com/minio/console/pkg/subnet" @@ -73,6 +75,8 @@ func startHealthInfo(ctx context.Context, conn WSConn, client MinioAdmin, deadli SubnetResponse string `json:"subnetResponse"` } + ctx = context.WithValue(ctx, utils.ContextClientIP, conn.remoteAddress()) + subnetResp, err := sendHealthInfoToSubnet(ctx, healthInfo, client) report := messageReport{ Encoded: encodedDiag, @@ -130,8 +134,10 @@ func getHealthInfoOptionsFromReq(req *http.Request) (*time.Duration, error) { func sendHealthInfoToSubnet(ctx context.Context, healthInfo interface{}, client MinioAdmin) (string, error) { filename := fmt.Sprintf("health_%d.json", time.Now().Unix()) + clientIP := utils.ClientIPFromContext(ctx) + subnetUploadURL := subnet.UploadURL("health", filename) - subnetHTTPClient := &xhttp.Client{Client: GetConsoleHTTPClient("")} + subnetHTTPClient := &xhttp.Client{Client: GetConsoleHTTPClient("", clientIP)} subnetTokenConfig, e := GetSubnetKeyFromMinIOConfig(ctx, client) if e != nil { return "", e diff --git a/restapi/admin_idp.go b/restapi/admin_idp.go index 359b2ed73..5f74bbc6d 100644 --- a/restapi/admin_idp.go +++ b/restapi/admin_idp.go @@ -79,7 +79,7 @@ func registerIDPHandlers(api *operations.ConsoleAPI) { func createIDPConfigurationResponse(session *models.Principal, params idp.CreateConfigurationParams) (*models.SetIDPResponse, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -93,7 +93,7 @@ func createIDPConfigurationResponse(session *models.Principal, params idp.Create func updateIDPConfigurationResponse(session *models.Principal, params idp.UpdateConfigurationParams) (*models.SetIDPResponse, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -118,7 +118,7 @@ func createOrUpdateIDPConfig(ctx context.Context, idpType, name, input string, u func listIDPConfigurationsResponse(session *models.Principal, params idp.ListConfigurationsParams) (*models.IdpListConfigurationsResponse, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -154,7 +154,7 @@ func parseIDPConfigurations(configs []madmin.IDPListItem) (serverConfigs []*mode func deleteIDPConfigurationResponse(session *models.Principal, params idp.DeleteConfigurationParams) (*models.SetIDPResponse, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -179,7 +179,7 @@ func deleteIDPConfig(ctx context.Context, idpType, name string, client MinioAdmi func getIDPConfigurationsResponse(session *models.Principal, params idp.GetConfigurationParams) (*models.IdpServerConfiguration, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -220,7 +220,7 @@ func parseIDPConfigurationsInfo(infoList []madmin.IDPCfgInfo) (results []*models func getLDAPEntitiesResponse(session *models.Principal, params idp.GetLDAPEntitiesParams) (*models.LdapEntities, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } diff --git a/restapi/admin_info.go b/restapi/admin_info.go index 75c2ae806..e2af09154 100644 --- a/restapi/admin_info.go +++ b/restapi/admin_info.go @@ -28,6 +28,8 @@ import ( "sync" "time" + "github.com/minio/console/pkg/utils" + "github.com/go-openapi/runtime/middleware" "github.com/go-openapi/swag" "github.com/minio/console/models" @@ -882,7 +884,7 @@ func getAdminInfoResponse(session *models.Principal, params systemApi.AdminInfoP prometheusURL = getPrometheusURL() } - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -954,9 +956,7 @@ func getUsageWidgetsForDeployment(ctx context.Context, prometheusURL string, adm return sessionResp, nil } -func unmarshalPrometheus(ctx context.Context, endpoint string, data interface{}) bool { - httpClnt := GetConsoleHTTPClient(endpoint) - +func unmarshalPrometheus(ctx context.Context, httpClnt *http.Client, endpoint string, data interface{}) bool { req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint, nil) if err != nil { ErrorWithContext(ctx, fmt.Errorf("Unable to create the request to fetch labels from prometheus: %w", err)) @@ -985,12 +985,14 @@ func unmarshalPrometheus(ctx context.Context, endpoint string, data interface{}) } func testPrometheusURL(ctx context.Context, url string) bool { + clientIP := utils.ClientIPFromContext(ctx) + httpClnt := GetConsoleHTTPClient(url, clientIP) req, err := http.NewRequestWithContext(ctx, http.MethodGet, url+"/-/healthy", nil) if err != nil { ErrorWithContext(ctx, fmt.Errorf("error Building Request: (%v)", err)) return false } - response, err := GetConsoleHTTPClient(url).Do(req) + response, err := httpClnt.Do(req) if err != nil { ErrorWithContext(ctx, fmt.Errorf("default Prometheus URL not reachable, trying root testing: (%v)", err)) newTestURL := req.URL.Scheme + "://" + req.URL.Host + "/-/healthy" @@ -999,7 +1001,7 @@ func testPrometheusURL(ctx context.Context, url string) bool { ErrorWithContext(ctx, fmt.Errorf("error Building Root Request: (%v)", err)) return false } - rootResponse, err := GetConsoleHTTPClient(newTestURL).Do(req2) + rootResponse, err := httpClnt.Do(req2) if err != nil { // URL & Root tests didn't work. Prometheus not reachable ErrorWithContext(ctx, fmt.Errorf("root Prometheus URL not reachable: (%v)", err)) @@ -1021,6 +1023,8 @@ func getAdminInfoWidgetResponse(params systemApi.DashboardWidgetDetailsParams) ( if strings.TrimSpace(prometheusExtraLabels) != "" { selector = fmt.Sprintf(`job="%s",%s`, prometheusJobID, prometheusExtraLabels) } + clientIP := getClientIP(params.HTTPRequest) + ctx = context.WithValue(ctx, utils.ContextClientIP, clientIP) return getWidgetDetails(ctx, prometheusURL, selector, params.WidgetID, params.Step, params.Start, params.End) } @@ -1029,6 +1033,9 @@ func getWidgetDetails(ctx context.Context, prometheusURL string, selector string if !testPrometheusURL(ctx, prometheusURL) { return nil, ErrorWithContext(ctx, errors.New("prometheus URL is unreachable")) } + clientIP := utils.ClientIPFromContext(ctx) + httpClnt := GetConsoleHTTPClient(prometheusURL, clientIP) + labelResultsCh := make(chan LabelResults) for _, lbl := range labels { @@ -1036,7 +1043,7 @@ func getWidgetDetails(ctx context.Context, prometheusURL string, selector string endpoint := fmt.Sprintf("%s/api/v1/label/%s/values", prometheusURL, lbl.Name) var response LabelResponse - if unmarshalPrometheus(ctx, endpoint, &response) { + if unmarshalPrometheus(ctx, httpClnt, endpoint, &response) { return } @@ -1122,7 +1129,7 @@ LabelsWaitLoop: endpoint := fmt.Sprintf("%s/api/v1/%s?query=%s%s", prometheusURL, apiType, url.QueryEscape(queryExpr), extraParamters) var response PromResp - if unmarshalPrometheus(ctx, endpoint, &response) { + if unmarshalPrometheus(ctx, httpClnt, endpoint, &response) { return } diff --git a/restapi/admin_info_test.go b/restapi/admin_info_test.go index 8051c467a..0c67418cb 100644 --- a/restapi/admin_info_test.go +++ b/restapi/admin_info_test.go @@ -23,6 +23,8 @@ import ( "os" "testing" + "github.com/minio/console/pkg/utils" + "github.com/minio/console/models" "github.com/minio/console/restapi/operations" systemApi "github.com/minio/console/restapi/operations/system" @@ -125,7 +127,7 @@ func (suite *AdminInfoTestSuite) initSystemDashboardWidgetDetailsRequest() (para } func (suite *AdminInfoTestSuite) TestGetUsageWidgetsForDeploymentWithoutError() { - ctx := context.Background() + ctx := context.WithValue(context.Background(), utils.ContextClientIP, "127.0.0.1") suite.isPrometheusRequest = true res, err := getUsageWidgetsForDeployment(ctx, suite.server.URL, suite.adminClient) suite.assert.Nil(err) @@ -134,7 +136,7 @@ func (suite *AdminInfoTestSuite) TestGetUsageWidgetsForDeploymentWithoutError() } func (suite *AdminInfoTestSuite) TestGetWidgetDetailsWithoutError() { - ctx := context.Background() + ctx := context.WithValue(context.Background(), utils.ContextClientIP, "127.0.0.1") suite.isPrometheusRequest = true var step int32 = 1 var start int64 diff --git a/restapi/admin_inspect.go b/restapi/admin_inspect.go index 5bbe9799c..57314bd45 100644 --- a/restapi/admin_inspect.go +++ b/restapi/admin_inspect.go @@ -54,7 +54,7 @@ func registerInspectHandler(api *operations.ConsoleAPI) { func getInspectResult(session *models.Principal, params *inspectApi.InspectParams) ([]byte, io.ReadCloser, *models.Error) { ctx := params.HTTPRequest.Context() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, nil, ErrorWithContext(ctx, err) } diff --git a/restapi/admin_kms.go b/restapi/admin_kms.go index 2ed74cff0..76180006c 100644 --- a/restapi/admin_kms.go +++ b/restapi/admin_kms.go @@ -73,7 +73,7 @@ func registerKMSStatusHandlers(api *operations.ConsoleAPI) { func GetKMSStatusResponse(session *models.Principal, params kmsAPI.KMSStatusParams) (*models.KmsStatusResponse, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -102,7 +102,7 @@ func parseStatusEndpoints(endpoints map[string]madmin.ItemState) (kmsEndpoints [ func GetKMSMetricsResponse(session *models.Principal, params kmsAPI.KMSMetricsParams) (*models.KmsMetricsResponse, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -146,7 +146,7 @@ func parseHistogram(histogram map[int64]int64) (records []*models.KmsLatencyHist func GetKMSAPIsResponse(session *models.Principal, params kmsAPI.KMSAPIsParams) (*models.KmsAPIsResponse, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -178,7 +178,7 @@ func parseApis(apis []madmin.KMSAPI) (data []*models.KmsAPI) { func GetKMSVersionResponse(session *models.Principal, params kmsAPI.KMSVersionParams) (*models.KmsVersionResponse, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -240,7 +240,7 @@ func registerKMSKeyHandlers(api *operations.ConsoleAPI) { func GetKMSCreateKeyResponse(session *models.Principal, params kmsAPI.KMSCreateKeyParams) *models.Error { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return ErrorWithContext(ctx, err) } @@ -257,7 +257,7 @@ func createKey(ctx context.Context, key string, minioClient MinioAdmin) *models. func GetKMSImportKeyResponse(session *models.Principal, params kmsAPI.KMSImportKeyParams) *models.Error { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return ErrorWithContext(ctx, err) } @@ -278,7 +278,7 @@ func importKey(ctx context.Context, key string, bytes []byte, minioClient MinioA func GetKMSListKeysResponse(session *models.Principal, params kmsAPI.KMSListKeysParams) (*models.KmsListKeysResponse, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -311,7 +311,7 @@ func parseKeys(results []madmin.KMSKeyInfo) (data []*models.KmsKeyInfo) { func GetKMSKeyStatusResponse(session *models.Principal, params kmsAPI.KMSKeyStatusParams) (*models.KmsKeyStatusResponse, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -333,7 +333,7 @@ func keyStatus(ctx context.Context, key string, minioClient MinioAdmin) (*models func GetKMSDeleteKeyResponse(session *models.Principal, params kmsAPI.KMSDeleteKeyParams) *models.Error { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return ErrorWithContext(ctx, err) } @@ -400,7 +400,7 @@ func registerKMSPolicyHandlers(api *operations.ConsoleAPI) { func GetKMSSetPolicyResponse(session *models.Principal, params kmsAPI.KMSSetPolicyParams) *models.Error { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return ErrorWithContext(ctx, err) } @@ -421,7 +421,7 @@ func setPolicy(ctx context.Context, policy string, content []byte, minioClient M func GetKMSAssignPolicyResponse(session *models.Principal, params kmsAPI.KMSAssignPolicyParams) *models.Error { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return ErrorWithContext(ctx, err) } @@ -442,7 +442,7 @@ func assignPolicy(ctx context.Context, policy string, content []byte, minioClien func GetKMSDescribePolicyResponse(session *models.Principal, params kmsAPI.KMSDescribePolicyParams) (*models.KmsDescribePolicyResponse, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -464,7 +464,7 @@ func describePolicy(ctx context.Context, policy string, minioClient MinioAdmin) func GetKMSGetPolicyResponse(session *models.Principal, params kmsAPI.KMSGetPolicyParams) (*models.KmsGetPolicyResponse, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -485,7 +485,7 @@ func getPolicy(ctx context.Context, policy string, minioClient MinioAdmin) (*mod func GetKMSListPoliciesResponse(session *models.Principal, params kmsAPI.KMSListPoliciesParams) (*models.KmsListPoliciesResponse, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -518,7 +518,7 @@ func parsePolicies(results []madmin.KMSPolicyInfo) (data []*models.KmsPolicyInfo func GetKMSDeletePolicyResponse(session *models.Principal, params kmsAPI.KMSDeletePolicyParams) *models.Error { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return ErrorWithContext(ctx, err) } @@ -568,7 +568,7 @@ func registerKMSIdentityHandlers(api *operations.ConsoleAPI) { func GetKMSDescribeIdentityResponse(session *models.Principal, params kmsAPI.KMSDescribeIdentityParams) (*models.KmsDescribeIdentityResponse, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -592,7 +592,7 @@ func describeIdentity(ctx context.Context, identity string, minioClient MinioAdm func GetKMSDescribeSelfIdentityResponse(session *models.Principal, params kmsAPI.KMSDescribeSelfIdentityParams) (*models.KmsDescribeSelfIdentityResponse, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -619,7 +619,7 @@ func describeSelfIdentity(ctx context.Context, minioClient MinioAdmin) (*models. func GetKMSListIdentitiesResponse(session *models.Principal, params kmsAPI.KMSListIdentitiesParams) (*models.KmsListIdentitiesResponse, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -654,7 +654,7 @@ func parseIdentities(results []madmin.KMSIdentityInfo) (data []*models.KmsIdenti func GetKMSDeleteIdentityResponse(session *models.Principal, params kmsAPI.KMSDeleteIdentityParams) *models.Error { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return ErrorWithContext(ctx, err) } diff --git a/restapi/admin_nodes.go b/restapi/admin_nodes.go index 549ee1c67..7ee228753 100644 --- a/restapi/admin_nodes.go +++ b/restapi/admin_nodes.go @@ -39,7 +39,7 @@ func registerNodesHandler(api *operations.ConsoleAPI) { func getListNodesResponse(session *models.Principal, params systemApi.ListNodesParams) ([]string, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } diff --git a/restapi/admin_notification_endpoints.go b/restapi/admin_notification_endpoints.go index f267aa353..508aa3e5e 100644 --- a/restapi/admin_notification_endpoints.go +++ b/restapi/admin_notification_endpoints.go @@ -76,7 +76,7 @@ func getNotificationEndpoints(ctx context.Context, client MinioAdmin) (*models.N func getNotificationEndpointsResponse(session *models.Principal, params configurationApi.NotificationEndpointListParams) (*models.NotifEndpointResponse, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -146,7 +146,7 @@ func addNotificationEndpoint(ctx context.Context, client MinioAdmin, params *con func getAddNotificationEndpointResponse(session *models.Principal, params configurationApi.AddNotificationEndpointParams) (*models.SetNotificationEndpointResponse, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } diff --git a/restapi/admin_policies.go b/restapi/admin_policies.go index 36fe8ef25..c7296b794 100644 --- a/restapi/admin_policies.go +++ b/restapi/admin_policies.go @@ -127,7 +127,7 @@ func registersPoliciesHandler(api *operations.ConsoleAPI) { }) // Gets policies for currently logged in user api.PolicyGetUserPolicyHandler = policyApi.GetUserPolicyHandlerFunc(func(params policyApi.GetUserPolicyParams, session *models.Principal) middleware.Responder { - userPolicyResponse, err := getUserPolicyResponse(session) + userPolicyResponse, err := getUserPolicyResponse(params.HTTPRequest.Context(), session) if err != nil { return policyApi.NewGetUserPolicyDefault(int(err.Code)).WithPayload(err) } @@ -147,7 +147,7 @@ func getListAccessRulesWithBucketResponse(session *models.Principal, params buck ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() bucket := params.Bucket - client, err := newS3BucketClient(session, bucket, "") + client, err := newS3BucketClient(session, bucket, "", getClientIP(params.HTTPRequest)) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -163,7 +163,7 @@ func getSetAccessRuleWithBucketResponse(session *models.Principal, params bucket ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() prefixAccess := params.Prefixaccess - client, err := newS3BucketClient(session, params.Bucket, prefixAccess.Prefix) + client, err := newS3BucketClient(session, params.Bucket, prefixAccess.Prefix, getClientIP(params.HTTPRequest)) if err != nil { return false, ErrorWithContext(ctx, err) } @@ -184,7 +184,7 @@ func getDeleteAccessRuleWithBucketResponse(session *models.Principal, params buc defer cancel() bucket := params.Bucket prefix := params.Prefix - client, err := newS3BucketClient(session, bucket, prefix.Prefix) + client, err := newS3BucketClient(session, bucket, prefix.Prefix, getClientIP(params.HTTPRequest)) if err != nil { return false, ErrorWithContext(ctx, err) } @@ -198,7 +198,7 @@ func getDeleteAccessRuleWithBucketResponse(session *models.Principal, params buc func getListPoliciesWithBucketResponse(session *models.Principal, params bucketApi.ListPoliciesWithBucketParams) (*models.ListPoliciesResponse, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -284,7 +284,7 @@ func listPolicies(ctx context.Context, client MinioAdmin) ([]*models.Policy, err func getListPoliciesResponse(session *models.Principal, params policyApi.ListPoliciesParams) (*models.ListPoliciesResponse, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -312,7 +312,7 @@ func getListUsersForPolicyResponse(session *models.Principal, params policyApi.L if err != nil { return nil, ErrorWithContext(ctx, err) } - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -350,7 +350,7 @@ func getListUsersForPolicyResponse(session *models.Principal, params policyApi.L return filteredUsers, nil } -func getUserPolicyResponse(session *models.Principal) (string, *models.Error) { +func getUserPolicyResponse(ctx context.Context, session *models.Principal) (string, *models.Error) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() // serialize output @@ -360,7 +360,7 @@ func getUserPolicyResponse(session *models.Principal) (string, *models.Error) { tokenClaims, _ := getClaimsFromToken(session.STSSessionToken) // initialize admin client - mAdminClient, err := NewMinioAdminClient(&models.Principal{ + mAdminClient, err := NewMinioAdminClient(ctx, &models.Principal{ STSAccessKeyID: session.STSAccessKeyID, STSSecretAccessKey: session.STSSecretAccessKey, STSSessionToken: session.STSSessionToken, @@ -387,7 +387,7 @@ func getSAUserPolicyResponse(session *models.Principal, params policyApi.GetSAUs return nil, ErrorWithContext(ctx, ErrPolicyNotFound) } // initialize admin client - mAdminClient, err := NewMinioAdminClient(&models.Principal{ + mAdminClient, err := NewMinioAdminClient(params.HTTPRequest.Context(), &models.Principal{ STSAccessKeyID: session.STSAccessKeyID, STSSecretAccessKey: session.STSSecretAccessKey, STSSessionToken: session.STSSessionToken, @@ -461,7 +461,7 @@ func getSAUserPolicyResponse(session *models.Principal, params policyApi.GetSAUs func getListGroupsForPolicyResponse(session *models.Principal, params policyApi.ListGroupsForPolicyParams) ([]string, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -528,7 +528,7 @@ func getRemovePolicyResponse(session *models.Principal, params policyApi.RemoveP if err != nil { return ErrorWithContext(ctx, err) } - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return ErrorWithContext(ctx, err) } @@ -571,7 +571,7 @@ func getAddPolicyResponse(session *models.Principal, params policyApi.AddPolicyP if strings.Contains(*params.Body.Name, " ") { return nil, ErrorWithContext(ctx, ErrPolicyNameContainsSpace) } - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -616,7 +616,7 @@ func getPolicyStatements(ctx context.Context, client MinioAdmin, name string) ([ func getPolicyInfoResponse(session *models.Principal, params policyApi.PolicyInfoParams) (*models.Policy, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -648,7 +648,7 @@ func getSetPolicyResponse(session *models.Principal, params policyApi.SetPolicyP ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() // Removing this section - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return ErrorWithContext(ctx, err) } @@ -665,7 +665,7 @@ func getSetPolicyResponse(session *models.Principal, params policyApi.SetPolicyP func getSetPolicyMultipleResponse(session *models.Principal, params policyApi.SetPolicyMultipleParams) *models.Error { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return ErrorWithContext(ctx, err) } diff --git a/restapi/admin_releases.go b/restapi/admin_releases.go index 31b86d325..427cc6b3a 100644 --- a/restapi/admin_releases.go +++ b/restapi/admin_releases.go @@ -24,6 +24,8 @@ import ( "net/url" "time" + "github.com/minio/console/pkg/utils" + "github.com/go-openapi/runtime/middleware" "github.com/minio/console/models" "github.com/minio/console/restapi/operations" @@ -62,12 +64,14 @@ func GetReleaseListResponse(_ *models.Principal, params release.ListReleasesPara if params.Filter != nil { filter = *params.Filter } + ctx = context.WithValue(ctx, utils.ContextClientIP, getClientIP(params.HTTPRequest)) return releaseList(ctx, repo, currentRelease, search, filter) } func releaseList(ctx context.Context, repo, currentRelease, search, filter string) (*models.ReleaseListResponse, *models.Error) { serviceURL := getReleaseServiceURL() - releases, err := getReleases(serviceURL, repo, currentRelease, search, filter) + clientIP := utils.ClientIPFromContext(ctx) + releases, err := getReleases(serviceURL, repo, currentRelease, search, filter, clientIP) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -79,7 +83,7 @@ func getReleaseServiceURL() string { return fmt.Sprintf("%s/releases", host) } -func getReleases(endpoint, repo, currentRelease, search, filter string) (*models.ReleaseListResponse, error) { +func getReleases(endpoint, repo, currentRelease, search, filter, clientIP string) (*models.ReleaseListResponse, error) { rl := &models.ReleaseListResponse{} req, err := http.NewRequest(http.MethodGet, endpoint, nil) if err != nil { @@ -93,7 +97,7 @@ func getReleases(endpoint, repo, currentRelease, search, filter string) (*models req.URL.RawQuery = q.Encode() req.Header.Set("Content-Type", "application/json") - client := GetConsoleHTTPClient("") + client := GetConsoleHTTPClient("", clientIP) client.Timeout = time.Second * 5 resp, err := client.Do(req) diff --git a/restapi/admin_remote_buckets.go b/restapi/admin_remote_buckets.go index 7a7add8f0..3c5167a3b 100644 --- a/restapi/admin_remote_buckets.go +++ b/restapi/admin_remote_buckets.go @@ -24,6 +24,8 @@ import ( "strconv" "time" + "github.com/minio/console/pkg/utils" + "github.com/minio/madmin-go/v2" "github.com/go-openapi/runtime/middleware" @@ -145,7 +147,7 @@ func registerAdminBucketRemoteHandlers(api *operations.ConsoleAPI) { func getListRemoteBucketsResponse(session *models.Principal, params bucketApi.ListRemoteBucketsParams) (*models.ListRemoteBucketsResponse, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, fmt.Errorf("error creating Madmin Client: %v", err)) } @@ -156,7 +158,7 @@ func getListRemoteBucketsResponse(session *models.Principal, params bucketApi.Li func getRemoteBucketDetailsResponse(session *models.Principal, params bucketApi.RemoteBucketDetailsParams) (*models.RemoteBucket, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, fmt.Errorf("error creating Madmin Client: %v", err)) } @@ -167,7 +169,7 @@ func getRemoteBucketDetailsResponse(session *models.Principal, params bucketApi. func getDeleteRemoteBucketResponse(session *models.Principal, params bucketApi.DeleteRemoteBucketParams) *models.Error { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return ErrorWithContext(ctx, fmt.Errorf("error creating Madmin Client: %v", err)) } @@ -182,7 +184,7 @@ func getDeleteRemoteBucketResponse(session *models.Principal, params bucketApi.D func getAddRemoteBucketResponse(session *models.Principal, params bucketApi.AddRemoteBucketParams) *models.Error { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return ErrorWithContext(ctx, fmt.Errorf("error creating Madmin Client: %v", err)) } @@ -310,8 +312,8 @@ func addBucketReplicationItem(ctx context.Context, session *models.Principal, mi } else { // User picked priority, we try to set this manually maxPrio = int(priority) } - - s3Client, err := newS3BucketClient(session, bucketName, prefix) + clientIP := utils.ClientIPFromContext(ctx) + s3Client, err := newS3BucketClient(session, bucketName, prefix, clientIP) if err != nil { ErrorWithContext(ctx, fmt.Errorf("error creating S3Client: %v", err)) return err @@ -365,7 +367,8 @@ func editBucketReplicationItem(ctx context.Context, session *models.Principal, m maxPrio := int(priority) - s3Client, err := newS3BucketClient(session, bucketName, prefix) + clientIP := utils.ClientIPFromContext(ctx) + s3Client, err := newS3BucketClient(session, bucketName, prefix, clientIP) if err != nil { return fmt.Errorf("error creating S3Client: %v", err) } @@ -503,13 +506,13 @@ func setMultiBucketReplicationResponse(session *models.Principal, params bucketA ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, fmt.Errorf("error creating Madmin Client: %v", err)) } adminClient := AdminClient{Client: mAdmin} - mClient, err := newMinioClient(session) + mClient, err := newMinioClient(session, getClientIP(params.HTTPRequest)) if err != nil { return nil, ErrorWithContext(ctx, fmt.Errorf("error creating MinIO Client: %v", err)) } @@ -588,7 +591,8 @@ func getARNsFromIDs(conf *replication.Config, rules []string) []string { } func deleteReplicationRule(ctx context.Context, session *models.Principal, bucketName, ruleID string) error { - mClient, err := newMinioClient(session) + clientIP := utils.ClientIPFromContext(ctx) + mClient, err := newMinioClient(session, clientIP) if err != nil { return fmt.Errorf("error creating MinIO Client: %v", err) } @@ -601,12 +605,11 @@ func deleteReplicationRule(ctx context.Context, session *models.Principal, bucke ErrorWithContext(ctx, fmt.Errorf("error versioning bucket: %v", err)) } - s3Client, err := newS3BucketClient(session, bucketName, "") + s3Client, err := newS3BucketClient(session, bucketName, "", clientIP) if err != nil { return fmt.Errorf("error creating S3Client: %v", err) } - - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(ctx, session) if err != nil { return fmt.Errorf("error creating Admin Client: %v", err) } @@ -636,15 +639,16 @@ func deleteReplicationRule(ctx context.Context, session *models.Principal, bucke } func deleteAllReplicationRules(ctx context.Context, session *models.Principal, bucketName string) error { - s3Client, err := newS3BucketClient(session, bucketName, "") + clientIP := utils.ClientIPFromContext(ctx) + + s3Client, err := newS3BucketClient(session, bucketName, "", clientIP) if err != nil { return fmt.Errorf("error creating S3Client: %v", err) } // create a mc S3Client interface implementation // defining the client to be used mcClient := mcClient{client: s3Client} - - mClient, err := newMinioClient(session) + mClient, err := newMinioClient(session, clientIP) if err != nil { return fmt.Errorf("error creating MinIO Client: %v", err) } @@ -657,7 +661,7 @@ func deleteAllReplicationRules(ctx context.Context, session *models.Principal, b ErrorWithContext(ctx, fmt.Errorf("error versioning bucket: %v", err)) } - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(ctx, session) if err != nil { return fmt.Errorf("error creating Admin Client: %v", err) } @@ -680,7 +684,8 @@ func deleteAllReplicationRules(ctx context.Context, session *models.Principal, b } func deleteSelectedReplicationRules(ctx context.Context, session *models.Principal, bucketName string, rules []string) error { - mClient, err := newMinioClient(session) + clientIP := utils.ClientIPFromContext(ctx) + mClient, err := newMinioClient(session, clientIP) if err != nil { return fmt.Errorf("error creating MinIO Client: %v", err) } @@ -693,7 +698,7 @@ func deleteSelectedReplicationRules(ctx context.Context, session *models.Princip ErrorWithContext(ctx, fmt.Errorf("error versioning bucket: %v", err)) } - s3Client, err := newS3BucketClient(session, bucketName, "") + s3Client, err := newS3BucketClient(session, bucketName, "", clientIP) if err != nil { return fmt.Errorf("error creating S3Client: %v", err) } @@ -701,7 +706,7 @@ func deleteSelectedReplicationRules(ctx context.Context, session *models.Princip // defining the client to be used mcClient := mcClient{client: s3Client} - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(ctx, session) if err != nil { return fmt.Errorf("error creating Admin Client: %v", err) } @@ -731,7 +736,7 @@ func deleteSelectedReplicationRules(ctx context.Context, session *models.Princip func deleteReplicationRuleResponse(session *models.Principal, params bucketApi.DeleteBucketReplicationRuleParams) *models.Error { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - + ctx = context.WithValue(ctx, utils.ContextClientIP, getClientIP(params.HTTPRequest)) err := deleteReplicationRule(ctx, session, params.BucketName, params.RuleID) if err != nil { return ErrorWithContext(ctx, err) @@ -742,7 +747,7 @@ func deleteReplicationRuleResponse(session *models.Principal, params bucketApi.D func deleteBucketReplicationRulesResponse(session *models.Principal, params bucketApi.DeleteAllReplicationRulesParams) *models.Error { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - + ctx = context.WithValue(ctx, utils.ContextClientIP, getClientIP(params.HTTPRequest)) err := deleteAllReplicationRules(ctx, session, params.BucketName) if err != nil { return ErrorWithContext(ctx, err) @@ -754,6 +759,8 @@ func deleteSelectedReplicationRulesResponse(session *models.Principal, params bu ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() + ctx = context.WithValue(ctx, utils.ContextClientIP, getClientIP(params.HTTPRequest)) + err := deleteSelectedReplicationRules(ctx, session, params.BucketName, params.Rules.Rules) if err != nil { return ErrorWithContext(ctx, err) @@ -765,7 +772,7 @@ func updateBucketReplicationResponse(session *models.Principal, params bucketApi ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mClient, err := newMinioClient(session) + mClient, err := newMinioClient(session, getClientIP(params.HTTPRequest)) if err != nil { return ErrorWithContext(ctx, err) } diff --git a/restapi/admin_remote_buckets_test.go b/restapi/admin_remote_buckets_test.go index fa0998df6..be3387462 100644 --- a/restapi/admin_remote_buckets_test.go +++ b/restapi/admin_remote_buckets_test.go @@ -24,6 +24,8 @@ import ( "os" "testing" + "github.com/minio/console/pkg/utils" + "github.com/go-openapi/swag" "github.com/minio/console/models" "github.com/minio/console/restapi/operations" @@ -371,7 +373,10 @@ func (suite *RemoteBucketsTestSuite) TestUpdateMultiBucketReplicationHandlerWith func (suite *RemoteBucketsTestSuite) initUpdateMultiBucketReplicationRequest() (params bucketApi.UpdateMultiBucketReplicationParams, api operations.ConsoleAPI) { registerAdminBucketRemoteHandlers(&api) - params.HTTPRequest = &http.Request{} + r := &http.Request{} + ctx := context.WithValue(context.Background(), utils.ContextClientIP, "127.0.0.1") + rc := r.WithContext(ctx) + params.HTTPRequest = rc params.Body = &models.MultiBucketReplicationEdit{} return params, api } diff --git a/restapi/admin_replication_status.go b/restapi/admin_replication_status.go index ce32f2726..4a6f732f6 100644 --- a/restapi/admin_replication_status.go +++ b/restapi/admin_replication_status.go @@ -39,7 +39,7 @@ func registerSiteReplicationStatusHandler(api *operations.ConsoleAPI) { func getSRStatusResponse(session *models.Principal, params siteRepApi.GetSiteReplicationStatusParams) (*models.SiteReplicationStatusResponse, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } diff --git a/restapi/admin_service.go b/restapi/admin_service.go index dd2b1cac9..76e01366b 100644 --- a/restapi/admin_service.go +++ b/restapi/admin_service.go @@ -62,7 +62,7 @@ func serviceRestart(ctx context.Context, client MinioAdmin) error { func getRestartServiceResponse(session *models.Principal, params svcApi.RestartServiceParams) *models.Error { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return ErrorWithContext(ctx, err) } diff --git a/restapi/admin_site_replication.go b/restapi/admin_site_replication.go index 16cdf98ff..405cc3d6b 100644 --- a/restapi/admin_site_replication.go +++ b/restapi/admin_site_replication.go @@ -63,7 +63,7 @@ func registerSiteReplicationHandler(api *operations.ConsoleAPI) { func getSRInfoResponse(session *models.Principal, params siteRepApi.GetSiteReplicationInfoParams) (*models.SiteReplicationInfoResponse, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -79,7 +79,7 @@ func getSRInfoResponse(session *models.Principal, params siteRepApi.GetSiteRepli func getSRAddResponse(session *models.Principal, params siteRepApi.SiteReplicationInfoAddParams) (*models.SiteReplicationAddResponse, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -95,7 +95,7 @@ func getSRAddResponse(session *models.Principal, params siteRepApi.SiteReplicati func getSREditResponse(session *models.Principal, params siteRepApi.SiteReplicationEditParams) (*models.PeerSiteEditResponse, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -110,7 +110,7 @@ func getSREditResponse(session *models.Principal, params siteRepApi.SiteReplicat func getSRRemoveResponse(session *models.Principal, params siteRepApi.SiteReplicationRemoveParams) (*models.PeerSiteRemoveResponse, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } diff --git a/restapi/admin_subnet.go b/restapi/admin_subnet.go index 3b5832346..20f475ccb 100644 --- a/restapi/admin_subnet.go +++ b/restapi/admin_subnet.go @@ -25,6 +25,8 @@ import ( "net/url" "os" + "github.com/minio/console/pkg/utils" + xhttp "github.com/minio/console/pkg/http" "github.com/go-openapi/runtime/middleware" @@ -93,7 +95,8 @@ func SubnetRegisterWithAPIKey(ctx context.Context, minioClient MinioAdmin, apiKe if err != nil { return false, err } - registerResult, err := subnet.Register(GetConsoleHTTPClient(""), serverInfo, apiKey, "", "") + clientIP := utils.ClientIPFromContext(ctx) + registerResult, err := subnet.Register(GetConsoleHTTPClient("", clientIP), serverInfo, apiKey, "", "") if err != nil { return false, err } @@ -130,7 +133,7 @@ func SubnetLogin(client xhttp.ClientI, username, password string) (string, strin func GetSubnetLoginResponse(session *models.Principal, params subnetApi.SubnetLoginParams) (*models.SubnetLoginResponse, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -195,7 +198,8 @@ func SubnetLoginWithMFA(client xhttp.ClientI, username, mfaToken, otp string) (* // GetSubnetHTTPClient will return a client with proxy if configured, otherwise will return the default console http client func GetSubnetHTTPClient(ctx context.Context, minioClient MinioAdmin) (*xhttp.Client, error) { - subnetHTTPClient := GetConsoleHTTPClient("") + clientIP := utils.ClientIPFromContext(ctx) + subnetHTTPClient := GetConsoleHTTPClient("", clientIP) subnetKey, err := GetSubnetKeyFromMinIOConfig(ctx, minioClient) if err != nil { return nil, err @@ -210,10 +214,9 @@ func GetSubnetHTTPClient(ctx context.Context, minioClient MinioAdmin) (*xhttp.Cl if err != nil { return nil, err } - subnetHTTPClient.Transport.(*http.Transport).Proxy = http.ProxyURL(subnetProxyURL) - } else { - subnetHTTPClient = GetConsoleHTTPClient("") + subnetHTTPClient.Transport.(*ConsoleTransport).Transport.Proxy = http.ProxyURL(subnetProxyURL) } + clientI := &xhttp.Client{ Client: subnetHTTPClient, } @@ -223,7 +226,7 @@ func GetSubnetHTTPClient(ctx context.Context, minioClient MinioAdmin) (*xhttp.Cl func GetSubnetLoginWithMFAResponse(session *models.Principal, params subnetApi.SubnetLoginMFAParams) (*models.SubnetLoginResponse, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -292,7 +295,7 @@ func GetSubnetRegister(ctx context.Context, minioClient MinioAdmin, httpClient x func GetSubnetRegisterResponse(session *models.Principal, params subnetApi.SubnetRegisterParams) *models.Error { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return ErrorWithContext(ctx, err) } @@ -317,14 +320,15 @@ var ErrSubnetLicenseNotFound = errors.New("license not found") func GetSubnetInfoResponse(session *models.Principal, params subnetApi.SubnetInfoParams) (*models.License, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() + clientIP := utils.ClientIPFromContext(ctx) client := &xhttp.Client{ - Client: GetConsoleHTTPClient(""), + Client: GetConsoleHTTPClient("", clientIP), } // license gets seeded to us by MinIO seededLicense := os.Getenv(EnvSubnetLicense) // if it's missing, we will gracefully fallback to attempt to fetch it from MinIO if seededLicense == "" { - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -383,7 +387,7 @@ func GetSubnetRegToken(ctx context.Context, minioClient MinioAdmin) (string, err func GetSubnetRegTokenResponse(session *models.Principal, params subnetApi.SubnetRegTokenParams) (*models.SubnetRegTokenResponse, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -404,7 +408,7 @@ func subnetRegTokenResponse(ctx context.Context, minioClient MinioAdmin) (*model func GetSubnetAPIKeyResponse(session *models.Principal, params subnetApi.SubnetAPIKeyParams) (*models.APIKey, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } diff --git a/restapi/admin_tiers.go b/restapi/admin_tiers.go index 1f4a2b7d3..21b8e756d 100644 --- a/restapi/admin_tiers.go +++ b/restapi/admin_tiers.go @@ -177,7 +177,7 @@ func getTiers(ctx context.Context, client MinioAdmin) (*models.TierListResponse, func getTiersResponse(session *models.Principal, params tieringApi.TiersListParams) (*models.TierListResponse, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -279,7 +279,7 @@ func addTier(ctx context.Context, client MinioAdmin, params *tieringApi.AddTierP func getAddTierResponse(session *models.Principal, params tieringApi.AddTierParams) *models.Error { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return ErrorWithContext(ctx, err) } @@ -361,7 +361,7 @@ func getTier(ctx context.Context, client MinioAdmin, params *tieringApi.GetTierP func getGetTierResponse(session *models.Principal, params tieringApi.GetTierParams) (*models.Tier, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -395,7 +395,7 @@ func editTierCredentials(ctx context.Context, client MinioAdmin, params *tiering func getEditTierCredentialsResponse(session *models.Principal, params tieringApi.EditTierCredentialsParams) *models.Error { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return ErrorWithContext(ctx, err) } diff --git a/restapi/admin_users.go b/restapi/admin_users.go index 5dfcc8314..9768ea35a 100644 --- a/restapi/admin_users.go +++ b/restapi/admin_users.go @@ -157,7 +157,7 @@ func listUsers(ctx context.Context, client MinioAdmin) ([]*models.User, error) { func getListUsersResponse(session *models.Principal, params userApi.ListUsersParams) (*models.ListUsersResponse, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -218,7 +218,7 @@ func addUser(ctx context.Context, client MinioAdmin, accessKey, secretKey *strin func getUserAddResponse(session *models.Principal, params userApi.AddUserParams) (*models.User, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -255,7 +255,7 @@ func removeUser(ctx context.Context, client MinioAdmin, accessKey string) error func getRemoveUserResponse(session *models.Principal, params userApi.RemoveUserParams) *models.Error { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return ErrorWithContext(ctx, err) } @@ -288,7 +288,7 @@ func getUserInfoResponse(session *models.Principal, params userApi.GetUserInfoPa ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -439,7 +439,7 @@ func getUpdateUserGroupsResponse(session *models.Principal, params userApi.Updat ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -480,7 +480,7 @@ func getUpdateUserResponse(session *models.Principal, params userApi.UpdateUserI ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -554,7 +554,7 @@ func getAddUsersListToGroupsResponse(session *models.Principal, params userApi.B ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return ErrorWithContext(ctx, err) } @@ -576,7 +576,7 @@ func getAddUsersListToGroupsResponse(session *models.Principal, params userApi.B func getListUsersWithAccessToBucketResponse(session *models.Principal, params bucketApi.ListUsersWithAccessToBucketParams) ([]string, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -687,7 +687,7 @@ func changeUserPassword(ctx context.Context, client MinioAdmin, selectedUser str func getChangeUserPasswordResponse(session *models.Principal, params accountApi.ChangeUserPasswordParams) *models.Error { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return ErrorWithContext(ctx, err) } @@ -709,7 +709,7 @@ func getChangeUserPasswordResponse(session *models.Principal, params accountApi. func getCheckUserSAResponse(session *models.Principal, params userApi.CheckUserServiceAccountsParams) (*models.UserServiceAccountSummary, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } diff --git a/restapi/client-admin.go b/restapi/client-admin.go index 0850b7e18..96e9f3c8e 100644 --- a/restapi/client-admin.go +++ b/restapi/client-admin.go @@ -24,45 +24,21 @@ import ( "net" "net/http" "net/url" + "strings" "sync" "time" + "github.com/minio/console/pkg/utils" + "github.com/minio/console/models" - "github.com/minio/console/pkg" "github.com/minio/madmin-go/v2" mcCmd "github.com/minio/mc/cmd" - "github.com/minio/mc/pkg/probe" "github.com/minio/minio-go/v7/pkg/credentials" iampolicy "github.com/minio/pkg/iam/policy" ) const globalAppName = "MinIO Console" -// NewAdminClientWithInsecure gives a new madmin client interface either secure or insecure based on parameter -func NewAdminClientWithInsecure(url, accessKey, secretKey, sessionToken string, insecure bool) (*madmin.AdminClient, *probe.Error) { - admClient, err := s3AdminNew(&mcCmd.Config{ - HostURL: url, - AccessKey: accessKey, - SecretKey: secretKey, - SessionToken: sessionToken, - AppName: globalAppName, - AppVersion: pkg.Version, - Insecure: insecure, - }) - if err != nil { - return nil, err.Trace(url) - } - stsClient := PrepareConsoleHTTPClient(insecure) - admClient.SetCustomTransport(stsClient.Transport) - // set user-agent to differentiate Console UI requests for auditing. - admClient.SetAppInfo("MinIO Console", pkg.Version) - return admClient, nil -} - -// s3AdminNew returns an initialized minioAdmin structure. If debug is enabled, -// it also enables an internal trace transport. -var s3AdminNew = mcCmd.NewAdminFactory() - // MinioAdmin interface with all functions to be implemented // by mock when testing, it should include all MinioAdmin respective api calls // that are used within this project. @@ -86,7 +62,6 @@ type MinioAdmin interface { helpConfigKVGlobal(ctx context.Context, envOnly bool) (madmin.Help, error) setConfigKV(ctx context.Context, kv string) (restart bool, err error) delConfigKV(ctx context.Context, kv string) (err error) - serviceRestart(ctx context.Context) error serverInfo(ctx context.Context) (madmin.InfoMessage, error) startProfiling(ctx context.Context, profiler madmin.ProfilerType) ([]madmin.StartProfilingResult, error) @@ -347,7 +322,6 @@ func (ac AdminClient) addServiceAccount(ctx context.Context, policy *iampolicy.P // implements madmin.ListServiceAccounts() func (ac AdminClient) listServiceAccounts(ctx context.Context, user string) (madmin.ListServiceAccountsResp, error) { - // TODO: Fix this return ac.Client.ListServiceAccounts(ctx, user) } @@ -485,8 +459,9 @@ func (ac AdminClient) verifyTierStatus(ctx context.Context, tierName string) err return ac.Client.VerifyTier(ctx, tierName) } -func NewMinioAdminClient(sessionClaims *models.Principal) (*madmin.AdminClient, error) { - adminClient, err := newAdminFromClaims(sessionClaims) +func NewMinioAdminClient(ctx context.Context, sessionClaims *models.Principal) (*madmin.AdminClient, error) { + clientIP := utils.ClientIPFromContext(ctx) + adminClient, err := newAdminFromClaims(sessionClaims, clientIP) if err != nil { return nil, err } @@ -494,7 +469,7 @@ func NewMinioAdminClient(sessionClaims *models.Principal) (*madmin.AdminClient, } // newAdminFromClaims creates a minio admin from Decrypted claims using Assume role credentials -func newAdminFromClaims(claims *models.Principal) (*madmin.AdminClient, error) { +func newAdminFromClaims(claims *models.Principal, clientIP string) (*madmin.AdminClient, error) { tlsEnabled := getMinIOEndpointIsSecure() endpoint := getMinIOEndpoint() @@ -505,7 +480,7 @@ func newAdminFromClaims(claims *models.Principal) (*madmin.AdminClient, error) { if err != nil { return nil, err } - adminClient.SetCustomTransport(GetConsoleHTTPClient(getMinIOServer()).Transport) + adminClient.SetCustomTransport(GetConsoleHTTPClient(getMinIOServer(), clientIP).Transport) return adminClient, nil } @@ -554,7 +529,7 @@ func isLocalIPAddress(ipAddr string) bool { // GetConsoleHTTPClient caches different http clients depending on the target endpoint while taking // in consideration CA certs stored in ${HOME}/.console/certs/CAs and ${HOME}/.minio/certs/CAs // If the target endpoint points to a loopback device, skip the TLS verification. -func GetConsoleHTTPClient(address string) *http.Client { +func GetConsoleHTTPClient(address string, clientIP string) *http.Client { u, err := url.Parse(address) if err == nil { address = u.Hostname() @@ -567,13 +542,41 @@ func GetConsoleHTTPClient(address string) *http.Client { return client } - client = PrepareConsoleHTTPClient(isLocalIPAddress(address)) + client = PrepareConsoleHTTPClient(isLocalIPAddress(address), clientIP) httpClients.Lock() httpClients.m[address] = client httpClients.Unlock() return client } +func getClientIP(r *http.Request) string { + // Try to get the IP address from the X-Real-IP header + // If the X-Real-IP header is not present, then it will return an empty string + xRealIP := r.Header.Get("X-Real-IP") + if xRealIP != "" { + return xRealIP + } + + // Try to get the IP address from the X-Forwarded-For header + // If the X-Forwarded-For header is not present, then it will return an empty string + xForwardedFor := r.Header.Get("X-Forwarded-For") + if xForwardedFor != "" { + // X-Forwarded-For can contain multiple addresses, we return the first one + split := strings.Split(xForwardedFor, ",") + if len(split) > 0 { + return strings.TrimSpace(split[0]) + } + } + + // If neither header is present (or they were empty), then fall back to the connection's remote address + ip, _, err := net.SplitHostPort(r.RemoteAddr) + if err != nil { + // In case there's an error, return an empty string + return "" + } + return ip +} + func (ac AdminClient) speedtest(ctx context.Context, opts madmin.SpeedtestOpts) (chan madmin.SpeedTestResult, error) { return ac.Client.Speedtest(ctx, opts) } diff --git a/restapi/client.go b/restapi/client.go index ebbf96362..b8b7662ee 100644 --- a/restapi/client.go +++ b/restapi/client.go @@ -329,7 +329,7 @@ func (s consoleSTSAssumeRole) IsExpired() bool { return s.stsAssumeRole.IsExpired() } -func stsCredentials(minioURL, accessKey, secretKey, location string) (*credentials.Credentials, error) { +func stsCredentials(minioURL, accessKey, secretKey, location, clientIP string) (*credentials.Credentials, error) { if accessKey == "" || secretKey == "" { return nil, errors.New("credentials endpoint, access and secret key are mandatory for AssumeRoleSTS") } @@ -340,7 +340,7 @@ func stsCredentials(minioURL, accessKey, secretKey, location string) (*credentia DurationSeconds: int(xjwt.GetConsoleSTSDuration().Seconds()), } stsAssumeRole := &credentials.STSAssumeRole{ - Client: GetConsoleHTTPClient(minioURL), + Client: GetConsoleHTTPClient(minioURL, clientIP), STSEndpoint: minioURL, Options: opts, } @@ -348,7 +348,7 @@ func stsCredentials(minioURL, accessKey, secretKey, location string) (*credentia return credentials.New(consoleSTSWrapper), nil } -func NewConsoleCredentials(accessKey, secretKey, location string) (*credentials.Credentials, error) { +func NewConsoleCredentials(accessKey, secretKey, location, clientIP string) (*credentials.Credentials, error) { minioURL := getMinIOServer() // Future authentication methods can be added under this switch statement @@ -356,7 +356,7 @@ func NewConsoleCredentials(accessKey, secretKey, location string) (*credentials. // LDAP authentication for Console case ldap.GetLDAPEnabled(): { - creds, err := auth.GetCredentialsFromLDAP(GetConsoleHTTPClient(minioURL), minioURL, accessKey, secretKey) + creds, err := auth.GetCredentialsFromLDAP(GetConsoleHTTPClient(minioURL, clientIP), minioURL, accessKey, secretKey) if err != nil { return nil, err } @@ -366,7 +366,7 @@ func NewConsoleCredentials(accessKey, secretKey, location string) (*credentials. if err != nil && strings.Contains(strings.ToLower(err.Error()), "not found") { // We try to use STS Credentials in case LDAP credentials are incorrect. - stsCreds, errSTS := stsCredentials(minioURL, accessKey, secretKey, location) + stsCreds, errSTS := stsCredentials(minioURL, accessKey, secretKey, location, clientIP) // If there is an error with STS too, then we return the original LDAP error if errSTS != nil { @@ -390,7 +390,7 @@ func NewConsoleCredentials(accessKey, secretKey, location string) (*credentials. // default authentication for Console is via STS (Security Token Service) against MinIO default: { - return stsCredentials(minioURL, accessKey, secretKey, location) + return stsCredentials(minioURL, accessKey, secretKey, location, clientIP) } } } @@ -406,14 +406,14 @@ func getConsoleCredentialsFromSession(claims *models.Principal) *credentials.Cre // newMinioClient creates a new MinIO client based on the ConsoleCredentials extracted // from the provided session token -func newMinioClient(claims *models.Principal) (*minio.Client, error) { +func newMinioClient(claims *models.Principal, clientIP string) (*minio.Client, error) { creds := getConsoleCredentialsFromSession(claims) endpoint := getMinIOEndpoint() secure := getMinIOEndpointIsSecure() minioClient, err := minio.New(endpoint, &minio.Options{ Creds: creds, Secure: secure, - Transport: GetConsoleHTTPClient(getMinIOServer()).Transport, + Transport: GetConsoleHTTPClient(getMinIOServer(), clientIP).Transport, }) if err != nil { return nil, err @@ -441,7 +441,7 @@ func computeObjectURLWithoutEncode(bucketName, prefix string) (string, error) { } // newS3BucketClient creates a new mc S3Client to talk to the server based on a bucket -func newS3BucketClient(claims *models.Principal, bucketName string, prefix string) (*mc.S3Client, error) { +func newS3BucketClient(claims *models.Principal, bucketName string, prefix string, clientIP string) (*mc.S3Client, error) { if claims == nil { return nil, fmt.Errorf("the provided credentials are invalid") } @@ -450,7 +450,7 @@ func newS3BucketClient(claims *models.Principal, bucketName string, prefix strin if err != nil { return nil, fmt.Errorf("the provided endpoint is invalid") } - s3Config := newS3Config(objectURL, claims.STSAccessKeyID, claims.STSSecretAccessKey, claims.STSSessionToken) + s3Config := newS3Config(objectURL, claims.STSAccessKeyID, claims.STSSecretAccessKey, claims.STSSessionToken, clientIP) client, pErr := mc.S3New(s3Config) if pErr != nil { return nil, pErr.Cause @@ -472,9 +472,10 @@ func pathJoinFinalSlash(elem ...string) string { return path.Join(elem...) } +// Deprecated // newS3Config simply creates a new Config struct using the passed // parameters. -func newS3Config(endpoint, accessKey, secretKey, sessionToken string) *mc.Config { +func newS3Config(endpoint, accessKey, secretKey, sessionToken string, clientIP string) *mc.Config { // We have a valid alias and hostConfig. We populate the/ // consoleCredentials from the match found in the config file. s3Config := new(mc.Config) @@ -492,7 +493,7 @@ func newS3Config(endpoint, accessKey, secretKey, sessionToken string) *mc.Config insecure := isLocalIPEndpoint(endpoint) s3Config.Insecure = insecure - s3Config.Transport = PrepareSTSClientTransport(insecure) + s3Config.Transport = PrepareSTSClientTransport(insecure, clientIP).Transport return s3Config } diff --git a/restapi/configure_console.go b/restapi/configure_console.go index 27a6dd984..0b7e07734 100644 --- a/restapi/configure_console.go +++ b/restapi/configure_console.go @@ -65,7 +65,7 @@ const ( ) var ( - subPath = "/" + cfgSubPath = "/" subPathOnce sync.Once ) @@ -203,6 +203,7 @@ func ContextMiddleware(next http.Handler) http.Handler { ctx = context.WithValue(ctx, utils.ContextRequestUserAgent, r.UserAgent()) ctx = context.WithValue(ctx, utils.ContextRequestHost, r.Host) ctx = context.WithValue(ctx, utils.ContextRequestRemoteAddr, r.RemoteAddr) + ctx = context.WithValue(ctx, utils.ContextClientIP, getClientIP(r)) next.ServeHTTP(w, r.WithContext(ctx)) }) } @@ -471,9 +472,9 @@ func configureServer(s *http.Server, _, _ string) { func getSubPath() string { subPathOnce.Do(func() { - subPath = parseSubPath(env.Get(SubPath, "")) + cfgSubPath = parseSubPath(env.Get(SubPath, "")) }) - return subPath + return cfgSubPath } func parseSubPath(v string) string { @@ -483,7 +484,7 @@ func parseSubPath(v string) string { } // Replace all unnecessary `\` to `/` // also add pro-actively at the end. - subPath = path.Clean(filepath.ToSlash(v)) + subPath := path.Clean(filepath.ToSlash(v)) if !strings.HasPrefix(subPath, SlashSeparator) { subPath = SlashSeparator + subPath } diff --git a/restapi/consts.go b/restapi/consts.go index ed3b4c45e..d05debd4a 100644 --- a/restapi/consts.go +++ b/restapi/consts.go @@ -57,4 +57,5 @@ const ( ConsoleAnimatedLogin = "CONSOLE_ANIMATED_LOGIN" LogSearchQueryAuthToken = "LOGSEARCH_QUERY_AUTH_TOKEN" SlashSeparator = "/" + LocalAddress = "127.0.0.1" ) diff --git a/restapi/license.go b/restapi/license.go index f3d060c52..27eebb8f7 100644 --- a/restapi/license.go +++ b/restapi/license.go @@ -44,7 +44,7 @@ func (sp SubnetPlan) String() string { var InstanceLicensePlan = PlanAGPL func fetchLicensePlan() { - licenseInfo, err := subnet.ParseLicense(GetConsoleHTTPClient(""), os.Getenv(EnvSubnetLicense)) + licenseInfo, err := subnet.ParseLicense(GetConsoleHTTPClient("", "127.0.0.1"), os.Getenv(EnvSubnetLicense)) if err != nil { return } diff --git a/restapi/user_service_accounts.go b/restapi/service_accounts_handlers.go similarity index 96% rename from restapi/user_service_accounts.go rename to restapi/service_accounts_handlers.go index 1839f1fc8..14e3b1ed6 100644 --- a/restapi/user_service_accounts.go +++ b/restapi/service_accounts_handlers.go @@ -167,7 +167,7 @@ func getCreateServiceAccountResponse(session *models.Principal, params saApi.Cre ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - userAdmin, err := NewMinioAdminClient(session) + userAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -228,7 +228,7 @@ func getCreateAUserServiceAccountResponse(session *models.Principal, params user ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - userAdmin, err := NewMinioAdminClient(session) + userAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -251,7 +251,8 @@ func getCreateAUserServiceAccountResponse(session *models.Principal, params user func getCreateAUserServiceAccountCredsResponse(session *models.Principal, params userApi.CreateServiceAccountCredentialsParams) (*models.ServiceAccountCreds, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - userAdmin, err := NewMinioAdminClient(session) + + userAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -286,7 +287,7 @@ func getCreateServiceAccountCredsResponse(session *models.Principal, params saAp ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() serviceAccount := params.Body - userAdmin, err := NewMinioAdminClient(session) + userAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -332,7 +333,7 @@ func getUserServiceAccounts(ctx context.Context, userClient MinioAdmin, user str // getUserServiceAccountsResponse authenticates the user and calls // getUserServiceAccounts to list the user's service accounts func getUserServiceAccountsResponse(ctx context.Context, session *models.Principal, user string) (models.ServiceAccounts, *models.Error) { - userAdmin, err := NewMinioAdminClient(session) + userAdmin, err := NewMinioAdminClient(ctx, session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -363,7 +364,7 @@ func getDeleteServiceAccountResponse(session *models.Principal, params saApi.Del if err != nil { return ErrorWithContext(ctx, err) } - userAdmin, err := NewMinioAdminClient(session) + userAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return ErrorWithContext(ctx, err) } @@ -399,7 +400,7 @@ func getServiceAccountPolicyResponse(session *models.Principal, params saApi.Get if err != nil { return "", ErrorWithContext(ctx, err) } - userAdmin, err := NewMinioAdminClient(session) + userAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return "", ErrorWithContext(ctx, err) } @@ -430,7 +431,7 @@ func getSetServiceAccountPolicyResponse(session *models.Principal, params saApi. return ErrorWithContext(ctx, err) } policy := *params.Policy.Policy - userAdmin, err := NewMinioAdminClient(session) + userAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return ErrorWithContext(ctx, err) } @@ -450,7 +451,7 @@ func getDeleteMultipleServiceAccountsResponse(session *models.Principal, params ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() selectedSAs := params.SelectedSA - userAdmin, err := NewMinioAdminClient(session) + userAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return ErrorWithContext(ctx, err) } diff --git a/restapi/user_service_accounts_test.go b/restapi/service_accounts_handlers_test.go similarity index 100% rename from restapi/user_service_accounts_test.go rename to restapi/service_accounts_handlers_test.go diff --git a/restapi/tls.go b/restapi/tls.go index 5ddeff567..b20f23f60 100644 --- a/restapi/tls.go +++ b/restapi/tls.go @@ -23,8 +23,19 @@ import ( "time" ) +type ConsoleTransport struct { + Transport *http.Transport + ClientIP string +} + +func (t *ConsoleTransport) RoundTrip(req *http.Request) (*http.Response, error) { + req.Header.Add("X-Forwarded-For", t.ClientIP) + resp, err := t.Transport.RoundTrip(req) + return resp, err +} + // PrepareSTSClientTransport : -func PrepareSTSClientTransport(insecure bool) *http.Transport { +func PrepareSTSClientTransport(insecure bool, remoteAddress string) *ConsoleTransport { // This takes github.com/minio/madmin-go/v2/transport.go as an example // // DefaultTransport - this default transport is similar to @@ -51,13 +62,17 @@ func PrepareSTSClientTransport(insecure bool) *http.Transport { RootCAs: GlobalRootCAs, }, } - return DefaultTransport + t := &ConsoleTransport{ + Transport: DefaultTransport, + ClientIP: remoteAddress, + } + return t } // PrepareConsoleHTTPClient returns an http.Client with custom configurations need it by *credentials.STSAssumeRole // custom configurations include the use of CA certificates -func PrepareConsoleHTTPClient(insecure bool) *http.Client { - transport := PrepareSTSClientTransport(insecure) +func PrepareConsoleHTTPClient(insecure bool, clientIP string) *http.Client { + transport := PrepareSTSClientTransport(insecure, clientIP) // Return http client with default configuration c := &http.Client{ Transport: transport, diff --git a/restapi/user_account.go b/restapi/user_account.go index d8f81645a..944ba1777 100644 --- a/restapi/user_account.go +++ b/restapi/user_account.go @@ -57,9 +57,11 @@ func changePassword(ctx context.Context, client MinioAdmin, session *models.Prin func getChangePasswordResponse(session *models.Principal, params accountApi.AccountChangePasswordParams) (*models.LoginResponse, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() + clientIP := getClientIP(params.HTTPRequest) + // changePassword operations requires an AdminClient initialized with parent account credentials not // STS credentials - parentAccountClient, err := NewMinioAdminClient(&models.Principal{ + parentAccountClient, err := NewMinioAdminClient(params.HTTPRequest.Context(), &models.Principal{ STSAccessKeyID: session.AccountAccessKey, STSSecretAccessKey: *params.Body.CurrentSecretKey, }) @@ -77,7 +79,7 @@ func getChangePasswordResponse(session *models.Principal, params accountApi.Acco } // user credentials are updated at this point, we need to generate a new admin client and authenticate using // the new credentials - credentials, err := getConsoleCredentials(accessKey, newSecretKey) + credentials, err := getConsoleCredentials(accessKey, newSecretKey, clientIP) if err != nil { return nil, ErrorWithContext(ctx, ErrInvalidLogin, nil, err) } diff --git a/restapi/user_bucket_quota.go b/restapi/user_bucket_quota.go index 346a97b10..da8920006 100644 --- a/restapi/user_bucket_quota.go +++ b/restapi/user_bucket_quota.go @@ -53,7 +53,7 @@ func registerBucketQuotaHandlers(api *operations.ConsoleAPI) { func setBucketQuotaResponse(session *models.Principal, params bucektApi.SetBucketQuotaParams) *models.Error { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return ErrorWithContext(ctx, err) } @@ -95,7 +95,7 @@ func setBucketQuota(ctx context.Context, ac *AdminClient, bucket *string, bucket func getBucketQuotaResponse(session *models.Principal, params bucektApi.GetBucketQuotaParams) (*models.BucketQuota, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } diff --git a/restapi/user_buckets.go b/restapi/user_buckets.go index 55a0c6d13..06639c3f7 100644 --- a/restapi/user_buckets.go +++ b/restapi/user_buckets.go @@ -188,8 +188,8 @@ const ( ) // removeBucket deletes a bucket -func doSetVersioning(client MCClient, state VersionState) error { - err := client.setVersioning(context.Background(), string(state)) +func doSetVersioning(ctx context.Context, client MCClient, state VersionState) error { + err := client.setVersioning(ctx, string(state)) if err != nil { return err.Cause } @@ -202,7 +202,7 @@ func setBucketVersioningResponse(session *models.Principal, params bucketApi.Set defer cancel() bucketName := params.BucketName - s3Client, err := newS3BucketClient(session, bucketName, "") + s3Client, err := newS3BucketClient(session, bucketName, "", getClientIP(params.HTTPRequest)) if err != nil { return ErrorWithContext(ctx, err) } @@ -216,7 +216,7 @@ func setBucketVersioningResponse(session *models.Principal, params bucketApi.Set versioningState = VersionEnable } - if err := doSetVersioning(amcClient, versioningState); err != nil { + if err := doSetVersioning(ctx, amcClient, versioningState); err != nil { return ErrorWithContext(ctx, fmt.Errorf("error setting versioning for bucket: %s", err)) } return nil @@ -226,7 +226,7 @@ func getBucketReplicationResponse(session *models.Principal, params bucketApi.Ge ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mClient, err := newMinioClient(session) + mClient, err := newMinioClient(session, getClientIP(params.HTTPRequest)) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -276,7 +276,7 @@ func getBucketReplicationRuleResponse(session *models.Principal, params bucketAp ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mClient, err := newMinioClient(session) + mClient, err := newMinioClient(session, getClientIP(params.HTTPRequest)) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -343,7 +343,7 @@ func getBucketVersionedResponse(session *models.Principal, params bucketApi.GetB ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mClient, err := newMinioClient(session) + mClient, err := newMinioClient(session, getClientIP(params.HTTPRequest)) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -424,7 +424,7 @@ func getListBucketsResponse(session *models.Principal, params bucketApi.ListBuck ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -459,7 +459,7 @@ func getMakeBucketResponse(session *models.Principal, params bucketApi.MakeBucke if br == nil { return nil, ErrorWithContext(ctx, ErrBucketBodyNotInRequest) } - mClient, err := newMinioClient(session) + mClient, err := newMinioClient(session, getClientIP(params.HTTPRequest)) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -488,7 +488,7 @@ func getMakeBucketResponse(session *models.Principal, params bucketApi.MakeBucke // enable versioning if indicated or retention enabled if br.Versioning || br.Retention != nil { - s3Client, err := newS3BucketClient(session, *br.Name, "") + s3Client, err := newS3BucketClient(session, *br.Name, "", getClientIP(params.HTTPRequest)) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -496,14 +496,14 @@ func getMakeBucketResponse(session *models.Principal, params bucketApi.MakeBucke // defining the client to be used amcClient := mcClient{client: s3Client} - if err = doSetVersioning(amcClient, VersionEnable); err != nil { + if err = doSetVersioning(ctx, amcClient, VersionEnable); err != nil { return nil, ErrorWithContext(ctx, fmt.Errorf("error setting versioning for bucket: %s", err)) } } // if it has support for if br.Quota != nil && br.Quota.Enabled != nil && *br.Quota.Enabled { - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -564,7 +564,7 @@ func getBucketSetPolicyResponse(session *models.Principal, params bucketApi.Buck defer cancel() // get updated bucket details and return it - mClient, err := newMinioClient(session) + mClient, err := newMinioClient(session, getClientIP(params.HTTPRequest)) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -572,7 +572,7 @@ func getBucketSetPolicyResponse(session *models.Principal, params bucketApi.Buck // defining the client to be used minioClient := minioClient{client: mClient} - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -597,7 +597,7 @@ func getPutBucketTagsResponse(session *models.Principal, params bucketApi.PutBuc ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mClient, err := newMinioClient(session) + mClient, err := newMinioClient(session, getClientIP(params.HTTPRequest)) if err != nil { return ErrorWithContext(ctx, err) } @@ -635,7 +635,7 @@ func getDeleteBucketResponse(session *models.Principal, params bucketApi.DeleteB } bucketName := params.Name - mClient, err := newMinioClient(session) + mClient, err := newMinioClient(session, getClientIP(params.HTTPRequest)) if err != nil { return ErrorWithContext(ctx, err) } @@ -714,7 +714,7 @@ func getBucketInfo(ctx context.Context, client MinioClient, adminClient MinioAdm func getBucketInfoResponse(session *models.Principal, params bucketApi.BucketInfoParams) (*models.Bucket, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mClient, err := newMinioClient(session) + mClient, err := newMinioClient(session, getClientIP(params.HTTPRequest)) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -722,7 +722,7 @@ func getBucketInfoResponse(session *models.Principal, params bucketApi.BucketInf // defining the client to be used minioClient := minioClient{client: mClient} - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -779,7 +779,7 @@ func enableBucketEncryption(ctx context.Context, client MinioClient, bucketName func enableBucketEncryptionResponse(session *models.Principal, params bucketApi.EnableBucketEncryptionParams) *models.Error { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mClient, err := newMinioClient(session) + mClient, err := newMinioClient(session, getClientIP(params.HTTPRequest)) if err != nil { return ErrorWithContext(ctx, err) } @@ -801,7 +801,7 @@ func disableBucketEncryption(ctx context.Context, client MinioClient, bucketName func disableBucketEncryptionResponse(session *models.Principal, params bucketApi.DisableBucketEncryptionParams) *models.Error { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mClient, err := newMinioClient(session) + mClient, err := newMinioClient(session, getClientIP(params.HTTPRequest)) if err != nil { return ErrorWithContext(ctx, err) } @@ -828,7 +828,7 @@ func getBucketEncryptionInfo(ctx context.Context, client MinioClient, bucketName func getBucketEncryptionInfoResponse(session *models.Principal, params bucketApi.GetBucketEncryptionInfoParams) (*models.BucketEncryptionInfo, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mClient, err := newMinioClient(session) + mClient, err := newMinioClient(session, getClientIP(params.HTTPRequest)) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -875,7 +875,7 @@ func setBucketRetentionConfig(ctx context.Context, client MinioClient, bucketNam func getSetBucketRetentionConfigResponse(session *models.Principal, params bucketApi.SetBucketRetentionConfigParams) *models.Error { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mClient, err := newMinioClient(session) + mClient, err := newMinioClient(session, getClientIP(params.HTTPRequest)) if err != nil { return ErrorWithContext(ctx, err) } @@ -948,7 +948,7 @@ func getBucketRetentionConfigResponse(session *models.Principal, params bucketAp ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() bucketName := params.BucketName - mClient, err := newMinioClient(session) + mClient, err := newMinioClient(session, getClientIP(params.HTTPRequest)) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -968,7 +968,7 @@ func getBucketObjectLockingResponse(session *models.Principal, params bucketApi. ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() bucketName := params.BucketName - mClient, err := newMinioClient(session) + mClient, err := newMinioClient(session, getClientIP(params.HTTPRequest)) if err != nil { return nil, ErrorWithContext(ctx, fmt.Errorf("error creating MinIO Client: %v", err)) } @@ -1005,7 +1005,7 @@ func getBucketRewindResponse(session *models.Principal, params bucketApi.GetBuck } prefix = string(decodedPrefix) } - s3Client, err := newS3BucketClient(session, params.BucketName, prefix) + s3Client, err := newS3BucketClient(session, params.BucketName, prefix, getClientIP(params.HTTPRequest)) if err != nil { return nil, ErrorWithContext(ctx, fmt.Errorf("error creating S3Client: %v", err)) } diff --git a/restapi/user_buckets_events.go b/restapi/user_buckets_events.go index ae9c24ecb..a80b448d1 100644 --- a/restapi/user_buckets_events.go +++ b/restapi/user_buckets_events.go @@ -132,7 +132,7 @@ func listBucketEvents(client MinioClient, bucketName string) ([]*models.Notifica func getListBucketEventsResponse(session *models.Principal, params bucketApi.ListBucketEventsParams) (*models.ListBucketEventsResponse, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mClient, err := newMinioClient(session) + mClient, err := newMinioClient(session, getClientIP(params.HTTPRequest)) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -187,7 +187,7 @@ func getCreateBucketEventsResponse(session *models.Principal, params bucketApi.C defer cancel() bucketName := params.BucketName eventReq := params.Body - s3Client, err := newS3BucketClient(session, bucketName, "") + s3Client, err := newS3BucketClient(session, bucketName, "", getClientIP(params.HTTPRequest)) if err != nil { return ErrorWithContext(ctx, err) } @@ -228,7 +228,7 @@ func getDeleteBucketEventsResponse(session *models.Principal, params bucketApi.D events := params.Body.Events prefix := params.Body.Prefix suffix := params.Body.Suffix - s3Client, err := newS3BucketClient(session, bucketName, "") + s3Client, err := newS3BucketClient(session, bucketName, "", getClientIP(params.HTTPRequest)) if err != nil { return ErrorWithContext(ctx, err) } diff --git a/restapi/user_buckets_lifecycle.go b/restapi/user_buckets_lifecycle.go index 1c4d8cf1e..33cdd4601 100644 --- a/restapi/user_buckets_lifecycle.go +++ b/restapi/user_buckets_lifecycle.go @@ -142,7 +142,7 @@ func getBucketLifecycle(ctx context.Context, client MinioClient, bucketName stri func getBucketLifecycleResponse(session *models.Principal, params bucketApi.GetBucketLifecycleParams) (*models.BucketLifecycleResponse, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mClient, err := newMinioClient(session) + mClient, err := newMinioClient(session, getClientIP(params.HTTPRequest)) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -245,7 +245,7 @@ func addBucketLifecycle(ctx context.Context, client MinioClient, params bucketAp func getAddBucketLifecycleResponse(session *models.Principal, params bucketApi.AddBucketLifecycleParams) *models.Error { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mClient, err := newMinioClient(session) + mClient, err := newMinioClient(session, getClientIP(params.HTTPRequest)) if err != nil { return ErrorWithContext(ctx, err) } @@ -358,7 +358,7 @@ func editBucketLifecycle(ctx context.Context, client MinioClient, params bucketA func getEditBucketLifecycleRule(session *models.Principal, params bucketApi.UpdateBucketLifecycleParams) *models.Error { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mClient, err := newMinioClient(session) + mClient, err := newMinioClient(session, getClientIP(params.HTTPRequest)) if err != nil { return ErrorWithContext(ctx, err) } @@ -412,7 +412,7 @@ func deleteBucketLifecycle(ctx context.Context, client MinioClient, params bucke func getDeleteBucketLifecycleRule(session *models.Principal, params bucketApi.DeleteBucketLifecycleRuleParams) *models.Error { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mClient, err := newMinioClient(session) + mClient, err := newMinioClient(session, getClientIP(params.HTTPRequest)) if err != nil { return ErrorWithContext(ctx, err) } @@ -498,7 +498,7 @@ func addMultiBucketLifecycle(ctx context.Context, client MinioClient, params buc func getAddMultiBucketLifecycleResponse(session *models.Principal, params bucketApi.AddMultiBucketLifecycleParams) (*models.MultiLifecycleResult, *models.Error) { ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mClient, err := newMinioClient(session) + mClient, err := newMinioClient(session, getClientIP(params.HTTPRequest)) if err != nil { return nil, ErrorWithContext(ctx, err) } diff --git a/restapi/user_buckets_test.go b/restapi/user_buckets_test.go index bd16b0f66..2c0d580ac 100644 --- a/restapi/user_buckets_test.go +++ b/restapi/user_buckets_test.go @@ -24,6 +24,8 @@ import ( "testing" "time" + "github.com/minio/console/pkg/utils" + "github.com/go-openapi/swag" "github.com/minio/console/models" "github.com/minio/madmin-go/v2" @@ -805,7 +807,7 @@ func Test_GetBucketRetentionConfig(t *testing.T) { func Test_SetBucketVersioning(t *testing.T) { assert := assert.New(t) - ctx := context.Background() + ctx := context.WithValue(context.Background(), utils.ContextClientIP, "127.0.0.1") errorMsg := "Error Message" minClient := s3ClientMock{} type args struct { @@ -852,7 +854,7 @@ func Test_SetBucketVersioning(t *testing.T) { t.Run(tt.name, func(t *testing.T) { minioSetVersioningMock = tt.args.setVersioningFunc - err := doSetVersioning(tt.args.client, tt.args.state) + err := doSetVersioning(tt.args.ctx, tt.args.client, tt.args.state) fmt.Println(t.Name()) fmt.Println("Expected:", tt.expectedError, "Error:", err) diff --git a/restapi/user_log_search.go b/restapi/user_log_search.go index ff0cbc848..7690640ce 100644 --- a/restapi/user_log_search.go +++ b/restapi/user_log_search.go @@ -83,15 +83,15 @@ func getLogSearchResponse(session *models.Principal, params logApi.LogSearchPara endpoint = fmt.Sprintf("%s&pageSize=%d", endpoint, *params.PageSize) endpoint = fmt.Sprintf("%s&pageNo=%d", endpoint, *params.PageNo) - response, errLogSearch := logSearch(endpoint) + response, errLogSearch := logSearch(endpoint, getClientIP(params.HTTPRequest)) if errLogSearch != nil { return nil, ErrorWithContext(ctx, errLogSearch) } return response, nil } -func logSearch(endpoint string) (*models.LogSearchResponse, error) { - httpClnt := GetConsoleHTTPClient(endpoint) +func logSearch(endpoint string, clientIP string) (*models.LogSearchResponse, error) { + httpClnt := GetConsoleHTTPClient(endpoint, clientIP) resp, err := httpClnt.Get(endpoint) if err != nil { return nil, fmt.Errorf("the Log Search API cannot be reached. Please review the URL and try again %v", err) diff --git a/restapi/user_log_search_test.go b/restapi/user_log_search_test.go index 74afee0e1..f3c58b13c 100644 --- a/restapi/user_log_search_test.go +++ b/restapi/user_log_search_test.go @@ -104,7 +104,7 @@ func TestLogSearch(t *testing.T) { })) defer testRequest.Close() - resp, err := logSearch(testRequest.URL) + resp, err := logSearch(testRequest.URL, "127.0.0.1") if (err != nil) != tt.wantErr { t.Errorf("logSearch() error = %v, wantErr %v", err, tt.wantErr) diff --git a/restapi/user_login.go b/restapi/user_login.go index 96bfcbf7c..8a75337ee 100644 --- a/restapi/user_login.go +++ b/restapi/user_login.go @@ -111,8 +111,8 @@ func getAccountInfo(ctx context.Context, client MinioAdmin) (*madmin.AccountInfo } // getConsoleCredentials will return ConsoleCredentials interface -func getConsoleCredentials(accessKey, secretKey string) (*ConsoleCredentials, error) { - creds, err := NewConsoleCredentials(accessKey, secretKey, GetMinIORegion()) +func getConsoleCredentials(accessKey, secretKey, clientIP string) (*ConsoleCredentials, error) { + creds, err := NewConsoleCredentials(accessKey, secretKey, GetMinIORegion(), clientIP) if err != nil { return nil, err } @@ -144,8 +144,9 @@ func getLoginResponse(params authApi.LoginParams) (*models.LoginResponse, *model } } else { + clientIP := getClientIP(params.HTTPRequest) // prepare console credentials - consoleCreds, err = getConsoleCredentials(lr.AccessKey, lr.SecretKey) + consoleCreds, err = getConsoleCredentials(lr.AccessKey, lr.SecretKey, clientIP) if err != nil { return nil, ErrorWithContext(ctx, err, ErrInvalidLogin) } @@ -188,7 +189,7 @@ func getLoginDetailsResponse(params authApi.LoginDetailParams, openIDProviders o loginStrategy = models.LoginDetailsLoginStrategyRedirect for name, provider := range openIDProviders { // initialize new oauth2 client - oauth2Client, err := openIDProviders.NewOauth2ProviderClient(name, nil, r, GetConsoleHTTPClient(""), GetConsoleHTTPClient(getMinIOServer())) + oauth2Client, err := openIDProviders.NewOauth2ProviderClient(name, nil, r, GetConsoleHTTPClient("", getClientIP(params.HTTPRequest)), GetConsoleHTTPClient(getMinIOServer(), getClientIP(params.HTTPRequest))) if err != nil { return nil, ErrorWithContext(ctx, err, ErrOauth2Provider) } @@ -267,7 +268,8 @@ func getLoginOauth2AuthResponse(params authApi.LoginOauth2AuthParams, openIDProv IDPName := requestItems.IDPName state := requestItems.State providerCfg := openIDProviders[IDPName] - oauth2Client, err := openIDProviders.NewOauth2ProviderClient(IDPName, nil, r, GetConsoleHTTPClient(""), GetConsoleHTTPClient(getMinIOServer())) + + oauth2Client, err := openIDProviders.NewOauth2ProviderClient(IDPName, nil, r, GetConsoleHTTPClient("", getClientIP(params.HTTPRequest)), GetConsoleHTTPClient(getMinIOServer(), getClientIP(params.HTTPRequest))) if err != nil { return nil, ErrorWithContext(ctx, err) } diff --git a/restapi/user_objects.go b/restapi/user_objects.go index bc32008be..54e768b5b 100644 --- a/restapi/user_objects.go +++ b/restapi/user_objects.go @@ -31,6 +31,8 @@ import ( "strings" "time" + "github.com/minio/console/pkg/utils" + "github.com/go-openapi/runtime" "github.com/go-openapi/runtime/middleware" "github.com/klauspost/compress/zip" @@ -197,7 +199,7 @@ func getListObjectsResponse(session *models.Principal, params objectApi.ListObje if params.BucketName == "" { return nil, ErrorWithContext(ctx, ErrBucketNameNotInRequest) } - mClient, err := newMinioClient(session) + mClient, err := newMinioClient(session, getClientIP(params.HTTPRequest)) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -398,7 +400,7 @@ func parseRange(s string, size int64) ([]httpRange, error) { func getDownloadObjectResponse(session *models.Principal, params objectApi.DownloadObjectParams) (middleware.Responder, *models.Error) { ctx := params.HTTPRequest.Context() var prefix string - mClient, err := newMinioClient(session) + mClient, err := newMinioClient(session, getClientIP(params.HTTPRequest)) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -514,7 +516,7 @@ func getDownloadObjectResponse(session *models.Principal, params objectApi.Downl func getDownloadFolderResponse(session *models.Principal, params objectApi.DownloadObjectParams) (middleware.Responder, *models.Error) { ctx := params.HTTPRequest.Context() var prefix string - mClient, err := newMinioClient(session) + mClient, err := newMinioClient(session, getClientIP(params.HTTPRequest)) if params.Prefix != "" { encodedPrefix := SanitizeEncodedPrefix(params.Prefix) decodedPrefix, err := base64.StdEncoding.DecodeString(encodedPrefix) @@ -631,7 +633,7 @@ func getDeleteObjectResponse(session *models.Principal, params objectApi.DeleteO } prefix = string(decodedPrefix) } - s3Client, err := newS3BucketClient(session, params.BucketName, prefix) + s3Client, err := newS3BucketClient(session, params.BucketName, prefix, getClientIP(params.HTTPRequest)) if err != nil { return ErrorWithContext(ctx, err) } @@ -689,7 +691,7 @@ func getDeleteMultiplePathsResponse(session *models.Principal, params objectApi. version = params.Files[i].VersionID } prefix := params.Files[i].Path - s3Client, err := newS3BucketClient(session, params.BucketName, prefix) + s3Client, err := newS3BucketClient(session, params.BucketName, prefix, getClientIP(params.HTTPRequest)) if err != nil { return ErrorWithContext(ctx, err) } @@ -828,7 +830,7 @@ func deleteNonCurrentVersions(ctx context.Context, client MCClient, isBypass boo func getUploadObjectResponse(session *models.Principal, params objectApi.PostBucketsBucketNameObjectsUploadParams) *models.Error { ctx := params.HTTPRequest.Context() - mClient, err := newMinioClient(session) + mClient, err := newMinioClient(session, getClientIP(params.HTTPRequest)) if err != nil { return ErrorWithContext(ctx, err) } @@ -895,6 +897,7 @@ func uploadFiles(ctx context.Context, client MinioClient, params objectApi.PostB // getShareObjectResponse returns a share object url func getShareObjectResponse(session *models.Principal, params objectApi.ShareObjectParams) (*string, *models.Error) { ctx := params.HTTPRequest.Context() + clientIP := utils.ClientIPFromContext(ctx) var prefix string if params.Prefix != "" { encodedPrefix := SanitizeEncodedPrefix(params.Prefix) @@ -904,7 +907,7 @@ func getShareObjectResponse(session *models.Principal, params objectApi.ShareObj } prefix = string(decodedPrefix) } - s3Client, err := newS3BucketClient(session, params.BucketName, prefix) + s3Client, err := newS3BucketClient(session, params.BucketName, prefix, clientIP) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -941,7 +944,7 @@ func getShareObjectURL(ctx context.Context, client MCClient, versionID string, d func getSetObjectLegalHoldResponse(session *models.Principal, params objectApi.PutObjectLegalHoldParams) *models.Error { ctx := params.HTTPRequest.Context() - mClient, err := newMinioClient(session) + mClient, err := newMinioClient(session, getClientIP(params.HTTPRequest)) if err != nil { return ErrorWithContext(ctx, err) } @@ -976,7 +979,7 @@ func setObjectLegalHold(ctx context.Context, client MinioClient, bucketName, pre func getSetObjectRetentionResponse(session *models.Principal, params objectApi.PutObjectRetentionParams) *models.Error { ctx := params.HTTPRequest.Context() - mClient, err := newMinioClient(session) + mClient, err := newMinioClient(session, getClientIP(params.HTTPRequest)) if err != nil { return ErrorWithContext(ctx, err) } @@ -1028,7 +1031,7 @@ func setObjectRetention(ctx context.Context, client MinioClient, bucketName, ver func deleteObjectRetentionResponse(session *models.Principal, params objectApi.DeleteObjectRetentionParams) *models.Error { ctx := params.HTTPRequest.Context() - mClient, err := newMinioClient(session) + mClient, err := newMinioClient(session, getClientIP(params.HTTPRequest)) if err != nil { return ErrorWithContext(ctx, err) } @@ -1062,7 +1065,7 @@ func deleteObjectRetention(ctx context.Context, client MinioClient, bucketName, func getPutObjectTagsResponse(session *models.Principal, params objectApi.PutObjectTagsParams) *models.Error { ctx := params.HTTPRequest.Context() - mClient, err := newMinioClient(session) + mClient, err := newMinioClient(session, getClientIP(params.HTTPRequest)) if err != nil { return ErrorWithContext(ctx, err) } @@ -1099,7 +1102,7 @@ func putObjectTags(ctx context.Context, client MinioClient, bucketName, prefix, // Restore Object Version func getPutObjectRestoreResponse(session *models.Principal, params objectApi.PutObjectRestoreParams) *models.Error { ctx := params.HTTPRequest.Context() - mClient, err := newMinioClient(session) + mClient, err := newMinioClient(session, getClientIP(params.HTTPRequest)) if err != nil { return ErrorWithContext(ctx, err) } @@ -1154,7 +1157,7 @@ func restoreObject(ctx context.Context, client MinioClient, bucketName, prefix, // Metadata Response from minio-go API func getObjectMetadataResponse(session *models.Principal, params objectApi.GetObjectMetadataParams) (*models.Metadata, *models.Error) { ctx := params.HTTPRequest.Context() - mClient, err := newMinioClient(session) + mClient, err := newMinioClient(session, getClientIP(params.HTTPRequest)) if err != nil { return nil, ErrorWithContext(ctx, err) } diff --git a/restapi/user_session.go b/restapi/user_session.go index e5750006e..779f02873 100644 --- a/restapi/user_session.go +++ b/restapi/user_session.go @@ -78,9 +78,8 @@ func getSessionResponse(ctx context.Context, session *models.Principal) (*models return nil, ErrorWithContext(ctx, ErrInvalidSession) } tokenClaims, _ := getClaimsFromToken(session.STSSessionToken) - // initialize admin client - mAdminClient, err := NewMinioAdminClient(&models.Principal{ + mAdminClient, err := NewMinioAdminClient(ctx, &models.Principal{ STSAccessKeyID: session.STSAccessKeyID, STSSecretAccessKey: session.STSSecretAccessKey, STSSessionToken: session.STSSessionToken, diff --git a/restapi/user_session_test.go b/restapi/user_session_test.go index 89fde948e..17ec6fcdd 100644 --- a/restapi/user_session_test.go +++ b/restapi/user_session_test.go @@ -22,6 +22,8 @@ import ( "reflect" "testing" + "github.com/minio/console/pkg/utils" + "github.com/minio/console/models" "github.com/minio/console/pkg/auth/idp/oauth2" "github.com/minio/console/pkg/auth/ldap" @@ -33,7 +35,7 @@ func Test_getSessionResponse(t *testing.T) { ctx context.Context session *models.Principal } - ctx := context.Background() + ctx := context.WithValue(context.Background(), utils.ContextClientIP, "127.0.0.1") tests := []struct { name string args args diff --git a/restapi/user_support.go b/restapi/user_support.go index 74f9d5200..b88c85c85 100644 --- a/restapi/user_support.go +++ b/restapi/user_support.go @@ -59,7 +59,7 @@ func getCallHomeOptionResponse(session *models.Principal, params support.GetCall ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return nil, ErrorWithContext(ctx, err) } @@ -133,7 +133,7 @@ func editCallHomeOptionResponse(session *models.Principal, params support.SetCal ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - mAdmin, err := NewMinioAdminClient(session) + mAdmin, err := NewMinioAdminClient(params.HTTPRequest.Context(), session) if err != nil { return ErrorWithContext(ctx, err) } diff --git a/restapi/user_version.go b/restapi/user_version.go index d8857981d..bb1361d33 100644 --- a/restapi/user_version.go +++ b/restapi/user_version.go @@ -44,7 +44,7 @@ func getVersionResponse(params systemApi.CheckMinIOVersionParams) (*models.Check ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) defer cancel() - client := GetConsoleHTTPClient("") + client := GetConsoleHTTPClient("", getClientIP(params.HTTPRequest)) client.Timeout = 15 * time.Second ver, err := utils.GetLatestMinIOImage(&xhttp.Client{ diff --git a/restapi/ws_handle.go b/restapi/ws_handle.go index 5ce0348f8..10f1acd0c 100644 --- a/restapi/ws_handle.go +++ b/restapi/ws_handle.go @@ -20,6 +20,7 @@ import ( "context" "errors" "fmt" + "log" "net" "net/http" "strconv" @@ -91,6 +92,7 @@ type WSConn interface { writeMessage(messageType int, data []byte) error close() error readMessage() (messageType int, p []byte, err error) + remoteAddress() string } // Interface implementation @@ -132,6 +134,16 @@ func (c wsConn) readMessage() (messageType int, p []byte, err error) { return c.conn.ReadMessage() } +func (c wsConn) remoteAddress() string { + clientIP, _, err := net.SplitHostPort(c.conn.RemoteAddr().String()) + if err != nil { + // In case there's an error, return an empty string + log.Printf("Invalid ws.clientIP = %s\n", err) + return "" + } + return clientIP +} + // serveWS validates the incoming request and // upgrades the request to a Websocket protocol. // Websocket communication will be done depending @@ -307,16 +319,19 @@ func serveWS(w http.ResponseWriter, req *http.Request) { // newWebSocketAdminClient returns a wsAdminClient authenticated as an admin user func newWebSocketAdminClient(conn *websocket.Conn, autClaims *models.Principal) (*wsAdminClient, error) { + // create a websocket connection interface implementation + // defining the connection to be used + wsConnection := wsConn{conn: conn} + + clientIP := wsConnection.remoteAddress() // Only start Websocket Interaction after user has been // authenticated with MinIO - mAdmin, err := newAdminFromClaims(autClaims) + mAdmin, err := newAdminFromClaims(autClaims, clientIP) if err != nil { LogError("error creating madmin client: %v", err) return nil, err } - // create a websocket connection interface implementation - // defining the connection to be used - wsConnection := wsConn{conn: conn} + // create a minioClient interface implementation // defining the client to be used adminClient := AdminClient{Client: mAdmin} @@ -329,7 +344,13 @@ func newWebSocketAdminClient(conn *websocket.Conn, autClaims *models.Principal) func newWebSocketS3Client(conn *websocket.Conn, claims *models.Principal, bucketName, prefix string) (*wsS3Client, error) { // Only start Websocket Interaction after user has been // authenticated with MinIO - s3Client, err := newS3BucketClient(claims, bucketName, prefix) + clientIP, _, err := net.SplitHostPort(conn.RemoteAddr().String()) + if err != nil { + // In case there's an error, return an empty string + log.Printf("Invalid ws.clientIP = %s\n", err) + } + + s3Client, err := newS3BucketClient(claims, bucketName, prefix, clientIP) if err != nil { LogError("error creating S3Client:", err) return nil, err @@ -348,8 +369,12 @@ func newWebSocketS3Client(conn *websocket.Conn, claims *models.Principal, bucket func newWebSocketMinioClient(conn *websocket.Conn, claims *models.Principal) (*wsMinioClient, error) { // Only start Websocket Interaction after user has been // authenticated with MinIO - - mClient, err := newMinioClient(claims) + clientIP, _, err := net.SplitHostPort(conn.RemoteAddr().String()) + if err != nil { + // In case there's an error, return an empty string + log.Printf("Invalid ws.clientIP = %s\n", err) + } + mClient, err := newMinioClient(claims, clientIP) if err != nil { LogError("error creating MinioClient:", err) return nil, err diff --git a/restapi/ws_handle_test.go b/restapi/ws_handle_test.go index f8622379f..cb046057d 100644 --- a/restapi/ws_handle_test.go +++ b/restapi/ws_handle_test.go @@ -46,6 +46,10 @@ func (c mockConn) close() error { return nil } +func (c mockConn) remoteAddress() string { + return "127.0.0.1" +} + func TestWSHandle(_ *testing.T) { // assert := assert.New(t) mockWSConn := mockConn{} diff --git a/restapi/ws_objects.go b/restapi/ws_objects.go index 7e63eaea6..e48f1b6d8 100644 --- a/restapi/ws_objects.go +++ b/restapi/ws_objects.go @@ -163,7 +163,9 @@ func (wsc *wsMinioClient) objectManager(session *models.Principal) { return } - s3Client, err := newS3BucketClient(session, objectRqConfigs.BucketName, objectRqConfigs.Prefix) + clientIP := wsc.conn.remoteAddress() + + s3Client, err := newS3BucketClient(session, objectRqConfigs.BucketName, objectRqConfigs.Prefix, clientIP) if err != nil { LogError("error creating S3Client:", err) close(done)