github.com/minio/minio@v0.0.0-20240328213742-3f72439b8a27/cmd/admin-router.go (about)

     1  // Copyright (c) 2015-2021 MinIO, Inc.
     2  //
     3  // This file is part of MinIO Object Storage stack
     4  //
     5  // This program is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU Affero General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // This program is distributed in the hope that it will be useful
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13  // GNU Affero General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU Affero General Public License
    16  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    17  
    18  package cmd
    19  
    20  import (
    21  	"net/http"
    22  
    23  	"github.com/klauspost/compress/gzhttp"
    24  	"github.com/klauspost/compress/gzip"
    25  	"github.com/minio/madmin-go/v3"
    26  	"github.com/minio/minio/internal/logger"
    27  	"github.com/minio/mux"
    28  )
    29  
    30  const (
    31  	adminPathPrefix                = minioReservedBucketPath + "/admin"
    32  	adminAPIVersion                = madmin.AdminAPIVersion
    33  	adminAPIVersionPrefix          = SlashSeparator + adminAPIVersion
    34  	adminAPISiteReplicationDevNull = "/site-replication/devnull"
    35  	adminAPISiteReplicationNetPerf = "/site-replication/netperf"
    36  	adminAPIClientDevNull          = "/speedtest/client/devnull"
    37  	adminAPIClientDevExtraTime     = "/speedtest/client/devnull/extratime"
    38  )
    39  
    40  var gzipHandler = func() func(http.Handler) http.HandlerFunc {
    41  	gz, err := gzhttp.NewWrapper(gzhttp.MinSize(1000), gzhttp.CompressionLevel(gzip.BestSpeed))
    42  	if err != nil {
    43  		// Static params, so this is very unlikely.
    44  		logger.Fatal(err, "Unable to initialize server")
    45  	}
    46  	return gz
    47  }()
    48  
    49  // Set of handler options as bit flags
    50  type hFlag uint8
    51  
    52  const (
    53  	// this flag disables gzip compression of responses
    54  	noGZFlag = 1 << iota
    55  
    56  	// this flag enables tracing body and headers instead of just headers
    57  	traceAllFlag
    58  
    59  	// pass this flag to skip checking if object layer is available
    60  	noObjLayerFlag
    61  )
    62  
    63  // Has checks if the given flag is enabled in `h`.
    64  func (h hFlag) Has(flag hFlag) bool {
    65  	// Use bitwise-AND and check if the result is non-zero.
    66  	return h&flag != 0
    67  }
    68  
    69  // adminMiddleware performs some common admin handler functionality for all
    70  // handlers:
    71  //
    72  // - updates request context with `logger.ReqInfo` and api name based on the
    73  // name of the function handler passed (this handler must be a method of
    74  // `adminAPIHandlers`).
    75  //
    76  // - sets up call to send AuditLog
    77  //
    78  // While this is a middleware function (i.e. it takes a handler function and
    79  // returns one), due to flags being passed based on required conditions, it is
    80  // done per-"handler function registration" in the router.
    81  //
    82  // The passed in handler function must be a method of `adminAPIHandlers` for the
    83  // name displayed in logs and trace to be accurate. The name is extracted via
    84  // reflection.
    85  //
    86  // When no flags are passed, gzip compression, http tracing of headers and
    87  // checking of object layer availability are all enabled. Use flags to modify
    88  // this behavior.
    89  func adminMiddleware(f http.HandlerFunc, flags ...hFlag) http.HandlerFunc {
    90  	// Collect all flags with bitwise-OR and assign operator
    91  	var handlerFlags hFlag
    92  	for _, flag := range flags {
    93  		handlerFlags |= flag
    94  	}
    95  
    96  	// Get name of the handler using reflection.
    97  	handlerName := getHandlerName(f, "adminAPIHandlers")
    98  
    99  	var handler http.HandlerFunc = func(w http.ResponseWriter, r *http.Request) {
   100  		// Update request context with `logger.ReqInfo`.
   101  		r = r.WithContext(newContext(r, w, handlerName))
   102  
   103  		defer logger.AuditLog(r.Context(), w, r, mustGetClaimsFromToken(r))
   104  
   105  		// Check if object layer is available, if not return error early.
   106  		if !handlerFlags.Has(noObjLayerFlag) {
   107  			objectAPI := newObjectLayerFn()
   108  			if objectAPI == nil || globalNotificationSys == nil {
   109  				writeErrorResponseJSON(r.Context(), w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
   110  				return
   111  			}
   112  		}
   113  
   114  		// Apply http tracing "middleware" based on presence of flag.
   115  		var f2 http.HandlerFunc
   116  		if handlerFlags.Has(traceAllFlag) {
   117  			f2 = httpTraceAll(f)
   118  		} else {
   119  			f2 = httpTraceHdrs(f)
   120  		}
   121  
   122  		// call the final handler
   123  		f2(w, r)
   124  	}
   125  
   126  	// Enable compression of responses based on presence of flag.
   127  	if !handlerFlags.Has(noGZFlag) {
   128  		handler = gzipHandler(handler)
   129  	}
   130  
   131  	return handler
   132  }
   133  
   134  // adminAPIHandlers provides HTTP handlers for MinIO admin API.
   135  type adminAPIHandlers struct{}
   136  
   137  // registerAdminRouter - Add handler functions for each service REST API routes.
   138  func registerAdminRouter(router *mux.Router, enableConfigOps bool) {
   139  	adminAPI := adminAPIHandlers{}
   140  	// Admin router
   141  	adminRouter := router.PathPrefix(adminPathPrefix).Subrouter()
   142  
   143  	adminVersions := []string{
   144  		adminAPIVersionPrefix,
   145  	}
   146  
   147  	for _, adminVersion := range adminVersions {
   148  		// Restart and stop MinIO service type=2
   149  		adminRouter.Methods(http.MethodPost).Path(adminVersion+"/service").HandlerFunc(adminMiddleware(adminAPI.ServiceV2Handler, traceAllFlag)).Queries("action", "{action:.*}", "type", "2")
   150  
   151  		// Deprecated: Restart and stop MinIO service.
   152  		adminRouter.Methods(http.MethodPost).Path(adminVersion+"/service").HandlerFunc(adminMiddleware(adminAPI.ServiceHandler, traceAllFlag)).Queries("action", "{action:.*}")
   153  
   154  		// Update all MinIO servers type=2
   155  		adminRouter.Methods(http.MethodPost).Path(adminVersion+"/update").HandlerFunc(adminMiddleware(adminAPI.ServerUpdateV2Handler, traceAllFlag)).Queries("updateURL", "{updateURL:.*}", "type", "2")
   156  
   157  		// Deprecated: Update MinIO servers.
   158  		adminRouter.Methods(http.MethodPost).Path(adminVersion+"/update").HandlerFunc(adminMiddleware(adminAPI.ServerUpdateHandler, traceAllFlag)).Queries("updateURL", "{updateURL:.*}")
   159  
   160  		// Info operations
   161  		adminRouter.Methods(http.MethodGet).Path(adminVersion + "/info").HandlerFunc(adminMiddleware(adminAPI.ServerInfoHandler, traceAllFlag, noObjLayerFlag))
   162  		adminRouter.Methods(http.MethodGet, http.MethodPost).Path(adminVersion + "/inspect-data").HandlerFunc(adminMiddleware(adminAPI.InspectDataHandler, noGZFlag, traceAllFlag))
   163  
   164  		// StorageInfo operations
   165  		adminRouter.Methods(http.MethodGet).Path(adminVersion + "/storageinfo").HandlerFunc(adminMiddleware(adminAPI.StorageInfoHandler, traceAllFlag))
   166  		// DataUsageInfo operations
   167  		adminRouter.Methods(http.MethodGet).Path(adminVersion + "/datausageinfo").HandlerFunc(adminMiddleware(adminAPI.DataUsageInfoHandler, traceAllFlag))
   168  		// Metrics operation
   169  		adminRouter.Methods(http.MethodGet).Path(adminVersion + "/metrics").HandlerFunc(adminMiddleware(adminAPI.MetricsHandler, traceAllFlag))
   170  
   171  		if globalIsDistErasure || globalIsErasure {
   172  			// Heal operations
   173  
   174  			// Heal processing endpoint.
   175  			adminRouter.Methods(http.MethodPost).Path(adminVersion + "/heal/").HandlerFunc(adminMiddleware(adminAPI.HealHandler, traceAllFlag))
   176  			adminRouter.Methods(http.MethodPost).Path(adminVersion + "/heal/{bucket}").HandlerFunc(adminMiddleware(adminAPI.HealHandler, traceAllFlag))
   177  			adminRouter.Methods(http.MethodPost).Path(adminVersion + "/heal/{bucket}/{prefix:.*}").HandlerFunc(adminMiddleware(adminAPI.HealHandler, traceAllFlag))
   178  			adminRouter.Methods(http.MethodPost).Path(adminVersion + "/background-heal/status").HandlerFunc(adminMiddleware(adminAPI.BackgroundHealStatusHandler, traceAllFlag))
   179  
   180  			// Pool operations
   181  			adminRouter.Methods(http.MethodGet).Path(adminVersion + "/pools/list").HandlerFunc(adminMiddleware(adminAPI.ListPools, traceAllFlag))
   182  			adminRouter.Methods(http.MethodGet).Path(adminVersion+"/pools/status").HandlerFunc(adminMiddleware(adminAPI.StatusPool, traceAllFlag)).Queries("pool", "{pool:.*}")
   183  
   184  			adminRouter.Methods(http.MethodPost).Path(adminVersion+"/pools/decommission").HandlerFunc(adminMiddleware(adminAPI.StartDecommission, traceAllFlag)).Queries("pool", "{pool:.*}")
   185  			adminRouter.Methods(http.MethodPost).Path(adminVersion+"/pools/cancel").HandlerFunc(adminMiddleware(adminAPI.CancelDecommission, traceAllFlag)).Queries("pool", "{pool:.*}")
   186  
   187  			// Rebalance operations
   188  			adminRouter.Methods(http.MethodPost).Path(adminVersion + "/rebalance/start").HandlerFunc(adminMiddleware(adminAPI.RebalanceStart, traceAllFlag))
   189  			adminRouter.Methods(http.MethodGet).Path(adminVersion + "/rebalance/status").HandlerFunc(adminMiddleware(adminAPI.RebalanceStatus, traceAllFlag))
   190  			adminRouter.Methods(http.MethodPost).Path(adminVersion + "/rebalance/stop").HandlerFunc(adminMiddleware(adminAPI.RebalanceStop, traceAllFlag))
   191  		}
   192  
   193  		// Profiling operations - deprecated API
   194  		adminRouter.Methods(http.MethodPost).Path(adminVersion+"/profiling/start").HandlerFunc(adminMiddleware(adminAPI.StartProfilingHandler, traceAllFlag, noObjLayerFlag)).
   195  			Queries("profilerType", "{profilerType:.*}")
   196  		adminRouter.Methods(http.MethodGet).Path(adminVersion + "/profiling/download").HandlerFunc(adminMiddleware(adminAPI.DownloadProfilingHandler, traceAllFlag, noObjLayerFlag))
   197  		// Profiling operations
   198  		adminRouter.Methods(http.MethodPost).Path(adminVersion + "/profile").HandlerFunc(adminMiddleware(adminAPI.ProfileHandler, traceAllFlag, noObjLayerFlag))
   199  
   200  		// Config KV operations.
   201  		if enableConfigOps {
   202  			adminRouter.Methods(http.MethodGet).Path(adminVersion+"/get-config-kv").HandlerFunc(adminMiddleware(adminAPI.GetConfigKVHandler)).Queries("key", "{key:.*}")
   203  			adminRouter.Methods(http.MethodPut).Path(adminVersion + "/set-config-kv").HandlerFunc(adminMiddleware(adminAPI.SetConfigKVHandler))
   204  			adminRouter.Methods(http.MethodDelete).Path(adminVersion + "/del-config-kv").HandlerFunc(adminMiddleware(adminAPI.DelConfigKVHandler))
   205  		}
   206  
   207  		// Enable config help in all modes.
   208  		adminRouter.Methods(http.MethodGet).Path(adminVersion+"/help-config-kv").HandlerFunc(adminMiddleware(adminAPI.HelpConfigKVHandler, traceAllFlag)).Queries("subSys", "{subSys:.*}", "key", "{key:.*}")
   209  
   210  		// Config KV history operations.
   211  		if enableConfigOps {
   212  			adminRouter.Methods(http.MethodGet).Path(adminVersion+"/list-config-history-kv").HandlerFunc(adminMiddleware(adminAPI.ListConfigHistoryKVHandler, traceAllFlag)).Queries("count", "{count:[0-9]+}")
   213  			adminRouter.Methods(http.MethodDelete).Path(adminVersion+"/clear-config-history-kv").HandlerFunc(adminMiddleware(adminAPI.ClearConfigHistoryKVHandler)).Queries("restoreId", "{restoreId:.*}")
   214  			adminRouter.Methods(http.MethodPut).Path(adminVersion+"/restore-config-history-kv").HandlerFunc(adminMiddleware(adminAPI.RestoreConfigHistoryKVHandler)).Queries("restoreId", "{restoreId:.*}")
   215  		}
   216  
   217  		// Config import/export bulk operations
   218  		if enableConfigOps {
   219  			// Get config
   220  			adminRouter.Methods(http.MethodGet).Path(adminVersion + "/config").HandlerFunc(adminMiddleware(adminAPI.GetConfigHandler))
   221  			// Set config
   222  			adminRouter.Methods(http.MethodPut).Path(adminVersion + "/config").HandlerFunc(adminMiddleware(adminAPI.SetConfigHandler))
   223  		}
   224  
   225  		// -- IAM APIs --
   226  
   227  		// Add policy IAM
   228  		adminRouter.Methods(http.MethodPut).Path(adminVersion+"/add-canned-policy").HandlerFunc(adminMiddleware(adminAPI.AddCannedPolicy, traceAllFlag)).Queries("name", "{name:.*}")
   229  
   230  		// Add user IAM
   231  		adminRouter.Methods(http.MethodGet).Path(adminVersion + "/accountinfo").HandlerFunc(adminMiddleware(adminAPI.AccountInfoHandler, traceAllFlag))
   232  
   233  		adminRouter.Methods(http.MethodPut).Path(adminVersion+"/add-user").HandlerFunc(adminMiddleware(adminAPI.AddUser)).Queries("accessKey", "{accessKey:.*}")
   234  
   235  		adminRouter.Methods(http.MethodPut).Path(adminVersion+"/set-user-status").HandlerFunc(adminMiddleware(adminAPI.SetUserStatus)).Queries("accessKey", "{accessKey:.*}").Queries("status", "{status:.*}")
   236  
   237  		// Service accounts ops
   238  		adminRouter.Methods(http.MethodPut).Path(adminVersion + "/add-service-account").HandlerFunc(adminMiddleware(adminAPI.AddServiceAccount))
   239  		adminRouter.Methods(http.MethodPost).Path(adminVersion+"/update-service-account").HandlerFunc(adminMiddleware(adminAPI.UpdateServiceAccount)).Queries("accessKey", "{accessKey:.*}")
   240  		adminRouter.Methods(http.MethodGet).Path(adminVersion+"/info-service-account").HandlerFunc(adminMiddleware(adminAPI.InfoServiceAccount)).Queries("accessKey", "{accessKey:.*}")
   241  		adminRouter.Methods(http.MethodGet).Path(adminVersion + "/list-service-accounts").HandlerFunc(adminMiddleware(adminAPI.ListServiceAccounts))
   242  		adminRouter.Methods(http.MethodDelete).Path(adminVersion+"/delete-service-account").HandlerFunc(adminMiddleware(adminAPI.DeleteServiceAccount)).Queries("accessKey", "{accessKey:.*}")
   243  
   244  		// STS accounts ops
   245  		adminRouter.Methods(http.MethodGet).Path(adminVersion+"/temporary-account-info").HandlerFunc(adminMiddleware(adminAPI.TemporaryAccountInfo)).Queries("accessKey", "{accessKey:.*}")
   246  
   247  		// Info policy IAM latest
   248  		adminRouter.Methods(http.MethodGet).Path(adminVersion+"/info-canned-policy").HandlerFunc(adminMiddleware(adminAPI.InfoCannedPolicy)).Queries("name", "{name:.*}")
   249  		// List policies latest
   250  		adminRouter.Methods(http.MethodGet).Path(adminVersion+"/list-canned-policies").HandlerFunc(adminMiddleware(adminAPI.ListBucketPolicies)).Queries("bucket", "{bucket:.*}")
   251  		adminRouter.Methods(http.MethodGet).Path(adminVersion + "/list-canned-policies").HandlerFunc(adminMiddleware(adminAPI.ListCannedPolicies))
   252  
   253  		// Builtin IAM policy associations
   254  		adminRouter.Methods(http.MethodGet).Path(adminVersion + "/idp/builtin/policy-entities").HandlerFunc(adminMiddleware(adminAPI.ListPolicyMappingEntities))
   255  
   256  		// Remove policy IAM
   257  		adminRouter.Methods(http.MethodDelete).Path(adminVersion+"/remove-canned-policy").HandlerFunc(adminMiddleware(adminAPI.RemoveCannedPolicy)).Queries("name", "{name:.*}")
   258  
   259  		// Set user or group policy
   260  		adminRouter.Methods(http.MethodPut).Path(adminVersion+"/set-user-or-group-policy").
   261  			HandlerFunc(adminMiddleware(adminAPI.SetPolicyForUserOrGroup)).
   262  			Queries("policyName", "{policyName:.*}", "userOrGroup", "{userOrGroup:.*}", "isGroup", "{isGroup:true|false}")
   263  
   264  		// Attach/Detach policies to/from user or group
   265  		adminRouter.Methods(http.MethodPost).Path(adminVersion + "/idp/builtin/policy/{operation}").HandlerFunc(adminMiddleware(adminAPI.AttachDetachPolicyBuiltin))
   266  
   267  		// Remove user IAM
   268  		adminRouter.Methods(http.MethodDelete).Path(adminVersion+"/remove-user").HandlerFunc(adminMiddleware(adminAPI.RemoveUser)).Queries("accessKey", "{accessKey:.*}")
   269  
   270  		// List users
   271  		adminRouter.Methods(http.MethodGet).Path(adminVersion+"/list-users").HandlerFunc(adminMiddleware(adminAPI.ListBucketUsers)).Queries("bucket", "{bucket:.*}")
   272  		adminRouter.Methods(http.MethodGet).Path(adminVersion + "/list-users").HandlerFunc(adminMiddleware(adminAPI.ListUsers))
   273  
   274  		// User info
   275  		adminRouter.Methods(http.MethodGet).Path(adminVersion+"/user-info").HandlerFunc(adminMiddleware(adminAPI.GetUserInfo)).Queries("accessKey", "{accessKey:.*}")
   276  		// Add/Remove members from group
   277  		adminRouter.Methods(http.MethodPut).Path(adminVersion + "/update-group-members").HandlerFunc(adminMiddleware(adminAPI.UpdateGroupMembers))
   278  
   279  		// Get Group
   280  		adminRouter.Methods(http.MethodGet).Path(adminVersion+"/group").HandlerFunc(adminMiddleware(adminAPI.GetGroup)).Queries("group", "{group:.*}")
   281  
   282  		// List Groups
   283  		adminRouter.Methods(http.MethodGet).Path(adminVersion + "/groups").HandlerFunc(adminMiddleware(adminAPI.ListGroups))
   284  
   285  		// Set Group Status
   286  		adminRouter.Methods(http.MethodPut).Path(adminVersion+"/set-group-status").HandlerFunc(adminMiddleware(adminAPI.SetGroupStatus)).Queries("group", "{group:.*}").Queries("status", "{status:.*}")
   287  
   288  		// Export IAM info to zipped file
   289  		adminRouter.Methods(http.MethodGet).Path(adminVersion + "/export-iam").HandlerFunc(adminMiddleware(adminAPI.ExportIAM, noGZFlag))
   290  
   291  		// Import IAM info
   292  		adminRouter.Methods(http.MethodPut).Path(adminVersion + "/import-iam").HandlerFunc(adminMiddleware(adminAPI.ImportIAM, noGZFlag))
   293  
   294  		// IDentity Provider configuration APIs
   295  		adminRouter.Methods(http.MethodPut).Path(adminVersion + "/idp-config/{type}/{name}").HandlerFunc(adminMiddleware(adminAPI.AddIdentityProviderCfg))
   296  		adminRouter.Methods(http.MethodPost).Path(adminVersion + "/idp-config/{type}/{name}").HandlerFunc(adminMiddleware(adminAPI.UpdateIdentityProviderCfg))
   297  		adminRouter.Methods(http.MethodGet).Path(adminVersion + "/idp-config/{type}").HandlerFunc(adminMiddleware(adminAPI.ListIdentityProviderCfg))
   298  		adminRouter.Methods(http.MethodGet).Path(adminVersion + "/idp-config/{type}/{name}").HandlerFunc(adminMiddleware(adminAPI.GetIdentityProviderCfg))
   299  		adminRouter.Methods(http.MethodDelete).Path(adminVersion + "/idp-config/{type}/{name}").HandlerFunc(adminMiddleware(adminAPI.DeleteIdentityProviderCfg))
   300  
   301  		// LDAP specific service accounts ops
   302  		adminRouter.Methods(http.MethodPut).Path(adminVersion + "/idp/ldap/add-service-account").HandlerFunc(adminMiddleware(adminAPI.AddServiceAccountLDAP))
   303  		adminRouter.Methods(http.MethodGet).Path(adminVersion+"/idp/ldap/list-access-keys").
   304  			HandlerFunc(adminMiddleware(adminAPI.ListAccessKeysLDAP)).
   305  			Queries("userDN", "{userDN:.*}", "listType", "{listType:.*}")
   306  
   307  		// LDAP IAM operations
   308  		adminRouter.Methods(http.MethodGet).Path(adminVersion + "/idp/ldap/policy-entities").HandlerFunc(adminMiddleware(adminAPI.ListLDAPPolicyMappingEntities))
   309  		adminRouter.Methods(http.MethodPost).Path(adminVersion + "/idp/ldap/policy/{operation}").HandlerFunc(adminMiddleware(adminAPI.AttachDetachPolicyLDAP))
   310  		// -- END IAM APIs --
   311  
   312  		// GetBucketQuotaConfig
   313  		adminRouter.Methods(http.MethodGet).Path(adminVersion+"/get-bucket-quota").HandlerFunc(
   314  			adminMiddleware(adminAPI.GetBucketQuotaConfigHandler)).Queries("bucket", "{bucket:.*}")
   315  		// PutBucketQuotaConfig
   316  		adminRouter.Methods(http.MethodPut).Path(adminVersion+"/set-bucket-quota").HandlerFunc(
   317  			adminMiddleware(adminAPI.PutBucketQuotaConfigHandler)).Queries("bucket", "{bucket:.*}")
   318  
   319  		// Bucket replication operations
   320  		// GetBucketTargetHandler
   321  		adminRouter.Methods(http.MethodGet).Path(adminVersion+"/list-remote-targets").HandlerFunc(
   322  			adminMiddleware(adminAPI.ListRemoteTargetsHandler)).Queries("bucket", "{bucket:.*}", "type", "{type:.*}")
   323  		// SetRemoteTargetHandler
   324  		adminRouter.Methods(http.MethodPut).Path(adminVersion+"/set-remote-target").HandlerFunc(
   325  			adminMiddleware(adminAPI.SetRemoteTargetHandler)).Queries("bucket", "{bucket:.*}")
   326  		// RemoveRemoteTargetHandler
   327  		adminRouter.Methods(http.MethodDelete).Path(adminVersion+"/remove-remote-target").HandlerFunc(
   328  			adminMiddleware(adminAPI.RemoveRemoteTargetHandler)).Queries("bucket", "{bucket:.*}", "arn", "{arn:.*}")
   329  		// ReplicationDiff - MinIO extension API
   330  		adminRouter.Methods(http.MethodPost).Path(adminVersion+"/replication/diff").HandlerFunc(
   331  			adminMiddleware(adminAPI.ReplicationDiffHandler)).Queries("bucket", "{bucket:.*}")
   332  		// ReplicationMRFHandler - MinIO extension API
   333  		adminRouter.Methods(http.MethodGet).Path(adminVersion+"/replication/mrf").HandlerFunc(
   334  			adminMiddleware(adminAPI.ReplicationMRFHandler)).Queries("bucket", "{bucket:.*}")
   335  
   336  		// Batch job operations
   337  		adminRouter.Methods(http.MethodPost).Path(adminVersion + "/start-job").HandlerFunc(
   338  			adminMiddleware(adminAPI.StartBatchJob))
   339  
   340  		adminRouter.Methods(http.MethodGet).Path(adminVersion + "/list-jobs").HandlerFunc(
   341  			adminMiddleware(adminAPI.ListBatchJobs))
   342  
   343  		adminRouter.Methods(http.MethodGet).Path(adminVersion + "/describe-job").HandlerFunc(
   344  			adminMiddleware(adminAPI.DescribeBatchJob))
   345  		adminRouter.Methods(http.MethodDelete).Path(adminVersion + "/cancel-job").HandlerFunc(
   346  			adminMiddleware(adminAPI.CancelBatchJob))
   347  
   348  		// Bucket migration operations
   349  		// ExportBucketMetaHandler
   350  		adminRouter.Methods(http.MethodGet).Path(adminVersion + "/export-bucket-metadata").HandlerFunc(
   351  			adminMiddleware(adminAPI.ExportBucketMetadataHandler))
   352  		// ImportBucketMetaHandler
   353  		adminRouter.Methods(http.MethodPut).Path(adminVersion + "/import-bucket-metadata").HandlerFunc(
   354  			adminMiddleware(adminAPI.ImportBucketMetadataHandler))
   355  
   356  		// Remote Tier management operations
   357  		adminRouter.Methods(http.MethodPut).Path(adminVersion + "/tier").HandlerFunc(adminMiddleware(adminAPI.AddTierHandler))
   358  		adminRouter.Methods(http.MethodPost).Path(adminVersion + "/tier/{tier}").HandlerFunc(adminMiddleware(adminAPI.EditTierHandler))
   359  		adminRouter.Methods(http.MethodGet).Path(adminVersion + "/tier").HandlerFunc(adminMiddleware(adminAPI.ListTierHandler))
   360  		adminRouter.Methods(http.MethodDelete).Path(adminVersion + "/tier/{tier}").HandlerFunc(adminMiddleware(adminAPI.RemoveTierHandler))
   361  		adminRouter.Methods(http.MethodGet).Path(adminVersion + "/tier/{tier}").HandlerFunc(adminMiddleware(adminAPI.VerifyTierHandler))
   362  		// Tier stats
   363  		adminRouter.Methods(http.MethodGet).Path(adminVersion + "/tier-stats").HandlerFunc(adminMiddleware(adminAPI.TierStatsHandler))
   364  
   365  		// Cluster Replication APIs
   366  		adminRouter.Methods(http.MethodPut).Path(adminVersion + "/site-replication/add").HandlerFunc(adminMiddleware(adminAPI.SiteReplicationAdd))
   367  		adminRouter.Methods(http.MethodPut).Path(adminVersion + "/site-replication/remove").HandlerFunc(adminMiddleware(adminAPI.SiteReplicationRemove))
   368  		adminRouter.Methods(http.MethodGet).Path(adminVersion + "/site-replication/info").HandlerFunc(adminMiddleware(adminAPI.SiteReplicationInfo))
   369  		adminRouter.Methods(http.MethodGet).Path(adminVersion + "/site-replication/metainfo").HandlerFunc(adminMiddleware(adminAPI.SiteReplicationMetaInfo))
   370  		adminRouter.Methods(http.MethodGet).Path(adminVersion + "/site-replication/status").HandlerFunc(adminMiddleware(adminAPI.SiteReplicationStatus))
   371  		adminRouter.Methods(http.MethodPost).Path(adminVersion + adminAPISiteReplicationDevNull).HandlerFunc(adminMiddleware(adminAPI.SiteReplicationDevNull, noObjLayerFlag))
   372  		adminRouter.Methods(http.MethodPost).Path(adminVersion + adminAPISiteReplicationNetPerf).HandlerFunc(adminMiddleware(adminAPI.SiteReplicationNetPerf, noObjLayerFlag))
   373  
   374  		adminRouter.Methods(http.MethodPut).Path(adminVersion + "/site-replication/peer/join").HandlerFunc(adminMiddleware(adminAPI.SRPeerJoin))
   375  		adminRouter.Methods(http.MethodPut).Path(adminVersion+"/site-replication/peer/bucket-ops").HandlerFunc(adminMiddleware(adminAPI.SRPeerBucketOps)).Queries("bucket", "{bucket:.*}").Queries("operation", "{operation:.*}")
   376  		adminRouter.Methods(http.MethodPut).Path(adminVersion + "/site-replication/peer/iam-item").HandlerFunc(adminMiddleware(adminAPI.SRPeerReplicateIAMItem))
   377  		adminRouter.Methods(http.MethodPut).Path(adminVersion + "/site-replication/peer/bucket-meta").HandlerFunc(adminMiddleware(adminAPI.SRPeerReplicateBucketItem))
   378  		adminRouter.Methods(http.MethodGet).Path(adminVersion + "/site-replication/peer/idp-settings").HandlerFunc(adminMiddleware(adminAPI.SRPeerGetIDPSettings))
   379  		adminRouter.Methods(http.MethodPut).Path(adminVersion + "/site-replication/edit").HandlerFunc(adminMiddleware(adminAPI.SiteReplicationEdit))
   380  		adminRouter.Methods(http.MethodPut).Path(adminVersion + "/site-replication/peer/edit").HandlerFunc(adminMiddleware(adminAPI.SRPeerEdit))
   381  		adminRouter.Methods(http.MethodPut).Path(adminVersion + "/site-replication/peer/remove").HandlerFunc(adminMiddleware(adminAPI.SRPeerRemove))
   382  		adminRouter.Methods(http.MethodPut).Path(adminVersion+"/site-replication/resync/op").HandlerFunc(adminMiddleware(adminAPI.SiteReplicationResyncOp)).Queries("operation", "{operation:.*}")
   383  		adminRouter.Methods(http.MethodPut).Path(adminVersion + "/site-replication/state/edit").HandlerFunc(adminMiddleware(adminAPI.SRStateEdit))
   384  
   385  		if globalIsDistErasure {
   386  			// Top locks
   387  			adminRouter.Methods(http.MethodGet).Path(adminVersion + "/top/locks").HandlerFunc(adminMiddleware(adminAPI.TopLocksHandler))
   388  			// Force unlocks paths
   389  			adminRouter.Methods(http.MethodPost).Path(adminVersion+"/force-unlock").
   390  				Queries("paths", "{paths:.*}").HandlerFunc(adminMiddleware(adminAPI.ForceUnlockHandler))
   391  		}
   392  
   393  		adminRouter.Methods(http.MethodPost).Path(adminVersion + "/speedtest").HandlerFunc(adminMiddleware(adminAPI.ObjectSpeedTestHandler, noGZFlag))
   394  		adminRouter.Methods(http.MethodPost).Path(adminVersion + "/speedtest/object").HandlerFunc(adminMiddleware(adminAPI.ObjectSpeedTestHandler, noGZFlag))
   395  		adminRouter.Methods(http.MethodPost).Path(adminVersion + "/speedtest/drive").HandlerFunc(adminMiddleware(adminAPI.DriveSpeedtestHandler, noGZFlag))
   396  		adminRouter.Methods(http.MethodPost).Path(adminVersion + "/speedtest/net").HandlerFunc(adminMiddleware(adminAPI.NetperfHandler, noGZFlag))
   397  		adminRouter.Methods(http.MethodPost).Path(adminVersion + "/speedtest/site").HandlerFunc(adminMiddleware(adminAPI.SitePerfHandler, noGZFlag))
   398  		adminRouter.Methods(http.MethodPost).Path(adminVersion + adminAPIClientDevNull).HandlerFunc(adminMiddleware(adminAPI.ClientDevNull, noGZFlag))
   399  		adminRouter.Methods(http.MethodPost).Path(adminVersion + adminAPIClientDevExtraTime).HandlerFunc(adminMiddleware(adminAPI.ClientDevNullExtraTime, noGZFlag))
   400  
   401  		// HTTP Trace
   402  		adminRouter.Methods(http.MethodGet).Path(adminVersion + "/trace").HandlerFunc(adminMiddleware(adminAPI.TraceHandler, noObjLayerFlag))
   403  
   404  		// Console Logs
   405  		adminRouter.Methods(http.MethodGet).Path(adminVersion + "/log").HandlerFunc(adminMiddleware(adminAPI.ConsoleLogHandler, traceAllFlag))
   406  
   407  		// -- KMS APIs --
   408  		//
   409  		adminRouter.Methods(http.MethodPost).Path(adminVersion + "/kms/status").HandlerFunc(adminMiddleware(adminAPI.KMSStatusHandler, traceAllFlag))
   410  		adminRouter.Methods(http.MethodPost).Path(adminVersion+"/kms/key/create").HandlerFunc(adminMiddleware(adminAPI.KMSCreateKeyHandler, traceAllFlag)).Queries("key-id", "{key-id:.*}")
   411  		adminRouter.Methods(http.MethodGet).Path(adminVersion + "/kms/key/status").HandlerFunc(adminMiddleware(adminAPI.KMSKeyStatusHandler, traceAllFlag))
   412  
   413  		// Keep obdinfo for backward compatibility with mc
   414  		adminRouter.Methods(http.MethodGet).Path(adminVersion + "/obdinfo").
   415  			HandlerFunc(adminMiddleware(adminAPI.HealthInfoHandler))
   416  		// -- Health API --
   417  		adminRouter.Methods(http.MethodGet).Path(adminVersion + "/healthinfo").
   418  			HandlerFunc(adminMiddleware(adminAPI.HealthInfoHandler))
   419  	}
   420  
   421  	// If none of the routes match add default error handler routes
   422  	adminRouter.NotFoundHandler = httpTraceAll(errorResponseHandler)
   423  	adminRouter.MethodNotAllowedHandler = httpTraceAll(methodNotAllowedHandler("Admin"))
   424  }