| 
									
										
										
										
											2021-04-19 03:41:13 +08:00
										 |  |  | // Copyright (c) 2015-2021 MinIO, Inc.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // This file is part of MinIO Object Storage stack
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // 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 <http://www.gnu.org/licenses/>.
 | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | package cmd | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"context" | 
					
						
							|  |  |  | 	"encoding/gob" | 
					
						
							|  |  |  | 	"errors" | 
					
						
							|  |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2019-08-19 10:56:32 +08:00
										 |  |  | 	"io" | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	"net/http" | 
					
						
							| 
									
										
										
										
											2019-06-07 08:46:22 +08:00
										 |  |  | 	"strconv" | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	"strings" | 
					
						
							| 
									
										
										
										
											2021-07-28 03:55:56 +08:00
										 |  |  | 	"sync/atomic" | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	"time" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-28 22:36:34 +08:00
										 |  |  | 	"github.com/dustin/go-humanize" | 
					
						
							| 
									
										
										
										
											2022-12-07 05:46:50 +08:00
										 |  |  | 	"github.com/minio/madmin-go/v2" | 
					
						
							| 
									
										
										
										
											2021-06-02 05:59:40 +08:00
										 |  |  | 	b "github.com/minio/minio/internal/bucket/bandwidth" | 
					
						
							|  |  |  | 	"github.com/minio/minio/internal/event" | 
					
						
							|  |  |  | 	"github.com/minio/minio/internal/logger" | 
					
						
							| 
									
										
										
										
											2022-07-06 05:45:49 +08:00
										 |  |  | 	"github.com/minio/minio/internal/pubsub" | 
					
						
							| 
									
										
										
										
											2023-01-23 19:12:47 +08:00
										 |  |  | 	"github.com/minio/mux" | 
					
						
							| 
									
										
										
										
											2023-02-22 13:21:17 +08:00
										 |  |  | 	"github.com/minio/pkg/logger/message/log" | 
					
						
							| 
									
										
										
										
											2020-10-29 00:18:35 +08:00
										 |  |  | 	"github.com/tinylib/msgp/msgp" | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // To abstract a node over network.
 | 
					
						
							| 
									
										
										
										
											2020-05-20 04:53:54 +08:00
										 |  |  | type peerRESTServer struct{} | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | // GetLocksHandler - returns list of older lock from the server.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) GetLocksHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ctx := newContext(r, w, "GetLocks") | 
					
						
							| 
									
										
										
										
											2020-12-10 23:28:37 +08:00
										 |  |  | 	logger.LogIf(ctx, gob.NewEncoder(w).Encode(globalLockServer.DupLockMap())) | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-07 08:46:22 +08:00
										 |  |  | // DeletePolicyHandler - deletes a policy on the server.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) DeletePolicyHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 00:59:52 +08:00
										 |  |  | 	objAPI := newObjectLayerFn() | 
					
						
							| 
									
										
										
										
											2019-06-07 08:46:22 +08:00
										 |  |  | 	if objAPI == nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errServerNotInitialized) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	vars := mux.Vars(r) | 
					
						
							|  |  |  | 	policyName := vars[peerRESTPolicy] | 
					
						
							|  |  |  | 	if policyName == "" { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("policyName is missing")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-30 06:38:57 +08:00
										 |  |  | 	if err := globalIAMSys.DeletePolicy(r.Context(), policyName, false); err != nil { | 
					
						
							| 
									
										
										
										
											2019-06-07 08:46:22 +08:00
										 |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // LoadPolicyHandler - reloads a policy on the server.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) LoadPolicyHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 00:59:52 +08:00
										 |  |  | 	objAPI := newObjectLayerFn() | 
					
						
							| 
									
										
										
										
											2019-06-07 08:46:22 +08:00
										 |  |  | 	if objAPI == nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errServerNotInitialized) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	vars := mux.Vars(r) | 
					
						
							|  |  |  | 	policyName := vars[peerRESTPolicy] | 
					
						
							|  |  |  | 	if policyName == "" { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("policyName is missing")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-16 06:14:22 +08:00
										 |  |  | 	if err := globalIAMSys.LoadPolicy(r.Context(), objAPI, policyName); err != nil { | 
					
						
							| 
									
										
										
										
											2019-06-07 08:46:22 +08:00
										 |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-14 04:41:06 +08:00
										 |  |  | // LoadPolicyMappingHandler - reloads a policy mapping on the server.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) LoadPolicyMappingHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 00:59:52 +08:00
										 |  |  | 	objAPI := newObjectLayerFn() | 
					
						
							| 
									
										
										
										
											2019-08-14 04:41:06 +08:00
										 |  |  | 	if objAPI == nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errServerNotInitialized) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-25 03:34:52 +08:00
										 |  |  | 	userOrGroup := r.Form.Get(peerRESTUserOrGroup) | 
					
						
							| 
									
										
										
										
											2019-08-14 04:41:06 +08:00
										 |  |  | 	if userOrGroup == "" { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("user-or-group is missing")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-25 03:34:52 +08:00
										 |  |  | 	userType, err := strconv.Atoi(r.Form.Get(peerRESTUserType)) | 
					
						
							| 
									
										
										
										
											2022-08-24 02:11:45 +08:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2022-08-25 03:34:52 +08:00
										 |  |  | 		s.writeErrorResponse(w, fmt.Errorf("user-type `%s` is invalid: %w", r.Form.Get(peerRESTUserType), err)) | 
					
						
							| 
									
										
										
										
											2022-08-24 02:11:45 +08:00
										 |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-08 13:43:01 +08:00
										 |  |  | 	_, isGroup := r.Form[peerRESTIsGroup] | 
					
						
							| 
									
										
										
										
											2022-08-24 02:11:45 +08:00
										 |  |  | 	if err := globalIAMSys.LoadPolicyMapping(r.Context(), objAPI, userOrGroup, IAMUserType(userType), isGroup); err != nil { | 
					
						
							| 
									
										
										
										
											2019-08-14 04:41:06 +08:00
										 |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-25 03:10:09 +08:00
										 |  |  | // DeleteServiceAccountHandler - deletes a service account on the server.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) DeleteServiceAccountHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 00:59:52 +08:00
										 |  |  | 	objAPI := newObjectLayerFn() | 
					
						
							| 
									
										
										
										
											2020-04-25 03:10:09 +08:00
										 |  |  | 	if objAPI == nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errServerNotInitialized) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	vars := mux.Vars(r) | 
					
						
							|  |  |  | 	accessKey := vars[peerRESTUser] | 
					
						
							|  |  |  | 	if accessKey == "" { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("service account name is missing")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-21 18:16:50 +08:00
										 |  |  | 	if err := globalIAMSys.DeleteServiceAccount(r.Context(), accessKey, false); err != nil { | 
					
						
							| 
									
										
										
										
											2020-04-25 03:10:09 +08:00
										 |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // LoadServiceAccountHandler - reloads a service account on the server.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) LoadServiceAccountHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 00:59:52 +08:00
										 |  |  | 	objAPI := newObjectLayerFn() | 
					
						
							| 
									
										
										
										
											2020-04-25 03:10:09 +08:00
										 |  |  | 	if objAPI == nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errServerNotInitialized) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	vars := mux.Vars(r) | 
					
						
							|  |  |  | 	accessKey := vars[peerRESTUser] | 
					
						
							|  |  |  | 	if accessKey == "" { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("service account parameter is missing")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-16 06:14:22 +08:00
										 |  |  | 	if err := globalIAMSys.LoadServiceAccount(r.Context(), accessKey); err != nil { | 
					
						
							| 
									
										
										
										
											2020-04-25 03:10:09 +08:00
										 |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-07 08:46:22 +08:00
										 |  |  | // DeleteUserHandler - deletes a user on the server.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) DeleteUserHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 00:59:52 +08:00
										 |  |  | 	objAPI := newObjectLayerFn() | 
					
						
							| 
									
										
										
										
											2019-06-07 08:46:22 +08:00
										 |  |  | 	if objAPI == nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errServerNotInitialized) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	vars := mux.Vars(r) | 
					
						
							|  |  |  | 	accessKey := vars[peerRESTUser] | 
					
						
							|  |  |  | 	if accessKey == "" { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("username is missing")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-21 18:16:50 +08:00
										 |  |  | 	if err := globalIAMSys.DeleteUser(r.Context(), accessKey, false); err != nil { | 
					
						
							| 
									
										
										
										
											2019-06-07 08:46:22 +08:00
										 |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // LoadUserHandler - reloads a user on the server.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) LoadUserHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 00:59:52 +08:00
										 |  |  | 	objAPI := newObjectLayerFn() | 
					
						
							| 
									
										
										
										
											2019-06-07 08:46:22 +08:00
										 |  |  | 	if objAPI == nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errServerNotInitialized) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	vars := mux.Vars(r) | 
					
						
							|  |  |  | 	accessKey := vars[peerRESTUser] | 
					
						
							|  |  |  | 	if accessKey == "" { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("username is missing")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	temp, err := strconv.ParseBool(vars[peerRESTUserTemp]) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-03 01:15:06 +08:00
										 |  |  | 	userType := regUser | 
					
						
							| 
									
										
										
										
											2020-03-18 01:36:13 +08:00
										 |  |  | 	if temp { | 
					
						
							|  |  |  | 		userType = stsUser | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-16 06:14:22 +08:00
										 |  |  | 	if err = globalIAMSys.LoadUser(r.Context(), objAPI, accessKey, userType); err != nil { | 
					
						
							| 
									
										
										
										
											2019-06-07 08:46:22 +08:00
										 |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-03 05:25:00 +08:00
										 |  |  | // LoadGroupHandler - reloads group along with members list.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) LoadGroupHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 00:59:52 +08:00
										 |  |  | 	objAPI := newObjectLayerFn() | 
					
						
							| 
									
										
										
										
											2019-08-03 05:25:00 +08:00
										 |  |  | 	if objAPI == nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errServerNotInitialized) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	vars := mux.Vars(r) | 
					
						
							|  |  |  | 	group := vars[peerRESTGroup] | 
					
						
							| 
									
										
										
										
											2021-11-16 06:14:22 +08:00
										 |  |  | 	err := globalIAMSys.LoadGroup(r.Context(), objAPI, group) | 
					
						
							| 
									
										
										
										
											2019-08-03 05:25:00 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | // StartProfilingHandler - Issues the start profiling command.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) StartProfilingHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	vars := mux.Vars(r) | 
					
						
							| 
									
										
										
										
											2020-01-11 09:19:58 +08:00
										 |  |  | 	profiles := strings.Split(vars[peerRESTProfiler], ",") | 
					
						
							|  |  |  | 	if len(profiles) == 0 { | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 		s.writeErrorResponse(w, errors.New("profiler name is missing")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-01-11 09:19:58 +08:00
										 |  |  | 	globalProfilerMu.Lock() | 
					
						
							|  |  |  | 	defer globalProfilerMu.Unlock() | 
					
						
							|  |  |  | 	if globalProfiler == nil { | 
					
						
							|  |  |  | 		globalProfiler = make(map[string]minioProfiler, 10) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-11 09:19:58 +08:00
										 |  |  | 	// Stop profiler of all types if already running
 | 
					
						
							|  |  |  | 	for k, v := range globalProfiler { | 
					
						
							|  |  |  | 		for _, p := range profiles { | 
					
						
							|  |  |  | 			if p == k { | 
					
						
							|  |  |  | 				v.Stop() | 
					
						
							|  |  |  | 				delete(globalProfiler, k) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-11 09:19:58 +08:00
										 |  |  | 	for _, profiler := range profiles { | 
					
						
							|  |  |  | 		prof, err := startProfiler(profiler) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		globalProfiler[profiler] = prof | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-11 09:19:58 +08:00
										 |  |  | // DownloadProfilingDataHandler - returns profiled data.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) DownloadProfilingDataHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ctx := newContext(r, w, "DownloadProfiling") | 
					
						
							|  |  |  | 	profileData, err := getProfileData() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	logger.LogIf(ctx, gob.NewEncoder(w).Encode(profileData)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-02 06:31:35 +08:00
										 |  |  | func (s *peerRESTServer) LocalStorageInfoHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ctx := newContext(r, w, "LocalStorageInfo") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	objLayer := newObjectLayerFn() | 
					
						
							|  |  |  | 	if objLayer == nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errServerNotInitialized) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	logger.LogIf(ctx, gob.NewEncoder(w).Encode(objLayer.LocalStorageInfo(r.Context()))) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-12 06:27:03 +08:00
										 |  |  | // ServerInfoHandler - returns Server Info
 | 
					
						
							|  |  |  | func (s *peerRESTServer) ServerInfoHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ctx := newContext(r, w, "ServerInfo") | 
					
						
							|  |  |  | 	info := getLocalServerProperty(globalEndpoints, r) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	logger.LogIf(ctx, gob.NewEncoder(w).Encode(info)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-01 23:55:49 +08:00
										 |  |  | // GetCPUsHandler - returns CPU info.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) GetCPUsHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							| 
									
										
										
										
											2020-03-27 12:07:39 +08:00
										 |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-19 00:59:45 +08:00
										 |  |  | 	ctx, cancel := context.WithCancel(r.Context()) | 
					
						
							| 
									
										
										
										
											2020-03-27 12:07:39 +08:00
										 |  |  | 	defer cancel() | 
					
						
							| 
									
										
										
										
											2020-05-19 00:59:45 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-01 23:55:49 +08:00
										 |  |  | 	info := madmin.GetCPUs(ctx, r.Host) | 
					
						
							| 
									
										
										
										
											2020-03-27 12:07:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	logger.LogIf(ctx, gob.NewEncoder(w).Encode(info)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-01 23:55:49 +08:00
										 |  |  | // GetPartitionsHandler - returns disk partition information.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) GetPartitionsHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							| 
									
										
										
										
											2020-03-27 12:07:39 +08:00
										 |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-19 00:59:45 +08:00
										 |  |  | 	ctx, cancel := context.WithCancel(r.Context()) | 
					
						
							| 
									
										
										
										
											2020-03-27 12:07:39 +08:00
										 |  |  | 	defer cancel() | 
					
						
							| 
									
										
										
										
											2020-05-19 00:59:45 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-01 23:55:49 +08:00
										 |  |  | 	info := madmin.GetPartitions(ctx, r.Host) | 
					
						
							| 
									
										
										
										
											2020-03-27 12:07:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	logger.LogIf(ctx, gob.NewEncoder(w).Encode(info)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-01 23:55:49 +08:00
										 |  |  | // GetOSInfoHandler - returns operating system's information.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) GetOSInfoHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							| 
									
										
										
										
											2020-03-27 12:07:39 +08:00
										 |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-19 00:59:45 +08:00
										 |  |  | 	ctx, cancel := context.WithCancel(r.Context()) | 
					
						
							| 
									
										
										
										
											2020-03-27 12:07:39 +08:00
										 |  |  | 	defer cancel() | 
					
						
							| 
									
										
										
										
											2020-05-19 00:59:45 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-01 23:55:49 +08:00
										 |  |  | 	info := madmin.GetOSInfo(ctx, r.Host) | 
					
						
							| 
									
										
										
										
											2020-03-27 12:07:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	logger.LogIf(ctx, gob.NewEncoder(w).Encode(info)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-01 23:55:49 +08:00
										 |  |  | // GetProcInfoHandler - returns this MinIO process information.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) GetProcInfoHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							| 
									
										
										
										
											2020-03-27 12:07:39 +08:00
										 |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-19 00:59:45 +08:00
										 |  |  | 	ctx, cancel := context.WithCancel(r.Context()) | 
					
						
							| 
									
										
										
										
											2020-03-27 12:07:39 +08:00
										 |  |  | 	defer cancel() | 
					
						
							| 
									
										
										
										
											2020-05-19 00:59:45 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-01 23:55:49 +08:00
										 |  |  | 	info := madmin.GetProcInfo(ctx, r.Host) | 
					
						
							| 
									
										
										
										
											2020-03-27 12:07:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	logger.LogIf(ctx, gob.NewEncoder(w).Encode(info)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-01 23:55:49 +08:00
										 |  |  | // GetMemInfoHandler - returns memory information.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) GetMemInfoHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							| 
									
										
										
										
											2020-03-27 12:07:39 +08:00
										 |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-19 00:59:45 +08:00
										 |  |  | 	ctx, cancel := context.WithCancel(r.Context()) | 
					
						
							| 
									
										
										
										
											2020-03-27 12:07:39 +08:00
										 |  |  | 	defer cancel() | 
					
						
							| 
									
										
										
										
											2020-05-19 00:59:45 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-01 23:55:49 +08:00
										 |  |  | 	info := madmin.GetMemInfo(ctx, r.Host) | 
					
						
							| 
									
										
										
										
											2020-03-27 12:07:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	logger.LogIf(ctx, gob.NewEncoder(w).Encode(info)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-06 05:45:49 +08:00
										 |  |  | // GetMetricsHandler - returns server metrics.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) GetMetricsHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var types madmin.MetricType | 
					
						
							| 
									
										
										
										
											2022-10-03 17:10:15 +08:00
										 |  |  | 	if t, _ := strconv.ParseUint(r.Form.Get(peerRESTMetricsTypes), 10, 64); t != 0 { | 
					
						
							| 
									
										
										
										
											2022-07-06 05:45:49 +08:00
										 |  |  | 		types = madmin.MetricType(t) | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		types = madmin.MetricsAll | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-16 22:13:49 +08:00
										 |  |  | 	diskMap := make(map[string]struct{}) | 
					
						
							| 
									
										
										
										
											2022-10-03 17:10:15 +08:00
										 |  |  | 	for _, disk := range r.Form[peerRESTDisk] { | 
					
						
							|  |  |  | 		diskMap[disk] = struct{}{} | 
					
						
							| 
									
										
										
										
											2022-08-16 22:13:49 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-10-03 17:10:15 +08:00
										 |  |  | 	jobID := r.Form.Get(peerRESTJobID) | 
					
						
							| 
									
										
										
										
											2022-11-14 23:16:40 +08:00
										 |  |  | 	depID := r.Form.Get(peerRESTDepID) | 
					
						
							| 
									
										
										
										
											2022-08-16 22:13:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-06 05:45:49 +08:00
										 |  |  | 	ctx, cancel := context.WithCancel(r.Context()) | 
					
						
							|  |  |  | 	defer cancel() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-03 17:10:15 +08:00
										 |  |  | 	info := collectLocalMetrics(types, collectMetricsOpts{ | 
					
						
							|  |  |  | 		disks: diskMap, | 
					
						
							|  |  |  | 		jobID: jobID, | 
					
						
							| 
									
										
										
										
											2022-11-14 23:16:40 +08:00
										 |  |  | 		depID: depID, | 
					
						
							| 
									
										
										
										
											2022-10-03 17:10:15 +08:00
										 |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2022-07-06 05:45:49 +08:00
										 |  |  | 	logger.LogIf(ctx, gob.NewEncoder(w).Encode(info)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 08:09:37 +08:00
										 |  |  | // GetSysConfigHandler - returns system config information.
 | 
					
						
							|  |  |  | // (only the config that are of concern to minio)
 | 
					
						
							|  |  |  | func (s *peerRESTServer) GetSysConfigHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ctx, cancel := context.WithCancel(r.Context()) | 
					
						
							|  |  |  | 	defer cancel() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	info := madmin.GetSysConfig(ctx, r.Host) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	logger.LogIf(ctx, gob.NewEncoder(w).Encode(info)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-13 09:58:40 +08:00
										 |  |  | // GetSysServicesHandler - returns system services information.
 | 
					
						
							|  |  |  | // (only the services that are of concern to minio)
 | 
					
						
							|  |  |  | func (s *peerRESTServer) GetSysServicesHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ctx, cancel := context.WithCancel(r.Context()) | 
					
						
							|  |  |  | 	defer cancel() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	info := madmin.GetSysServices(ctx, r.Host) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	logger.LogIf(ctx, gob.NewEncoder(w).Encode(info)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // GetSysErrorsHandler - returns system level errors
 | 
					
						
							| 
									
										
										
										
											2021-07-30 14:05:34 +08:00
										 |  |  | func (s *peerRESTServer) GetSysErrorsHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ctx, cancel := context.WithCancel(r.Context()) | 
					
						
							|  |  |  | 	defer cancel() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	info := madmin.GetSysErrors(ctx, r.Host) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	logger.LogIf(ctx, gob.NewEncoder(w).Encode(info)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-20 04:53:54 +08:00
										 |  |  | // DeleteBucketMetadataHandler - Delete in memory bucket metadata
 | 
					
						
							|  |  |  | func (s *peerRESTServer) DeleteBucketMetadataHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	vars := mux.Vars(r) | 
					
						
							|  |  |  | 	bucketName := vars[peerRESTBucket] | 
					
						
							|  |  |  | 	if bucketName == "" { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Bucket name is missing")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-05 06:34:33 +08:00
										 |  |  | 	globalReplicationStats.Delete(bucketName) | 
					
						
							| 
									
										
										
										
											2020-05-20 04:53:54 +08:00
										 |  |  | 	globalBucketMetadataSys.Remove(bucketName) | 
					
						
							| 
									
										
										
										
											2021-06-24 23:39:58 +08:00
										 |  |  | 	globalBucketTargetSys.Delete(bucketName) | 
					
						
							| 
									
										
										
										
											2022-08-24 21:42:36 +08:00
										 |  |  | 	globalEventNotifier.RemoveNotification(bucketName) | 
					
						
							| 
									
										
										
										
											2022-06-15 06:14:24 +08:00
										 |  |  | 	globalBucketConnStats.delete(bucketName) | 
					
						
							| 
									
										
										
										
											2020-11-01 00:46:18 +08:00
										 |  |  | 	if localMetacacheMgr != nil { | 
					
						
							|  |  |  | 		localMetacacheMgr.deleteBucketCache(bucketName) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-07 07:36:31 +08:00
										 |  |  | // ReloadSiteReplicationConfigHandler - reloads site replication configuration from the disks
 | 
					
						
							|  |  |  | func (s *peerRESTServer) ReloadSiteReplicationConfigHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ctx := newContext(r, w, "LoadSiteReplication") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	objAPI := newObjectLayerFn() | 
					
						
							|  |  |  | 	if objAPI == nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errServerNotInitialized) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	logger.LogIf(r.Context(), globalSiteReplicationSys.Init(ctx, objAPI)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-24 00:15:30 +08:00
										 |  |  | // GetAllBucketStatsHandler - fetches bucket replication stats for all buckets from this peer.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) GetAllBucketStatsHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	replicationStats := globalReplicationStats.GetAll() | 
					
						
							|  |  |  | 	bucketStatsMap := make(map[string]BucketStats, len(replicationStats)) | 
					
						
							|  |  |  | 	for k, v := range replicationStats { | 
					
						
							|  |  |  | 		bucketStatsMap[k] = BucketStats{ | 
					
						
							|  |  |  | 			ReplicationStats: v, | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-09-13 03:40:02 +08:00
										 |  |  | 	logger.LogIf(r.Context(), msgp.Encode(w, &BucketStatsMap{Stats: bucketStatsMap, Timestamp: UTCNow()})) | 
					
						
							| 
									
										
										
										
											2022-05-24 00:15:30 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-05 06:34:33 +08:00
										 |  |  | // GetBucketStatsHandler - fetches current in-memory bucket stats, currently only
 | 
					
						
							| 
									
										
										
										
											2022-05-24 00:15:30 +08:00
										 |  |  | // returns BucketStats, that currently includes ReplicationStats.
 | 
					
						
							| 
									
										
										
										
											2021-04-05 06:34:33 +08:00
										 |  |  | func (s *peerRESTServer) GetBucketStatsHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	vars := mux.Vars(r) | 
					
						
							|  |  |  | 	bucketName := vars[peerRESTBucket] | 
					
						
							|  |  |  | 	if bucketName == "" { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Bucket name is missing")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	bs := BucketStats{ | 
					
						
							|  |  |  | 		ReplicationStats: globalReplicationStats.Get(bucketName), | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	logger.LogIf(r.Context(), msgp.Encode(w, &bs)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-20 04:53:54 +08:00
										 |  |  | // LoadBucketMetadataHandler - reloads in memory bucket metadata
 | 
					
						
							|  |  |  | func (s *peerRESTServer) LoadBucketMetadataHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	vars := mux.Vars(r) | 
					
						
							| 
									
										
										
										
											2020-05-20 04:53:54 +08:00
										 |  |  | 	bucketName := vars[peerRESTBucket] | 
					
						
							|  |  |  | 	if bucketName == "" { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Bucket name is missing")) | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 00:59:52 +08:00
										 |  |  | 	objAPI := newObjectLayerFn() | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	if objAPI == nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errServerNotInitialized) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-01-10 18:35:06 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-20 04:53:54 +08:00
										 |  |  | 	meta, err := loadBucketMetadata(r.Context(), objAPI, bucketName) | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2020-05-21 01:18:15 +08:00
										 |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-20 04:53:54 +08:00
										 |  |  | 	globalBucketMetadataSys.Set(bucketName, meta) | 
					
						
							| 
									
										
										
										
											2020-06-27 04:17:31 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if meta.notificationConfig != nil { | 
					
						
							| 
									
										
										
										
											2022-08-24 21:42:36 +08:00
										 |  |  | 		globalEventNotifier.AddRulesMap(bucketName, meta.notificationConfig.ToRulesMap()) | 
					
						
							| 
									
										
										
										
											2020-06-27 04:17:31 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-08-07 08:10:21 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if meta.bucketTargetConfig != nil { | 
					
						
							| 
									
										
										
										
											2020-10-10 11:36:00 +08:00
										 |  |  | 		globalBucketTargetSys.UpdateAllTargets(bucketName, meta.bucketTargetConfig) | 
					
						
							| 
									
										
										
										
											2020-08-07 08:10:21 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-29 00:18:35 +08:00
										 |  |  | func (s *peerRESTServer) GetMetacacheListingHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	ctx := newContext(r, w, "GetMetacacheListing") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var opts listPathOptions | 
					
						
							|  |  |  | 	err := gob.NewDecoder(r.Body).Decode(&opts) | 
					
						
							|  |  |  | 	if err != nil && err != io.EOF { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	resp := localMetacacheMgr.getBucket(ctx, opts.Bucket).findCache(opts) | 
					
						
							|  |  |  | 	logger.LogIf(ctx, msgp.Encode(w, &resp)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (s *peerRESTServer) UpdateMetacacheListingHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	ctx := newContext(r, w, "UpdateMetacacheListing") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var req metacache | 
					
						
							|  |  |  | 	err := msgp.Decode(r.Body, &req) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-11-04 04:47:52 +08:00
										 |  |  | 	cache, err := localMetacacheMgr.updateCacheEntry(req) | 
					
						
							| 
									
										
										
										
											2020-10-29 00:18:35 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// Return updated metadata.
 | 
					
						
							|  |  |  | 	logger.LogIf(ctx, msgp.Encode(w, &cache)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | // PutBucketNotificationHandler - Set bucket policy.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) PutBucketNotificationHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	vars := mux.Vars(r) | 
					
						
							|  |  |  | 	bucketName := vars[peerRESTBucket] | 
					
						
							|  |  |  | 	if bucketName == "" { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Bucket name is missing")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var rulesMap event.RulesMap | 
					
						
							|  |  |  | 	if r.ContentLength < 0 { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errInvalidArgument) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err := gob.NewDecoder(r.Body).Decode(&rulesMap) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-24 21:42:36 +08:00
										 |  |  | 	globalEventNotifier.AddRulesMap(bucketName, rulesMap) | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-24 08:38:39 +08:00
										 |  |  | // Return disk IDs of all the local disks.
 | 
					
						
							| 
									
										
										
										
											2020-12-02 05:50:33 +08:00
										 |  |  | func getLocalDiskIDs(z *erasureServerPools) []string { | 
					
						
							| 
									
										
										
										
											2020-05-24 08:38:39 +08:00
										 |  |  | 	var ids []string | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-07 01:35:47 +08:00
										 |  |  | 	for poolIdx := range z.serverPools { | 
					
						
							|  |  |  | 		for _, set := range z.serverPools[poolIdx].sets { | 
					
						
							| 
									
										
										
										
											2020-05-24 08:38:39 +08:00
										 |  |  | 			disks := set.getDisks() | 
					
						
							|  |  |  | 			for _, disk := range disks { | 
					
						
							|  |  |  | 				if disk == nil { | 
					
						
							|  |  |  | 					continue | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				if disk.IsLocal() { | 
					
						
							|  |  |  | 					id, err := disk.GetDiskID() | 
					
						
							|  |  |  | 					if err != nil { | 
					
						
							|  |  |  | 						continue | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					if id == "" { | 
					
						
							|  |  |  | 						continue | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					ids = append(ids, id) | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ids | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-18 05:49:26 +08:00
										 |  |  | // HealthHandler - returns true of health
 | 
					
						
							|  |  |  | func (s *peerRESTServer) HealthHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	s.IsValid(w, r) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-24 08:38:39 +08:00
										 |  |  | // GetLocalDiskIDs - Return disk IDs of all the local disks.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) GetLocalDiskIDs(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ctx := newContext(r, w, "GetLocalDiskIDs") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 00:59:52 +08:00
										 |  |  | 	objLayer := newObjectLayerFn() | 
					
						
							| 
									
										
										
										
											2020-05-24 08:38:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Service not initialized yet
 | 
					
						
							|  |  |  | 	if objLayer == nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errServerNotInitialized) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-02 05:50:33 +08:00
										 |  |  | 	z, ok := objLayer.(*erasureServerPools) | 
					
						
							| 
									
										
										
										
											2020-05-24 08:38:39 +08:00
										 |  |  | 	if !ok { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errServerNotInitialized) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ids := getLocalDiskIDs(z) | 
					
						
							|  |  |  | 	logger.LogIf(ctx, gob.NewEncoder(w).Encode(ids)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-26 08:49:47 +08:00
										 |  |  | // DownloadBinary - updates the current server.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) DownloadBinaryHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							| 
									
										
										
										
											2019-08-29 06:04:43 +08:00
										 |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-23 23:03:31 +08:00
										 |  |  | 	if r.ContentLength < 0 { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errInvalidArgument) | 
					
						
							|  |  |  | 		return | 
					
						
							| 
									
										
										
										
											2019-08-29 06:04:43 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-07-23 23:03:31 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-26 08:49:47 +08:00
										 |  |  | 	var info binaryInfo | 
					
						
							| 
									
										
										
										
											2020-07-23 23:03:31 +08:00
										 |  |  | 	err := gob.NewDecoder(r.Body).Decode(&info) | 
					
						
							| 
									
										
										
										
											2019-08-29 06:04:43 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-07-23 23:03:31 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-29 23:34:30 +08:00
										 |  |  | 	if err = verifyBinary(info.URL, info.Sha256Sum, info.ReleaseInfo, getMinioMode(), info.BinaryFile); err != nil { | 
					
						
							| 
									
										
										
										
											2022-07-26 08:49:47 +08:00
										 |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // CommitBinary - overwrites the current binary with the new one.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) CommitBinaryHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err := commitBinary(); err != nil { | 
					
						
							| 
									
										
										
										
											2020-07-23 23:03:31 +08:00
										 |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							| 
									
										
										
										
											2019-08-29 06:04:43 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-24 04:02:16 +08:00
										 |  |  | var errUnsupportedSignal = fmt.Errorf("unsupported signal") | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | // SignalServiceHandler - signal service handler.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) SignalServiceHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	vars := mux.Vars(r) | 
					
						
							|  |  |  | 	signalString := vars[peerRESTSignal] | 
					
						
							|  |  |  | 	if signalString == "" { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("signal name is missing")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-08-28 02:37:47 +08:00
										 |  |  | 	si, err := strconv.Atoi(signalString) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	signal := serviceSignal(si) | 
					
						
							| 
									
										
										
										
											2019-08-29 06:04:43 +08:00
										 |  |  | 	switch signal { | 
					
						
							|  |  |  | 	case serviceRestart: | 
					
						
							|  |  |  | 		globalServiceSignalCh <- signal | 
					
						
							|  |  |  | 	case serviceStop: | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 		globalServiceSignalCh <- signal | 
					
						
							| 
									
										
										
										
											2021-11-24 04:02:16 +08:00
										 |  |  | 	case serviceFreeze: | 
					
						
							|  |  |  | 		freezeServices() | 
					
						
							|  |  |  | 	case serviceUnFreeze: | 
					
						
							|  |  |  | 		unfreezeServices() | 
					
						
							| 
									
										
										
										
											2020-12-05 01:32:35 +08:00
										 |  |  | 	case serviceReloadDynamic: | 
					
						
							| 
									
										
										
										
											2021-01-23 04:09:24 +08:00
										 |  |  | 		objAPI := newObjectLayerFn() | 
					
						
							|  |  |  | 		if objAPI == nil { | 
					
						
							|  |  |  | 			s.writeErrorResponse(w, errServerNotInitialized) | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		srvCfg, err := getValidConfig(objAPI) | 
					
						
							| 
									
										
										
										
											2020-12-05 01:32:35 +08:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2022-05-17 07:10:51 +08:00
										 |  |  | 		subSys := r.Form.Get(peerRESTSubSys) | 
					
						
							|  |  |  | 		// Apply dynamic values.
 | 
					
						
							|  |  |  | 		if subSys == "" { | 
					
						
							|  |  |  | 			err = applyDynamicConfig(r.Context(), objAPI, srvCfg) | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			err = applyDynamicConfigForSubSys(r.Context(), objAPI, srvCfg, subSys) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							| 
									
										
										
										
											2020-12-05 01:32:35 +08:00
										 |  |  | 			s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	default: | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errUnsupportedSignal) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-13 02:01:23 +08:00
										 |  |  | // ListenHandler sends http trace messages back to peer rest client
 | 
					
						
							|  |  |  | func (s *peerRESTServer) ListenHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 		s.writeErrorResponse(w, errors.New("invalid request")) | 
					
						
							| 
									
										
										
										
											2019-12-13 02:01:23 +08:00
										 |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-08 13:43:01 +08:00
										 |  |  | 	values := r.Form | 
					
						
							| 
									
										
										
										
											2019-12-17 12:30:57 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	var prefix string | 
					
						
							|  |  |  | 	if len(values[peerRESTListenPrefix]) > 1 { | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 		s.writeErrorResponse(w, errors.New("invalid request")) | 
					
						
							| 
									
										
										
										
											2019-12-17 12:30:57 +08:00
										 |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if len(values[peerRESTListenPrefix]) == 1 { | 
					
						
							|  |  |  | 		if err := event.ValidateFilterRuleValue(values[peerRESTListenPrefix][0]); err != nil { | 
					
						
							|  |  |  | 			s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		prefix = values[peerRESTListenPrefix][0] | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var suffix string | 
					
						
							|  |  |  | 	if len(values[peerRESTListenSuffix]) > 1 { | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 		s.writeErrorResponse(w, errors.New("invalid request")) | 
					
						
							| 
									
										
										
										
											2019-12-17 12:30:57 +08:00
										 |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if len(values[peerRESTListenSuffix]) == 1 { | 
					
						
							|  |  |  | 		if err := event.ValidateFilterRuleValue(values[peerRESTListenSuffix][0]); err != nil { | 
					
						
							|  |  |  | 			s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		suffix = values[peerRESTListenSuffix][0] | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	pattern := event.NewPattern(prefix, suffix) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var eventNames []event.Name | 
					
						
							| 
									
										
										
										
											2022-07-06 05:45:49 +08:00
										 |  |  | 	var mask pubsub.Mask | 
					
						
							| 
									
										
										
										
											2019-12-17 12:30:57 +08:00
										 |  |  | 	for _, ev := range values[peerRESTListenEvents] { | 
					
						
							|  |  |  | 		eventName, err := event.ParseName(ev) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2022-07-06 05:45:49 +08:00
										 |  |  | 		mask.MergeMaskable(eventName) | 
					
						
							| 
									
										
										
										
											2019-12-17 12:30:57 +08:00
										 |  |  | 		eventNames = append(eventNames, eventName) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	rulesMap := event.NewRulesMap(eventNames, pattern, event.TargetID{ID: mustGetUUID()}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-06 05:45:49 +08:00
										 |  |  | 	doneCh := r.Context().Done() | 
					
						
							| 
									
										
										
										
											2019-12-13 02:01:23 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Listen Publisher uses nonblocking publish and hence does not wait for slow subscribers.
 | 
					
						
							|  |  |  | 	// Use buffered channel to take care of burst sends or slow w.Write()
 | 
					
						
							| 
									
										
										
										
											2022-10-29 01:55:42 +08:00
										 |  |  | 	ch := make(chan event.Event, 2000) | 
					
						
							| 
									
										
										
										
											2019-12-13 02:01:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-29 01:55:42 +08:00
										 |  |  | 	err := globalHTTPListen.Subscribe(mask, ch, doneCh, func(ev event.Event) bool { | 
					
						
							| 
									
										
										
										
											2020-07-21 03:52:49 +08:00
										 |  |  | 		if ev.S3.Bucket.Name != "" && values.Get(peerRESTListenBucket) != "" { | 
					
						
							|  |  |  | 			if ev.S3.Bucket.Name != values.Get(peerRESTListenBucket) { | 
					
						
							|  |  |  | 				return false | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2019-12-21 03:45:03 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-04-27 21:25:05 +08:00
										 |  |  | 		return rulesMap.MatchSimple(ev.EventName, ev.S3.Object.Key) | 
					
						
							| 
									
										
										
										
											2022-07-06 05:45:49 +08:00
										 |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2022-06-06 05:29:12 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-12-13 02:01:23 +08:00
										 |  |  | 	keepAliveTicker := time.NewTicker(500 * time.Millisecond) | 
					
						
							|  |  |  | 	defer keepAliveTicker.Stop() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	enc := gob.NewEncoder(w) | 
					
						
							|  |  |  | 	for { | 
					
						
							|  |  |  | 		select { | 
					
						
							|  |  |  | 		case ev := <-ch: | 
					
						
							|  |  |  | 			if err := enc.Encode(ev); err != nil { | 
					
						
							|  |  |  | 				return | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2022-07-06 05:45:49 +08:00
										 |  |  | 			if len(ch) == 0 { | 
					
						
							|  |  |  | 				// Flush if nothing is queued
 | 
					
						
							|  |  |  | 				w.(http.Flusher).Flush() | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2022-05-07 03:39:58 +08:00
										 |  |  | 		case <-r.Context().Done(): | 
					
						
							|  |  |  | 			return | 
					
						
							| 
									
										
										
										
											2019-12-13 02:01:23 +08:00
										 |  |  | 		case <-keepAliveTicker.C: | 
					
						
							|  |  |  | 			if err := enc.Encode(&event.Event{}); err != nil { | 
					
						
							|  |  |  | 				return | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			w.(http.Flusher).Flush() | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-09 06:54:41 +08:00
										 |  |  | // TraceHandler sends http trace messages back to peer rest client
 | 
					
						
							|  |  |  | func (s *peerRESTServer) TraceHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-03-27 14:24:07 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-06 05:45:49 +08:00
										 |  |  | 	var traceOpts madmin.ServiceTraceOpts | 
					
						
							|  |  |  | 	err := traceOpts.ParseParams(r) | 
					
						
							| 
									
										
										
										
											2021-03-27 14:24:07 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-06-09 06:54:41 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-27 13:41:12 +08:00
										 |  |  | 	// Trace Publisher uses nonblocking publish and hence does not wait for slow subscribers.
 | 
					
						
							|  |  |  | 	// Use buffered channel to take care of burst sends or slow w.Write()
 | 
					
						
							| 
									
										
										
										
											2022-10-29 01:55:42 +08:00
										 |  |  | 	ch := make(chan madmin.TraceInfo, 2000) | 
					
						
							|  |  |  | 	err = globalTrace.Subscribe(traceOpts.TraceTypes(), ch, r.Context().Done(), func(entry madmin.TraceInfo) bool { | 
					
						
							|  |  |  | 		return shouldTrace(entry, traceOpts) | 
					
						
							| 
									
										
										
										
											2022-07-06 05:45:49 +08:00
										 |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2022-06-06 05:29:12 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-03-18 07:01:03 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Publish bootstrap events that have already occurred before client could subscribe.
 | 
					
						
							|  |  |  | 	if traceOpts.TraceTypes().Contains(madmin.TraceBootstrap) { | 
					
						
							|  |  |  | 		go globalBootstrapTracer.Publish(r.Context(), globalTrace) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-01 02:08:39 +08:00
										 |  |  | 	keepAliveTicker := time.NewTicker(500 * time.Millisecond) | 
					
						
							|  |  |  | 	defer keepAliveTicker.Stop() | 
					
						
							| 
									
										
										
										
											2019-06-27 13:41:12 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	enc := gob.NewEncoder(w) | 
					
						
							| 
									
										
										
										
											2019-06-09 06:54:41 +08:00
										 |  |  | 	for { | 
					
						
							|  |  |  | 		select { | 
					
						
							|  |  |  | 		case entry := <-ch: | 
					
						
							| 
									
										
										
										
											2019-06-27 13:41:12 +08:00
										 |  |  | 			if err := enc.Encode(entry); err != nil { | 
					
						
							| 
									
										
										
										
											2019-06-09 06:54:41 +08:00
										 |  |  | 				return | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2022-05-07 03:39:58 +08:00
										 |  |  | 		case <-r.Context().Done(): | 
					
						
							|  |  |  | 			return | 
					
						
							| 
									
										
										
										
											2019-08-01 02:08:39 +08:00
										 |  |  | 		case <-keepAliveTicker.C: | 
					
						
							| 
									
										
										
										
											2021-05-06 23:52:02 +08:00
										 |  |  | 			if err := enc.Encode(&madmin.TraceInfo{}); err != nil { | 
					
						
							| 
									
										
										
										
											2019-08-01 02:08:39 +08:00
										 |  |  | 				return | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			w.(http.Flusher).Flush() | 
					
						
							| 
									
										
										
										
											2019-06-09 06:54:41 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-26 07:42:24 +08:00
										 |  |  | func (s *peerRESTServer) BackgroundHealStatusHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	ctx := newContext(r, w, "BackgroundHealStatus") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-17 07:32:00 +08:00
										 |  |  | 	state, ok := getLocalBackgroundHealStatus(ctx, newObjectLayerFn()) | 
					
						
							| 
									
										
										
										
											2020-08-08 10:43:06 +08:00
										 |  |  | 	if !ok { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errServerNotInitialized) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-06-26 07:42:24 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	logger.LogIf(ctx, gob.NewEncoder(w).Encode(state)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-11 01:07:49 +08:00
										 |  |  | func (s *peerRESTServer) ReloadPoolMetaHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	objAPI := newObjectLayerFn() | 
					
						
							|  |  |  | 	if objAPI == nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errServerNotInitialized) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	pools, ok := objAPI.(*erasureServerPools) | 
					
						
							|  |  |  | 	if !ok { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if err := pools.ReloadPoolMeta(r.Context()); err != nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-26 03:36:57 +08:00
										 |  |  | func (s *peerRESTServer) StopRebalanceHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	objAPI := newObjectLayerFn() | 
					
						
							|  |  |  | 	if objAPI == nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errServerNotInitialized) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	pools, ok := objAPI.(*erasureServerPools) | 
					
						
							|  |  |  | 	if !ok { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("not a multiple pools setup")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	pools.StopRebalance() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (s *peerRESTServer) LoadRebalanceMetaHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	objAPI := newObjectLayerFn() | 
					
						
							|  |  |  | 	if objAPI == nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errServerNotInitialized) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	pools, ok := objAPI.(*erasureServerPools) | 
					
						
							|  |  |  | 	if !ok { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("not a multiple pools setup")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	startRebalanceStr := r.Form.Get(peerRESTStartRebalance) | 
					
						
							|  |  |  | 	startRebalance, err := strconv.ParseBool(startRebalanceStr) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err := pools.loadRebalanceMeta(r.Context()); err != nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if startRebalance { | 
					
						
							|  |  |  | 		go pools.StartRebalance() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-20 01:30:42 +08:00
										 |  |  | func (s *peerRESTServer) LoadTransitionTierConfigHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	go func() { | 
					
						
							|  |  |  | 		err := globalTierConfigMgr.Reload(context.Background(), newObjectLayerFn()) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			logger.LogIf(context.Background(), fmt.Errorf("Failed to reload remote tier config %s", err)) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-04 02:10:48 +08:00
										 |  |  | // ConsoleLogHandler sends console logs of this node back to peer rest client
 | 
					
						
							|  |  |  | func (s *peerRESTServer) ConsoleLogHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	doneCh := make(chan struct{}) | 
					
						
							|  |  |  | 	defer close(doneCh) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-29 01:55:42 +08:00
										 |  |  | 	ch := make(chan log.Info, 2000) | 
					
						
							| 
									
										
										
										
											2022-07-06 05:45:49 +08:00
										 |  |  | 	err := globalConsoleSys.Subscribe(ch, doneCh, "", 0, madmin.LogMaskAll, nil) | 
					
						
							| 
									
										
										
										
											2022-06-06 05:29:12 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-05-07 03:39:58 +08:00
										 |  |  | 	keepAliveTicker := time.NewTicker(500 * time.Millisecond) | 
					
						
							|  |  |  | 	defer keepAliveTicker.Stop() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-04 02:10:48 +08:00
										 |  |  | 	enc := gob.NewEncoder(w) | 
					
						
							|  |  |  | 	for { | 
					
						
							|  |  |  | 		select { | 
					
						
							| 
									
										
										
										
											2022-11-08 02:38:08 +08:00
										 |  |  | 		case entry, ok := <-ch: | 
					
						
							|  |  |  | 			if !ok { | 
					
						
							|  |  |  | 				return | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2019-09-22 16:24:32 +08:00
										 |  |  | 			if err := enc.Encode(entry); err != nil { | 
					
						
							| 
									
										
										
										
											2019-09-04 02:10:48 +08:00
										 |  |  | 				return | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2022-10-29 01:55:42 +08:00
										 |  |  | 			if len(ch) == 0 { | 
					
						
							|  |  |  | 				w.(http.Flusher).Flush() | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2022-05-07 03:39:58 +08:00
										 |  |  | 		case <-keepAliveTicker.C: | 
					
						
							| 
									
										
										
										
											2022-10-29 01:55:42 +08:00
										 |  |  | 			if len(ch) == 0 { | 
					
						
							|  |  |  | 				if err := enc.Encode(&madmin.LogInfo{}); err != nil { | 
					
						
							|  |  |  | 					return | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				w.(http.Flusher).Flush() | 
					
						
							| 
									
										
										
										
											2022-05-07 03:39:58 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2019-09-04 02:10:48 +08:00
										 |  |  | 		case <-r.Context().Done(): | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | func (s *peerRESTServer) writeErrorResponse(w http.ResponseWriter, err error) { | 
					
						
							|  |  |  | 	w.WriteHeader(http.StatusForbidden) | 
					
						
							|  |  |  | 	w.Write([]byte(err.Error())) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // IsValid - To authenticate and verify the time difference.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) IsValid(w http.ResponseWriter, r *http.Request) bool { | 
					
						
							|  |  |  | 	if err := storageServerRequestValidate(r); err != nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return false | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return true | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 11:36:00 +08:00
										 |  |  | // GetBandwidth gets the bandwidth for the buckets requested.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) GetBandwidth(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 		s.writeErrorResponse(w, errors.New("invalid request")) | 
					
						
							| 
									
										
										
										
											2020-10-10 11:36:00 +08:00
										 |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-08-08 13:43:01 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	bucketsString := r.Form.Get("buckets") | 
					
						
							| 
									
										
										
										
											2020-10-10 11:36:00 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	doneCh := make(chan struct{}) | 
					
						
							|  |  |  | 	defer close(doneCh) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-13 00:04:55 +08:00
										 |  |  | 	selectBuckets := b.SelectBuckets(strings.Split(bucketsString, ",")...) | 
					
						
							|  |  |  | 	report := globalBucketMonitor.GetReport(selectBuckets) | 
					
						
							| 
									
										
										
										
											2020-10-10 11:36:00 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	enc := gob.NewEncoder(w) | 
					
						
							|  |  |  | 	if err := enc.Encode(report); err != nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Encoding report failed: "+err.Error())) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | // GetPeerMetrics gets the metrics to be federated across peers.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) GetPeerMetrics(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("invalid request")) | 
					
						
							| 
									
										
										
										
											2023-03-30 07:21:13 +08:00
										 |  |  | 		return | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	enc := gob.NewEncoder(w) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-08 17:43:13 +08:00
										 |  |  | 	for m := range ReportMetrics(r.Context(), peerMetricsGroups) { | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 		if err := enc.Encode(m); err != nil { | 
					
						
							|  |  |  | 			s.writeErrorResponse(w, errors.New("Encoding metric failed: "+err.Error())) | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-13 01:12:47 +08:00
										 |  |  | func (s *peerRESTServer) SpeedTestHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							| 
									
										
										
										
											2021-07-28 03:55:56 +08:00
										 |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("invalid request")) | 
					
						
							| 
									
										
										
										
											2021-11-24 04:02:16 +08:00
										 |  |  | 		return | 
					
						
							| 
									
										
										
										
											2021-07-28 03:55:56 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	objAPI := newObjectLayerFn() | 
					
						
							|  |  |  | 	if objAPI == nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errServerNotInitialized) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-08 13:43:01 +08:00
										 |  |  | 	sizeStr := r.Form.Get(peerRESTSize) | 
					
						
							|  |  |  | 	durationStr := r.Form.Get(peerRESTDuration) | 
					
						
							|  |  |  | 	concurrentStr := r.Form.Get(peerRESTConcurrent) | 
					
						
							| 
									
										
										
										
											2021-11-30 01:05:46 +08:00
										 |  |  | 	storageClass := r.Form.Get(peerRESTStorageClass) | 
					
						
							| 
									
										
										
										
											2022-07-13 01:12:47 +08:00
										 |  |  | 	bucketName := r.Form.Get(peerRESTBucket) | 
					
						
							| 
									
										
										
										
											2021-07-28 03:55:56 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	size, err := strconv.Atoi(sizeStr) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		size = 64 * humanize.MiByte | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	concurrent, err := strconv.Atoi(concurrentStr) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		concurrent = 32 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	duration, err := time.ParseDuration(durationStr) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		duration = time.Second * 10 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-01 05:08:23 +08:00
										 |  |  | 	done := keepHTTPResponseAlive(w) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-13 01:12:47 +08:00
										 |  |  | 	result, err := selfSpeedTest(r.Context(), speedTestOpts{ | 
					
						
							|  |  |  | 		objectSize:   size, | 
					
						
							|  |  |  | 		concurrency:  concurrent, | 
					
						
							|  |  |  | 		duration:     duration, | 
					
						
							|  |  |  | 		storageClass: storageClass, | 
					
						
							|  |  |  | 		bucketName:   bucketName, | 
					
						
							|  |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2021-07-28 03:55:56 +08:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2021-09-01 05:08:23 +08:00
										 |  |  | 		result.Error = err.Error() | 
					
						
							| 
									
										
										
										
											2021-07-28 03:55:56 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-01 05:08:23 +08:00
										 |  |  | 	done(nil) | 
					
						
							|  |  |  | 	logger.LogIf(r.Context(), gob.NewEncoder(w).Encode(result)) | 
					
						
							| 
									
										
										
										
											2021-07-28 03:55:56 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-27 06:33:10 +08:00
										 |  |  | // GetLastDayTierStatsHandler - returns per-tier stats in the last 24hrs for this server
 | 
					
						
							|  |  |  | func (s *peerRESTServer) GetLastDayTierStatsHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ctx := newContext(r, w, "GetLastDayTierStats") | 
					
						
							|  |  |  | 	if objAPI := newObjectLayerFn(); objAPI == nil || globalTransitionState == nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errServerNotInitialized) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	result := globalTransitionState.getDailyAllTierStats() | 
					
						
							|  |  |  | 	logger.LogIf(ctx, gob.NewEncoder(w).Encode(result)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-02 14:38:05 +08:00
										 |  |  | func (s *peerRESTServer) DriveSpeedTestHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	objAPI := newObjectLayerFn() | 
					
						
							|  |  |  | 	if objAPI == nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errServerNotInitialized) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	serial := r.Form.Get("serial") == "true" | 
					
						
							|  |  |  | 	blockSizeStr := r.Form.Get("blocksize") | 
					
						
							|  |  |  | 	fileSizeStr := r.Form.Get("filesize") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	blockSize, err := strconv.ParseUint(blockSizeStr, 10, 64) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		blockSize = 4 * humanize.MiByte // default value
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fileSize, err := strconv.ParseUint(fileSizeStr, 10, 64) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		fileSize = 1 * humanize.GiByte // default value
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	opts := madmin.DriveSpeedTestOpts{ | 
					
						
							|  |  |  | 		Serial:    serial, | 
					
						
							|  |  |  | 		BlockSize: blockSize, | 
					
						
							|  |  |  | 		FileSize:  fileSize, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	done := keepHTTPResponseAlive(w) | 
					
						
							|  |  |  | 	result := driveSpeedTest(r.Context(), opts) | 
					
						
							|  |  |  | 	done(nil) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	logger.LogIf(r.Context(), gob.NewEncoder(w).Encode(result)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-09 01:54:38 +08:00
										 |  |  | // DevNull - everything goes to io.Discard
 | 
					
						
							|  |  |  | func (s *peerRESTServer) DevNull(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	globalNetPerfRX.Connect() | 
					
						
							|  |  |  | 	defer globalNetPerfRX.Disconnect() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	connectTime := time.Now() | 
					
						
							|  |  |  | 	ctx := newContext(r, w, "DevNull") | 
					
						
							|  |  |  | 	for { | 
					
						
							|  |  |  | 		n, err := io.CopyN(io.Discard, r.Body, 128*humanize.KiByte) | 
					
						
							|  |  |  | 		atomic.AddUint64(&globalNetPerfRX.RX, uint64(n)) | 
					
						
							|  |  |  | 		if err != nil && err != io.EOF { | 
					
						
							|  |  |  | 			// If there is a disconnection before globalNetPerfMinDuration (we give a margin of error of 1 sec)
 | 
					
						
							|  |  |  | 			// would mean the network is not stable. Logging here will help in debugging network issues.
 | 
					
						
							|  |  |  | 			if time.Since(connectTime) < (globalNetPerfMinDuration - time.Second) { | 
					
						
							|  |  |  | 				logger.LogIf(ctx, err) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			break | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-16 05:51:42 +08:00
										 |  |  | // NetSpeedTestHandlers - perform network speedtest
 | 
					
						
							|  |  |  | func (s *peerRESTServer) NetSpeedTestHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							| 
									
										
										
										
											2022-03-09 01:54:38 +08:00
										 |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	durationStr := r.Form.Get(peerRESTDuration) | 
					
						
							|  |  |  | 	duration, err := time.ParseDuration(durationStr) | 
					
						
							|  |  |  | 	if err != nil || duration.Seconds() == 0 { | 
					
						
							|  |  |  | 		duration = time.Second * 10 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	result := netperf(r.Context(), duration.Round(time.Second)) | 
					
						
							|  |  |  | 	logger.LogIf(r.Context(), gob.NewEncoder(w).Encode(result)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | // registerPeerRESTHandlers - register peer rest router.
 | 
					
						
							|  |  |  | func registerPeerRESTHandlers(router *mux.Router) { | 
					
						
							|  |  |  | 	server := &peerRESTServer{} | 
					
						
							| 
									
										
										
										
											2019-11-05 01:30:59 +08:00
										 |  |  | 	subrouter := router.PathPrefix(peerRESTPrefix).Subrouter() | 
					
						
							| 
									
										
										
										
											2020-06-18 05:49:26 +08:00
										 |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodHealth).HandlerFunc(httpTraceHdrs(server.HealthHandler)) | 
					
						
							| 
									
										
										
										
											2019-11-05 01:30:59 +08:00
										 |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodGetLocks).HandlerFunc(httpTraceHdrs(server.GetLocksHandler)) | 
					
						
							|  |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodServerInfo).HandlerFunc(httpTraceHdrs(server.ServerInfoHandler)) | 
					
						
							| 
									
										
										
										
											2022-12-02 06:31:35 +08:00
										 |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodLocalStorageInfo).HandlerFunc(httpTraceHdrs(server.LocalStorageInfoHandler)) | 
					
						
							| 
									
										
										
										
											2021-06-01 23:55:49 +08:00
										 |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodProcInfo).HandlerFunc(httpTraceHdrs(server.GetProcInfoHandler)) | 
					
						
							|  |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodMemInfo).HandlerFunc(httpTraceHdrs(server.GetMemInfoHandler)) | 
					
						
							| 
									
										
										
										
											2022-10-03 17:10:15 +08:00
										 |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodMetrics).HandlerFunc(httpTraceHdrs(server.GetMetricsHandler)).Queries(restQueries(peerRESTMetricsTypes)...) | 
					
						
							| 
									
										
										
										
											2021-07-30 14:05:34 +08:00
										 |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodSysErrors).HandlerFunc(httpTraceHdrs(server.GetSysErrorsHandler)) | 
					
						
							| 
									
										
										
										
											2021-08-13 09:58:40 +08:00
										 |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodSysServices).HandlerFunc(httpTraceHdrs(server.GetSysServicesHandler)) | 
					
						
							| 
									
										
										
										
											2021-08-25 08:09:37 +08:00
										 |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodSysConfig).HandlerFunc(httpTraceHdrs(server.GetSysConfigHandler)) | 
					
						
							| 
									
										
										
										
											2021-06-01 23:55:49 +08:00
										 |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodOsInfo).HandlerFunc(httpTraceHdrs(server.GetOSInfoHandler)) | 
					
						
							|  |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodDiskHwInfo).HandlerFunc(httpTraceHdrs(server.GetPartitionsHandler)) | 
					
						
							|  |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodCPUInfo).HandlerFunc(httpTraceHdrs(server.GetCPUsHandler)) | 
					
						
							| 
									
										
										
										
											2022-05-24 00:15:30 +08:00
										 |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodGetAllBucketStats).HandlerFunc(httpTraceHdrs(server.GetAllBucketStatsHandler)) | 
					
						
							| 
									
										
										
										
											2020-05-20 04:53:54 +08:00
										 |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodDeleteBucketMetadata).HandlerFunc(httpTraceHdrs(server.DeleteBucketMetadataHandler)).Queries(restQueries(peerRESTBucket)...) | 
					
						
							|  |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodLoadBucketMetadata).HandlerFunc(httpTraceHdrs(server.LoadBucketMetadataHandler)).Queries(restQueries(peerRESTBucket)...) | 
					
						
							| 
									
										
										
										
											2021-04-05 06:34:33 +08:00
										 |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodGetBucketStats).HandlerFunc(httpTraceHdrs(server.GetBucketStatsHandler)).Queries(restQueries(peerRESTBucket)...) | 
					
						
							| 
									
										
										
										
											2019-11-05 01:30:59 +08:00
										 |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodSignalService).HandlerFunc(httpTraceHdrs(server.SignalServiceHandler)).Queries(restQueries(peerRESTSignal)...) | 
					
						
							| 
									
										
										
										
											2022-07-26 08:49:47 +08:00
										 |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodDownloadBinary).HandlerFunc(httpTraceHdrs(server.DownloadBinaryHandler)) | 
					
						
							|  |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodCommitBinary).HandlerFunc(httpTraceHdrs(server.CommitBinaryHandler)) | 
					
						
							| 
									
										
										
										
											2019-11-05 01:30:59 +08:00
										 |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodDeletePolicy).HandlerFunc(httpTraceAll(server.DeletePolicyHandler)).Queries(restQueries(peerRESTPolicy)...) | 
					
						
							|  |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodLoadPolicy).HandlerFunc(httpTraceAll(server.LoadPolicyHandler)).Queries(restQueries(peerRESTPolicy)...) | 
					
						
							| 
									
										
										
										
											2022-08-25 03:34:52 +08:00
										 |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodLoadPolicyMapping).HandlerFunc(httpTraceAll(server.LoadPolicyMappingHandler)) | 
					
						
							| 
									
										
										
										
											2020-04-21 23:35:19 +08:00
										 |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodDeleteUser).HandlerFunc(httpTraceAll(server.DeleteUserHandler)).Queries(restQueries(peerRESTUser)...) | 
					
						
							| 
									
										
										
										
											2020-04-25 03:10:09 +08:00
										 |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodDeleteServiceAccount).HandlerFunc(httpTraceAll(server.DeleteServiceAccountHandler)).Queries(restQueries(peerRESTUser)...) | 
					
						
							| 
									
										
										
										
											2019-11-05 01:30:59 +08:00
										 |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodLoadUser).HandlerFunc(httpTraceAll(server.LoadUserHandler)).Queries(restQueries(peerRESTUser, peerRESTUserTemp)...) | 
					
						
							| 
									
										
										
										
											2020-04-25 03:10:09 +08:00
										 |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodLoadServiceAccount).HandlerFunc(httpTraceAll(server.LoadServiceAccountHandler)).Queries(restQueries(peerRESTUser)...) | 
					
						
							| 
									
										
										
										
											2019-11-05 01:30:59 +08:00
										 |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodLoadGroup).HandlerFunc(httpTraceAll(server.LoadGroupHandler)).Queries(restQueries(peerRESTGroup)...) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodStartProfiling).HandlerFunc(httpTraceAll(server.StartProfilingHandler)).Queries(restQueries(peerRESTProfiler)...) | 
					
						
							| 
									
										
										
										
											2020-01-11 09:19:58 +08:00
										 |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodDownloadProfilingData).HandlerFunc(httpTraceHdrs(server.DownloadProfilingDataHandler)) | 
					
						
							| 
									
										
										
										
											2019-11-05 01:30:59 +08:00
										 |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodTrace).HandlerFunc(server.TraceHandler) | 
					
						
							| 
									
										
										
										
											2019-12-17 12:30:57 +08:00
										 |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodListen).HandlerFunc(httpTraceHdrs(server.ListenHandler)) | 
					
						
							| 
									
										
										
										
											2019-11-05 01:30:59 +08:00
										 |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodBackgroundHealStatus).HandlerFunc(server.BackgroundHealStatusHandler) | 
					
						
							|  |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodLog).HandlerFunc(server.ConsoleLogHandler) | 
					
						
							| 
									
										
										
										
											2020-05-24 08:38:39 +08:00
										 |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodGetLocalDiskIDs).HandlerFunc(httpTraceHdrs(server.GetLocalDiskIDs)) | 
					
						
							| 
									
										
										
										
											2020-10-10 11:36:00 +08:00
										 |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodGetBandwidth).HandlerFunc(httpTraceHdrs(server.GetBandwidth)) | 
					
						
							| 
									
										
										
										
											2020-10-29 00:18:35 +08:00
										 |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodGetMetacacheListing).HandlerFunc(httpTraceHdrs(server.GetMetacacheListingHandler)) | 
					
						
							|  |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodUpdateMetacacheListing).HandlerFunc(httpTraceHdrs(server.UpdateMetacacheListingHandler)) | 
					
						
							| 
									
										
										
										
											2021-01-19 12:35:38 +08:00
										 |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodGetPeerMetrics).HandlerFunc(httpTraceHdrs(server.GetPeerMetrics)) | 
					
						
							| 
									
										
										
										
											2021-04-20 01:30:42 +08:00
										 |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodLoadTransitionTierConfig).HandlerFunc(httpTraceHdrs(server.LoadTransitionTierConfigHandler)) | 
					
						
							| 
									
										
										
										
											2022-07-13 01:12:47 +08:00
										 |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodSpeedTest).HandlerFunc(httpTraceHdrs(server.SpeedTestHandler)) | 
					
						
							| 
									
										
										
										
											2022-02-02 14:38:05 +08:00
										 |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodDriveSpeedTest).HandlerFunc(httpTraceHdrs(server.DriveSpeedTestHandler)) | 
					
						
							| 
									
										
										
										
											2022-06-16 05:51:42 +08:00
										 |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodNetperf).HandlerFunc(httpTraceHdrs(server.NetSpeedTestHandler)) | 
					
						
							| 
									
										
										
										
											2022-03-09 01:54:38 +08:00
										 |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodDevNull).HandlerFunc(httpTraceHdrs(server.DevNull)) | 
					
						
							| 
									
										
										
										
											2021-10-07 07:36:31 +08:00
										 |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodReloadSiteReplicationConfig).HandlerFunc(httpTraceHdrs(server.ReloadSiteReplicationConfigHandler)) | 
					
						
							| 
									
										
										
										
											2022-01-11 01:07:49 +08:00
										 |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodReloadPoolMeta).HandlerFunc(httpTraceHdrs(server.ReloadPoolMetaHandler)) | 
					
						
							| 
									
										
										
										
											2022-10-26 03:36:57 +08:00
										 |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodLoadRebalanceMeta).HandlerFunc(httpTraceHdrs(server.LoadRebalanceMetaHandler)) | 
					
						
							|  |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodStopRebalance).HandlerFunc(httpTraceHdrs(server.StopRebalanceHandler)) | 
					
						
							| 
									
										
										
										
											2022-01-27 06:33:10 +08:00
										 |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodGetLastDayTierStats).HandlerFunc(httpTraceHdrs(server.GetLastDayTierStatsHandler)) | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | } |