diff --git a/cmd/admin-handlers-config-kv.go b/cmd/admin-handlers-config-kv.go index 0bf88a188..7477ae4cc 100644 --- a/cmd/admin-handlers-config-kv.go +++ b/cmd/admin-handlers-config-kv.go @@ -57,7 +57,7 @@ func validateAdminReqConfigKV(ctx context.Context, w http.ResponseWriter, r *htt return objectAPI } -// DelConfigKVHandler - DELETE /minio/admin/v2/del-config-kv +// DelConfigKVHandler - DELETE /minio/admin/v3/del-config-kv func (a adminAPIHandlers) DelConfigKVHandler(w http.ResponseWriter, r *http.Request) { ctx := newContext(r, w, "DelConfigKVHandler") @@ -103,7 +103,7 @@ func (a adminAPIHandlers) DelConfigKVHandler(w http.ResponseWriter, r *http.Requ } } -// SetConfigKVHandler - PUT /minio/admin/v2/set-config-kv +// SetConfigKVHandler - PUT /minio/admin/v3/set-config-kv func (a adminAPIHandlers) SetConfigKVHandler(w http.ResponseWriter, r *http.Request) { ctx := newContext(r, w, "SetConfigKVHandler") @@ -168,7 +168,7 @@ func (a adminAPIHandlers) SetConfigKVHandler(w http.ResponseWriter, r *http.Requ writeSuccessResponseHeadersOnly(w) } -// GetConfigKVHandler - GET /minio/admin/v2/get-config-kv?key={key} +// GetConfigKVHandler - GET /minio/admin/v3/get-config-kv?key={key} func (a adminAPIHandlers) GetConfigKVHandler(w http.ResponseWriter, r *http.Request) { ctx := newContext(r, w, "GetConfigKVHandler") @@ -323,7 +323,7 @@ func (a adminAPIHandlers) ListConfigHistoryKVHandler(w http.ResponseWriter, r *h writeSuccessResponseJSON(w, econfigData) } -// HelpConfigKVHandler - GET /minio/admin/v2/help-config-kv?subSys={subSys}&key={key} +// HelpConfigKVHandler - GET /minio/admin/v3/help-config-kv?subSys={subSys}&key={key} func (a adminAPIHandlers) HelpConfigKVHandler(w http.ResponseWriter, r *http.Request) { ctx := newContext(r, w, "HelpConfigKVHandler") @@ -349,7 +349,7 @@ func (a adminAPIHandlers) HelpConfigKVHandler(w http.ResponseWriter, r *http.Req w.(http.Flusher).Flush() } -// SetConfigHandler - PUT /minio/admin/v2/config +// SetConfigHandler - PUT /minio/admin/v3/config func (a adminAPIHandlers) SetConfigHandler(w http.ResponseWriter, r *http.Request) { ctx := newContext(r, w, "SetConfigHandler") @@ -409,7 +409,7 @@ func (a adminAPIHandlers) SetConfigHandler(w http.ResponseWriter, r *http.Reques writeSuccessResponseHeadersOnly(w) } -// GetConfigHandler - GET /minio/admin/v2/config +// GetConfigHandler - GET /minio/admin/v3/config // Get config.json of this minio setup. func (a adminAPIHandlers) GetConfigHandler(w http.ResponseWriter, r *http.Request) { ctx := newContext(r, w, "GetConfigHandler") diff --git a/cmd/admin-handlers-users.go b/cmd/admin-handlers-users.go index 6384b9146..9867d4d49 100644 --- a/cmd/admin-handlers-users.go +++ b/cmd/admin-handlers-users.go @@ -1,5 +1,5 @@ /* - * MinIO Cloud Storage, (C) 2019 MinIO, Inc. + * MinIO Cloud Storage, (C) 2019-2020 MinIO, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -51,7 +51,7 @@ func validateAdminUsersReq(ctx context.Context, w http.ResponseWriter, r *http.R return objectAPI, cred } -// RemoveUser - DELETE /minio/admin/v2/remove-user?accessKey= +// RemoveUser - DELETE /minio/admin/v3/remove-user?accessKey= func (a adminAPIHandlers) RemoveUser(w http.ResponseWriter, r *http.Request) { ctx := newContext(r, w, "RemoveUser") @@ -93,7 +93,7 @@ func (a adminAPIHandlers) RemoveUser(w http.ResponseWriter, r *http.Request) { } } -// ListUsers - GET /minio/admin/v2/list-users +// ListUsers - GET /minio/admin/v3/list-users func (a adminAPIHandlers) ListUsers(w http.ResponseWriter, r *http.Request) { ctx := newContext(r, w, "ListUsers") @@ -125,7 +125,7 @@ func (a adminAPIHandlers) ListUsers(w http.ResponseWriter, r *http.Request) { writeSuccessResponseJSON(w, econfigData) } -// GetUserInfo - GET /minio/admin/v2/user-info +// GetUserInfo - GET /minio/admin/v3/user-info func (a adminAPIHandlers) GetUserInfo(w http.ResponseWriter, r *http.Request) { ctx := newContext(r, w, "GetUserInfo") @@ -152,7 +152,7 @@ func (a adminAPIHandlers) GetUserInfo(w http.ResponseWriter, r *http.Request) { writeSuccessResponseJSON(w, data) } -// UpdateGroupMembers - PUT /minio/admin/v2/update-group-members +// UpdateGroupMembers - PUT /minio/admin/v3/update-group-members func (a adminAPIHandlers) UpdateGroupMembers(w http.ResponseWriter, r *http.Request) { ctx := newContext(r, w, "UpdateGroupMembers") @@ -195,7 +195,7 @@ func (a adminAPIHandlers) UpdateGroupMembers(w http.ResponseWriter, r *http.Requ } } -// GetGroup - /minio/admin/v2/group?group=mygroup1 +// GetGroup - /minio/admin/v3/group?group=mygroup1 func (a adminAPIHandlers) GetGroup(w http.ResponseWriter, r *http.Request) { ctx := newContext(r, w, "GetGroup") @@ -222,7 +222,7 @@ func (a adminAPIHandlers) GetGroup(w http.ResponseWriter, r *http.Request) { writeSuccessResponseJSON(w, body) } -// ListGroups - GET /minio/admin/v2/groups +// ListGroups - GET /minio/admin/v3/groups func (a adminAPIHandlers) ListGroups(w http.ResponseWriter, r *http.Request) { ctx := newContext(r, w, "ListGroups") @@ -246,7 +246,7 @@ func (a adminAPIHandlers) ListGroups(w http.ResponseWriter, r *http.Request) { writeSuccessResponseJSON(w, body) } -// SetGroupStatus - PUT /minio/admin/v2/set-group-status?group=mygroup1&status=enabled +// SetGroupStatus - PUT /minio/admin/v3/set-group-status?group=mygroup1&status=enabled func (a adminAPIHandlers) SetGroupStatus(w http.ResponseWriter, r *http.Request) { ctx := newContext(r, w, "SetGroupStatus") @@ -281,7 +281,7 @@ func (a adminAPIHandlers) SetGroupStatus(w http.ResponseWriter, r *http.Request) } } -// SetUserStatus - PUT /minio/admin/v2/set-user-status?accessKey=&status=[enabled|disabled] +// SetUserStatus - PUT /minio/admin/v3/set-user-status?accessKey=&status=[enabled|disabled] func (a adminAPIHandlers) SetUserStatus(w http.ResponseWriter, r *http.Request) { ctx := newContext(r, w, "SetUserStatus") @@ -320,7 +320,7 @@ func (a adminAPIHandlers) SetUserStatus(w http.ResponseWriter, r *http.Request) } } -// AddUser - PUT /minio/admin/v2/add-user?accessKey= +// AddUser - PUT /minio/admin/v3/add-user?accessKey= func (a adminAPIHandlers) AddUser(w http.ResponseWriter, r *http.Request) { ctx := newContext(r, w, "AddUser") @@ -379,7 +379,7 @@ func (a adminAPIHandlers) AddUser(w http.ResponseWriter, r *http.Request) { } } -// AddServiceAccount - PUT /minio/admin/v2/add-service-account?parentUser= +// AddServiceAccount - PUT /minio/admin/v3/add-service-account?parentUser= func (a adminAPIHandlers) AddServiceAccount(w http.ResponseWriter, r *http.Request) { ctx := newContext(r, w, "AddServiceAccount") @@ -459,7 +459,7 @@ func (a adminAPIHandlers) AddServiceAccount(w http.ResponseWriter, r *http.Reque writeSuccessResponseJSON(w, econfigData) } -// GetServiceAccount - GET /minio/admin/v2/get-service-account?accessKey= +// GetServiceAccount - GET /minio/admin/v3/get-service-account?accessKey= func (a adminAPIHandlers) GetServiceAccount(w http.ResponseWriter, r *http.Request) { ctx := newContext(r, w, "GetServiceAccount") @@ -494,7 +494,32 @@ func (a adminAPIHandlers) GetServiceAccount(w http.ResponseWriter, r *http.Reque writeSuccessResponseJSON(w, econfigData) } -// InfoCannedPolicy - GET /minio/admin/v2/info-canned-policy?name={policyName} +// InfoCannedPolicyV2 - GET /minio/admin/v2/info-canned-policy?name={policyName} +func (a adminAPIHandlers) InfoCannedPolicyV2(w http.ResponseWriter, r *http.Request) { + ctx := newContext(r, w, "InfoCannedPolicyV2") + + objectAPI, _ := validateAdminUsersReq(ctx, w, r, iampolicy.GetPolicyAdminAction) + if objectAPI == nil { + return + } + + policy, err := globalIAMSys.InfoPolicy(mux.Vars(r)["name"]) + if err != nil { + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) + return + } + + data, err := json.Marshal(policy) + if err != nil { + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) + return + } + + w.Write(data) + w.(http.Flusher).Flush() +} + +// InfoCannedPolicy - GET /minio/admin/v3/info-canned-policy?name={policyName} func (a adminAPIHandlers) InfoCannedPolicy(w http.ResponseWriter, r *http.Request) { ctx := newContext(r, w, "InfoCannedPolicy") @@ -503,17 +528,49 @@ func (a adminAPIHandlers) InfoCannedPolicy(w http.ResponseWriter, r *http.Reques return } - data, err := globalIAMSys.InfoPolicy(mux.Vars(r)["name"]) + policy, err := globalIAMSys.InfoPolicy(mux.Vars(r)["name"]) if err != nil { writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) return } - w.Write(data) + json.NewEncoder(w).Encode(policy) + w.(http.Flusher).Flush() +} + +// ListCannedPoliciesV2 - GET /minio/admin/v2/list-canned-policies +func (a adminAPIHandlers) ListCannedPoliciesV2(w http.ResponseWriter, r *http.Request) { + ctx := newContext(r, w, "ListCannedPoliciesV2") + + objectAPI, _ := validateAdminUsersReq(ctx, w, r, iampolicy.ListUserPoliciesAdminAction) + if objectAPI == nil { + return + } + + policies, err := globalIAMSys.ListPolicies() + if err != nil { + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) + return + } + + policyMap := make(map[string][]byte, len(policies)) + for k, p := range policies { + var err error + policyMap[k], err = json.Marshal(p) + if err != nil { + logger.LogIf(ctx, err) + continue + } + } + if err = json.NewEncoder(w).Encode(policyMap); err != nil { + writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) + return + } + w.(http.Flusher).Flush() } -// ListCannedPolicies - GET /minio/admin/v2/list-canned-policies +// ListCannedPolicies - GET /minio/admin/v3/list-canned-policies func (a adminAPIHandlers) ListCannedPolicies(w http.ResponseWriter, r *http.Request) { ctx := newContext(r, w, "ListCannedPolicies") @@ -536,7 +593,7 @@ func (a adminAPIHandlers) ListCannedPolicies(w http.ResponseWriter, r *http.Requ w.(http.Flusher).Flush() } -// RemoveCannedPolicy - DELETE /minio/admin/v2/remove-canned-policy?name= +// RemoveCannedPolicy - DELETE /minio/admin/v3/remove-canned-policy?name= func (a adminAPIHandlers) RemoveCannedPolicy(w http.ResponseWriter, r *http.Request) { ctx := newContext(r, w, "RemoveCannedPolicy") @@ -568,7 +625,7 @@ func (a adminAPIHandlers) RemoveCannedPolicy(w http.ResponseWriter, r *http.Requ } } -// AddCannedPolicy - PUT /minio/admin/v2/add-canned-policy?name= +// AddCannedPolicy - PUT /minio/admin/v3/add-canned-policy?name= func (a adminAPIHandlers) AddCannedPolicy(w http.ResponseWriter, r *http.Request) { ctx := newContext(r, w, "AddCannedPolicy") @@ -624,7 +681,7 @@ func (a adminAPIHandlers) AddCannedPolicy(w http.ResponseWriter, r *http.Request } } -// SetPolicyForUserOrGroup - PUT /minio/admin/v2/set-policy?policy=xxx&user-or-group=?[&is-group] +// SetPolicyForUserOrGroup - PUT /minio/admin/v3/set-policy?policy=xxx&user-or-group=?[&is-group] func (a adminAPIHandlers) SetPolicyForUserOrGroup(w http.ResponseWriter, r *http.Request) { ctx := newContext(r, w, "SetPolicyForUserOrGroup") diff --git a/cmd/admin-handlers.go b/cmd/admin-handlers.go index 6948ee425..43f058979 100644 --- a/cmd/admin-handlers.go +++ b/cmd/admin-handlers.go @@ -99,7 +99,7 @@ func updateServer(updateURL, sha256Hex string, latestReleaseTime time.Time) (us return us, nil } -// ServerUpdateHandler - POST /minio/admin/v2/update?updateURL={updateURL} +// ServerUpdateHandler - POST /minio/admin/v3/update?updateURL={updateURL} // ---------- // updates all minio servers and restarts them gracefully. func (a adminAPIHandlers) ServerUpdateHandler(w http.ResponseWriter, r *http.Request) { @@ -178,7 +178,7 @@ func (a adminAPIHandlers) ServerUpdateHandler(w http.ResponseWriter, r *http.Req } } -// ServiceActionHandler - POST /minio/admin/v2/service?action={action} +// ServiceActionHandler - POST /minio/admin/v3/service?action={action} // ---------- // restarts/stops minio server gracefully. In a distributed setup, func (a adminAPIHandlers) ServiceActionHandler(w http.ResponseWriter, r *http.Request) { @@ -267,7 +267,7 @@ type ServerInfo struct { Data *ServerInfoData `json:"data"` } -// StorageInfoHandler - GET /minio/admin/v2/storageinfo +// StorageInfoHandler - GET /minio/admin/v3/storageinfo // ---------- // Get server information func (a adminAPIHandlers) StorageInfoHandler(w http.ResponseWriter, r *http.Request) { @@ -292,7 +292,7 @@ func (a adminAPIHandlers) StorageInfoHandler(w http.ResponseWriter, r *http.Requ } -// DataUsageInfoHandler - GET /minio/admin/v2/datausage +// DataUsageInfoHandler - GET /minio/admin/v3/datausage // ---------- // Get server/cluster data usage info func (a adminAPIHandlers) DataUsageInfoHandler(w http.ResponseWriter, r *http.Request) { @@ -405,7 +405,7 @@ type ServerNetReadPerfInfo struct { Error string `json:"error,omitempty"` } -// PerfInfoHandler - GET /minio/admin/v2/performance?perfType={perfType} +// PerfInfoHandler - GET /minio/admin/v3/performance?perfType={perfType} // ---------- // Get all performance information based on input type // Supported types = drive @@ -622,7 +622,7 @@ type StartProfilingResult struct { Error string `json:"error"` } -// StartProfilingHandler - POST /minio/admin/v2/profiling/start?profilerType={profilerType} +// StartProfilingHandler - POST /minio/admin/v3/profiling/start?profilerType={profilerType} // ---------- // Enable server profiling func (a adminAPIHandlers) StartProfilingHandler(w http.ResponseWriter, r *http.Request) { @@ -718,7 +718,7 @@ func (f dummyFileInfo) ModTime() time.Time { return f.modTime } func (f dummyFileInfo) IsDir() bool { return f.isDir } func (f dummyFileInfo) Sys() interface{} { return f.sys } -// DownloadProfilingHandler - POST /minio/admin/v2/profiling/download +// DownloadProfilingHandler - POST /minio/admin/v3/profiling/download // ---------- // Download profiling information of all nodes in a zip format func (a adminAPIHandlers) DownloadProfilingHandler(w http.ResponseWriter, r *http.Request) { @@ -800,7 +800,7 @@ func extractHealInitParams(vars map[string]string, qParms url.Values, r io.Reade return } -// HealHandler - POST /minio/admin/v2/heal/ +// HealHandler - POST /minio/admin/v3/heal/ // ----------- // Start heal processing and return heal status items. // @@ -1116,7 +1116,7 @@ func mustTrace(entry interface{}, trcAll, errOnly bool) bool { return trace } -// TraceHandler - POST /minio/admin/v2/trace +// TraceHandler - POST /minio/admin/v3/trace // ---------- // The handler sends http trace to the connected HTTP client. func (a adminAPIHandlers) TraceHandler(w http.ResponseWriter, r *http.Request) { @@ -1246,7 +1246,7 @@ func (a adminAPIHandlers) ConsoleLogHandler(w http.ResponseWriter, r *http.Reque } } -// KMSKeyStatusHandler - GET /minio/admin/v2/kms/key/status?key-id= +// KMSKeyStatusHandler - GET /minio/admin/v3/kms/key/status?key-id= func (a adminAPIHandlers) KMSKeyStatusHandler(w http.ResponseWriter, r *http.Request) { ctx := newContext(r, w, "KMSKeyStatusHandler") @@ -1315,7 +1315,7 @@ func (a adminAPIHandlers) KMSKeyStatusHandler(w http.ResponseWriter, r *http.Req writeSuccessResponseJSON(w, resp) } -// ServerHardwareInfoHandler - GET /minio/admin/v2/hardwareinfo?Type={hwType} +// ServerHardwareInfoHandler - GET /minio/admin/v3/hardwareinfo?Type={hwType} // ---------- // Get all hardware information based on input type // Supported types = cpu @@ -1372,7 +1372,7 @@ func (a adminAPIHandlers) ServerHardwareInfoHandler(w http.ResponseWriter, r *ht } } -// OBDInfoHandler - GET /minio/admin/v2/obdinfo +// OBDInfoHandler - GET /minio/admin/v3/obdinfo // ---------- // Get server on-board diagnostics func (a adminAPIHandlers) OBDInfoHandler(w http.ResponseWriter, r *http.Request) { @@ -1501,7 +1501,7 @@ func (a adminAPIHandlers) OBDInfoHandler(w http.ResponseWriter, r *http.Request) finish() } -// ServerInfoHandler - GET /minio/admin/v2/info +// ServerInfoHandler - GET /minio/admin/v3/info // ---------- // Get server information func (a adminAPIHandlers) ServerInfoHandler(w http.ResponseWriter, r *http.Request) { diff --git a/cmd/admin-router.go b/cmd/admin-router.go index 47ead4b30..f26290d8e 100644 --- a/cmd/admin-router.go +++ b/cmd/admin-router.go @@ -24,9 +24,11 @@ import ( ) const ( - adminPathPrefix = minioReservedBucketPath + "/admin" - adminAPIVersion = madmin.AdminAPIVersion - adminAPIVersionPrefix = SlashSeparator + madmin.AdminAPIVersion + adminPathPrefix = minioReservedBucketPath + "/admin" + adminAPIVersionV2 = madmin.AdminAPIVersionV2 + adminAPIVersion = madmin.AdminAPIVersion + adminAPIVersionPrefix = SlashSeparator + adminAPIVersion + adminAPIVersionV2Prefix = SlashSeparator + adminAPIVersionV2 ) // adminAPIHandlers provides HTTP handlers for MinIO admin API. @@ -41,135 +43,150 @@ func registerAdminRouter(router *mux.Router, enableConfigOps, enableIAMOps bool) /// Service operations - // Restart and stop MinIO service. - adminRouter.Methods(http.MethodPost).Path(adminAPIVersionPrefix+"/service").HandlerFunc(httpTraceAll(adminAPI.ServiceActionHandler)).Queries("action", "{action:.*}") - // Update MinIO servers. - adminRouter.Methods(http.MethodPost).Path(adminAPIVersionPrefix+"/update").HandlerFunc(httpTraceAll(adminAPI.ServerUpdateHandler)).Queries("updateURL", "{updateURL:.*}") + adminVersions := []string{ + adminAPIVersionPrefix, + adminAPIVersionV2Prefix, + } - // Info operations - adminRouter.Methods(http.MethodGet).Path(adminAPIVersionPrefix + "/info").HandlerFunc(httpTraceAll(adminAPI.ServerInfoHandler)) - // Harware Info operations - adminRouter.Methods(http.MethodGet).Path(adminAPIVersionPrefix+"/hardware").HandlerFunc(httpTraceAll(adminAPI.ServerHardwareInfoHandler)).Queries("hwType", "{hwType:.*}") + for _, adminVersion := range adminVersions { + // Restart and stop MinIO service. + adminRouter.Methods(http.MethodPost).Path(adminVersion+"/service").HandlerFunc(httpTraceAll(adminAPI.ServiceActionHandler)).Queries("action", "{action:.*}") + // Update MinIO servers. + adminRouter.Methods(http.MethodPost).Path(adminVersion+"/update").HandlerFunc(httpTraceAll(adminAPI.ServerUpdateHandler)).Queries("updateURL", "{updateURL:.*}") - // StorageInfo operations - adminRouter.Methods(http.MethodGet).Path(adminAPIVersionPrefix + "/storageinfo").HandlerFunc(httpTraceAll(adminAPI.StorageInfoHandler)) - // DataUsageInfo operations - adminRouter.Methods(http.MethodGet).Path(adminAPIVersionPrefix + "/datausageinfo").HandlerFunc(httpTraceAll(adminAPI.DataUsageInfoHandler)) + // Info operations + adminRouter.Methods(http.MethodGet).Path(adminVersion + "/info").HandlerFunc(httpTraceAll(adminAPI.ServerInfoHandler)) + // Harware Info operations + adminRouter.Methods(http.MethodGet).Path(adminVersion+"/hardware").HandlerFunc(httpTraceAll(adminAPI.ServerHardwareInfoHandler)).Queries("hwType", "{hwType:.*}") - adminRouter.Methods(http.MethodGet).Path(adminAPIVersionPrefix + "/accountingusageinfo").HandlerFunc(httpTraceAll(adminAPI.AccountingUsageInfoHandler)) + // StorageInfo operations + adminRouter.Methods(http.MethodGet).Path(adminVersion + "/storageinfo").HandlerFunc(httpTraceAll(adminAPI.StorageInfoHandler)) + // DataUsageInfo operations + adminRouter.Methods(http.MethodGet).Path(adminVersion + "/datausageinfo").HandlerFunc(httpTraceAll(adminAPI.DataUsageInfoHandler)) - if globalIsDistXL || globalIsXL { - /// Heal operations + adminRouter.Methods(http.MethodGet).Path(adminVersion + "/accountingusageinfo").HandlerFunc(httpTraceAll(adminAPI.AccountingUsageInfoHandler)) - // Heal processing endpoint. - adminRouter.Methods(http.MethodPost).Path(adminAPIVersionPrefix + "/heal/").HandlerFunc(httpTraceAll(adminAPI.HealHandler)) - adminRouter.Methods(http.MethodPost).Path(adminAPIVersionPrefix + "/heal/{bucket}").HandlerFunc(httpTraceAll(adminAPI.HealHandler)) - adminRouter.Methods(http.MethodPost).Path(adminAPIVersionPrefix + "/heal/{bucket}/{prefix:.*}").HandlerFunc(httpTraceAll(adminAPI.HealHandler)) + if globalIsDistXL || globalIsXL { + /// Heal operations - adminRouter.Methods(http.MethodPost).Path(adminAPIVersionPrefix + "/background-heal/status").HandlerFunc(httpTraceAll(adminAPI.BackgroundHealStatusHandler)) + // Heal processing endpoint. + adminRouter.Methods(http.MethodPost).Path(adminVersion + "/heal/").HandlerFunc(httpTraceAll(adminAPI.HealHandler)) + adminRouter.Methods(http.MethodPost).Path(adminVersion + "/heal/{bucket}").HandlerFunc(httpTraceAll(adminAPI.HealHandler)) + adminRouter.Methods(http.MethodPost).Path(adminVersion + "/heal/{bucket}/{prefix:.*}").HandlerFunc(httpTraceAll(adminAPI.HealHandler)) - /// Health operations + adminRouter.Methods(http.MethodPost).Path(adminVersion + "/background-heal/status").HandlerFunc(httpTraceAll(adminAPI.BackgroundHealStatusHandler)) - } - // Performance command - return performance details based on input type - adminRouter.Methods(http.MethodGet).Path(adminAPIVersionPrefix+"/performance").HandlerFunc(httpTraceAll(adminAPI.PerfInfoHandler)).Queries("perfType", "{perfType:.*}") - - // Profiling operations - adminRouter.Methods(http.MethodPost).Path(adminAPIVersionPrefix+"/profiling/start").HandlerFunc(httpTraceAll(adminAPI.StartProfilingHandler)). - Queries("profilerType", "{profilerType:.*}") - adminRouter.Methods(http.MethodGet).Path(adminAPIVersionPrefix + "/profiling/download").HandlerFunc(httpTraceAll(adminAPI.DownloadProfilingHandler)) - - // Config KV operations. - if enableConfigOps { - adminRouter.Methods(http.MethodGet).Path(adminAPIVersionPrefix+"/get-config-kv").HandlerFunc(httpTraceHdrs(adminAPI.GetConfigKVHandler)).Queries("key", "{key:.*}") - adminRouter.Methods(http.MethodPut).Path(adminAPIVersionPrefix + "/set-config-kv").HandlerFunc(httpTraceHdrs(adminAPI.SetConfigKVHandler)) - adminRouter.Methods(http.MethodDelete).Path(adminAPIVersionPrefix + "/del-config-kv").HandlerFunc(httpTraceHdrs(adminAPI.DelConfigKVHandler)) - adminRouter.Methods(http.MethodGet).Path(adminAPIVersionPrefix+"/help-config-kv").HandlerFunc(httpTraceAll(adminAPI.HelpConfigKVHandler)).Queries("subSys", "{subSys:.*}", "key", "{key:.*}") - adminRouter.Methods(http.MethodGet).Path(adminAPIVersionPrefix+"/list-config-history-kv").HandlerFunc(httpTraceAll(adminAPI.ListConfigHistoryKVHandler)).Queries("count", "{count:[0-9]+}") - adminRouter.Methods(http.MethodDelete).Path(adminAPIVersionPrefix+"/clear-config-history-kv").HandlerFunc(httpTraceHdrs(adminAPI.ClearConfigHistoryKVHandler)).Queries("restoreId", "{restoreId:.*}") - adminRouter.Methods(http.MethodPut).Path(adminAPIVersionPrefix+"/restore-config-history-kv").HandlerFunc(httpTraceHdrs(adminAPI.RestoreConfigHistoryKVHandler)).Queries("restoreId", "{restoreId:.*}") - } + /// Health operations - /// Config operations - if enableConfigOps { - // Get config - adminRouter.Methods(http.MethodGet).Path(adminAPIVersionPrefix + "/config").HandlerFunc(httpTraceHdrs(adminAPI.GetConfigHandler)) - // Set config - adminRouter.Methods(http.MethodPut).Path(adminAPIVersionPrefix + "/config").HandlerFunc(httpTraceHdrs(adminAPI.SetConfigHandler)) - } + } + // Performance command - return performance details based on input type + adminRouter.Methods(http.MethodGet).Path(adminVersion+"/performance").HandlerFunc(httpTraceAll(adminAPI.PerfInfoHandler)).Queries("perfType", "{perfType:.*}") - if enableIAMOps { - // -- IAM APIs -- + // Profiling operations + adminRouter.Methods(http.MethodPost).Path(adminVersion+"/profiling/start").HandlerFunc(httpTraceAll(adminAPI.StartProfilingHandler)). + Queries("profilerType", "{profilerType:.*}") + adminRouter.Methods(http.MethodGet).Path(adminVersion + "/profiling/download").HandlerFunc(httpTraceAll(adminAPI.DownloadProfilingHandler)) - // Add policy IAM - adminRouter.Methods(http.MethodPut).Path(adminAPIVersionPrefix+"/add-canned-policy").HandlerFunc(httpTraceHdrs(adminAPI.AddCannedPolicy)).Queries("name", - "{name:.*}") + // Config KV operations. + if enableConfigOps { + adminRouter.Methods(http.MethodGet).Path(adminVersion+"/get-config-kv").HandlerFunc(httpTraceHdrs(adminAPI.GetConfigKVHandler)).Queries("key", "{key:.*}") + adminRouter.Methods(http.MethodPut).Path(adminVersion + "/set-config-kv").HandlerFunc(httpTraceHdrs(adminAPI.SetConfigKVHandler)) + adminRouter.Methods(http.MethodDelete).Path(adminVersion + "/del-config-kv").HandlerFunc(httpTraceHdrs(adminAPI.DelConfigKVHandler)) + adminRouter.Methods(http.MethodGet).Path(adminVersion+"/help-config-kv").HandlerFunc(httpTraceAll(adminAPI.HelpConfigKVHandler)).Queries("subSys", "{subSys:.*}", "key", "{key:.*}") + adminRouter.Methods(http.MethodGet).Path(adminVersion+"/list-config-history-kv").HandlerFunc(httpTraceAll(adminAPI.ListConfigHistoryKVHandler)).Queries("count", "{count:[0-9]+}") + adminRouter.Methods(http.MethodDelete).Path(adminVersion+"/clear-config-history-kv").HandlerFunc(httpTraceHdrs(adminAPI.ClearConfigHistoryKVHandler)).Queries("restoreId", "{restoreId:.*}") + adminRouter.Methods(http.MethodPut).Path(adminVersion+"/restore-config-history-kv").HandlerFunc(httpTraceHdrs(adminAPI.RestoreConfigHistoryKVHandler)).Queries("restoreId", "{restoreId:.*}") + } - // Add user IAM - adminRouter.Methods(http.MethodPut).Path(adminAPIVersionPrefix+"/add-user").HandlerFunc(httpTraceHdrs(adminAPI.AddUser)).Queries("accessKey", "{accessKey:.*}") - adminRouter.Methods(http.MethodPut).Path(adminAPIVersionPrefix+"/set-user-status").HandlerFunc(httpTraceHdrs(adminAPI.SetUserStatus)). - Queries("accessKey", "{accessKey:.*}").Queries("status", "{status:.*}") + /// Config operations + if enableConfigOps { + // Get config + adminRouter.Methods(http.MethodGet).Path(adminVersion + "/config").HandlerFunc(httpTraceHdrs(adminAPI.GetConfigHandler)) + // Set config + adminRouter.Methods(http.MethodPut).Path(adminVersion + "/config").HandlerFunc(httpTraceHdrs(adminAPI.SetConfigHandler)) + } - // Service accounts ops - adminRouter.Methods(http.MethodPut).Path(adminAPIVersionPrefix + "/add-service-account").HandlerFunc(httpTraceHdrs(adminAPI.AddServiceAccount)) - adminRouter.Methods(http.MethodGet).Path(adminAPIVersionPrefix+"/get-service-account").HandlerFunc(httpTraceHdrs(adminAPI.GetServiceAccount)).Queries("accessKey", "{accessKey:.*}") + if enableIAMOps { + // -- IAM APIs -- - // Info policy IAM - adminRouter.Methods(http.MethodGet).Path(adminAPIVersionPrefix+"/info-canned-policy").HandlerFunc(httpTraceHdrs(adminAPI.InfoCannedPolicy)).Queries("name", "{name:.*}") + // Add policy IAM + adminRouter.Methods(http.MethodPut).Path(adminVersion+"/add-canned-policy").HandlerFunc(httpTraceHdrs(adminAPI.AddCannedPolicy)).Queries("name", "{name:.*}") - // Remove policy IAM - adminRouter.Methods(http.MethodDelete).Path(adminAPIVersionPrefix+"/remove-canned-policy").HandlerFunc(httpTraceHdrs(adminAPI.RemoveCannedPolicy)).Queries("name", "{name:.*}") + // Add user IAM + adminRouter.Methods(http.MethodPut).Path(adminVersion+"/add-user").HandlerFunc(httpTraceHdrs(adminAPI.AddUser)).Queries("accessKey", "{accessKey:.*}") - // Set user or group policy - adminRouter.Methods(http.MethodPut).Path(adminAPIVersionPrefix+"/set-user-or-group-policy"). - HandlerFunc(httpTraceHdrs(adminAPI.SetPolicyForUserOrGroup)). - Queries("policyName", "{policyName:.*}", "userOrGroup", "{userOrGroup:.*}", "isGroup", "{isGroup:true|false}") + adminRouter.Methods(http.MethodPut).Path(adminVersion+"/set-user-status").HandlerFunc(httpTraceHdrs(adminAPI.SetUserStatus)).Queries("accessKey", "{accessKey:.*}").Queries("status", "{status:.*}") - // Remove user IAM - adminRouter.Methods(http.MethodDelete).Path(adminAPIVersionPrefix+"/remove-user").HandlerFunc(httpTraceHdrs(adminAPI.RemoveUser)).Queries("accessKey", "{accessKey:.*}") + // Service accounts ops + adminRouter.Methods(http.MethodPut).Path(adminVersion + "/add-service-account").HandlerFunc(httpTraceHdrs(adminAPI.AddServiceAccount)) + adminRouter.Methods(http.MethodGet).Path(adminVersion+"/get-service-account").HandlerFunc(httpTraceHdrs(adminAPI.GetServiceAccount)).Queries("accessKey", "{accessKey:.*}") - // List users - adminRouter.Methods(http.MethodGet).Path(adminAPIVersionPrefix + "/list-users").HandlerFunc(httpTraceHdrs(adminAPI.ListUsers)) + if adminVersion == adminAPIVersionV2Prefix { + // Info policy IAM v2 + adminRouter.Methods(http.MethodGet).Path(adminVersion+"/info-canned-policy").HandlerFunc(httpTraceHdrs(adminAPI.InfoCannedPolicyV2)).Queries("name", "{name:.*}") - // User info - adminRouter.Methods(http.MethodGet).Path(adminAPIVersionPrefix+"/user-info").HandlerFunc(httpTraceHdrs(adminAPI.GetUserInfo)).Queries("accessKey", "{accessKey:.*}") + // List policies v2 + adminRouter.Methods(http.MethodGet).Path(adminVersion + "/list-canned-policies").HandlerFunc(httpTraceHdrs(adminAPI.ListCannedPoliciesV2)) + } else { + // Info policy IAM latest + adminRouter.Methods(http.MethodGet).Path(adminVersion+"/info-canned-policy").HandlerFunc(httpTraceHdrs(adminAPI.InfoCannedPolicy)).Queries("name", "{name:.*}") - // Add/Remove members from group - adminRouter.Methods(http.MethodPut).Path(adminAPIVersionPrefix + "/update-group-members").HandlerFunc(httpTraceHdrs(adminAPI.UpdateGroupMembers)) + // List policies latest + adminRouter.Methods(http.MethodGet).Path(adminVersion + "/list-canned-policies").HandlerFunc(httpTraceHdrs(adminAPI.ListCannedPolicies)) + } - // Get Group - adminRouter.Methods(http.MethodGet).Path(adminAPIVersionPrefix+"/group").HandlerFunc(httpTraceHdrs(adminAPI.GetGroup)).Queries("group", "{group:.*}") + // Remove policy IAM + adminRouter.Methods(http.MethodDelete).Path(adminVersion+"/remove-canned-policy").HandlerFunc(httpTraceHdrs(adminAPI.RemoveCannedPolicy)).Queries("name", "{name:.*}") - // List Groups - adminRouter.Methods(http.MethodGet).Path(adminAPIVersionPrefix + "/groups").HandlerFunc(httpTraceHdrs(adminAPI.ListGroups)) + // Set user or group policy + adminRouter.Methods(http.MethodPut).Path(adminVersion+"/set-user-or-group-policy"). + HandlerFunc(httpTraceHdrs(adminAPI.SetPolicyForUserOrGroup)). + Queries("policyName", "{policyName:.*}", "userOrGroup", "{userOrGroup:.*}", "isGroup", "{isGroup:true|false}") - // Set Group Status - adminRouter.Methods(http.MethodPut).Path(adminAPIVersionPrefix+"/set-group-status").HandlerFunc(httpTraceHdrs(adminAPI.SetGroupStatus)).Queries("group", "{group:.*}").Queries("status", "{status:.*}") + // Remove user IAM + adminRouter.Methods(http.MethodDelete).Path(adminVersion+"/remove-user").HandlerFunc(httpTraceHdrs(adminAPI.RemoveUser)).Queries("accessKey", "{accessKey:.*}") - // List policies - adminRouter.Methods(http.MethodGet).Path(adminAPIVersionPrefix + "/list-canned-policies").HandlerFunc(httpTraceHdrs(adminAPI.ListCannedPolicies)) - } + // List users + adminRouter.Methods(http.MethodGet).Path(adminVersion + "/list-users").HandlerFunc(httpTraceHdrs(adminAPI.ListUsers)) - // -- Top APIs -- - // Top locks - if globalIsDistXL { - adminRouter.Methods(http.MethodGet).Path(adminAPIVersionPrefix + "/top/locks").HandlerFunc(httpTraceHdrs(adminAPI.TopLocksHandler)) - } + // User info + adminRouter.Methods(http.MethodGet).Path(adminVersion+"/user-info").HandlerFunc(httpTraceHdrs(adminAPI.GetUserInfo)).Queries("accessKey", "{accessKey:.*}") + + // Add/Remove members from group + adminRouter.Methods(http.MethodPut).Path(adminVersion + "/update-group-members").HandlerFunc(httpTraceHdrs(adminAPI.UpdateGroupMembers)) + + // Get Group + adminRouter.Methods(http.MethodGet).Path(adminVersion+"/group").HandlerFunc(httpTraceHdrs(adminAPI.GetGroup)).Queries("group", "{group:.*}") + + // List Groups + adminRouter.Methods(http.MethodGet).Path(adminVersion + "/groups").HandlerFunc(httpTraceHdrs(adminAPI.ListGroups)) + + // Set Group Status + adminRouter.Methods(http.MethodPut).Path(adminVersion+"/set-group-status").HandlerFunc(httpTraceHdrs(adminAPI.SetGroupStatus)).Queries("group", "{group:.*}").Queries("status", "{status:.*}") + + } + + // -- Top APIs -- + // Top locks + if globalIsDistXL { + adminRouter.Methods(http.MethodGet).Path(adminVersion + "/top/locks").HandlerFunc(httpTraceHdrs(adminAPI.TopLocksHandler)) + } - // HTTP Trace - adminRouter.Methods(http.MethodGet).Path(adminAPIVersionPrefix + "/trace").HandlerFunc(adminAPI.TraceHandler) + // HTTP Trace + adminRouter.Methods(http.MethodGet).Path(adminVersion + "/trace").HandlerFunc(adminAPI.TraceHandler) - // Console Logs - adminRouter.Methods(http.MethodGet).Path(adminAPIVersionPrefix + "/log").HandlerFunc(httpTraceAll(adminAPI.ConsoleLogHandler)) + // Console Logs + adminRouter.Methods(http.MethodGet).Path(adminVersion + "/log").HandlerFunc(httpTraceAll(adminAPI.ConsoleLogHandler)) - // -- KMS APIs -- - // - adminRouter.Methods(http.MethodGet).Path(adminAPIVersionPrefix + "/kms/key/status").HandlerFunc(httpTraceAll(adminAPI.KMSKeyStatusHandler)) + // -- KMS APIs -- + // + adminRouter.Methods(http.MethodGet).Path(adminVersion + "/kms/key/status").HandlerFunc(httpTraceAll(adminAPI.KMSKeyStatusHandler)) - if !globalIsGateway { + if !globalIsGateway { - // -- OBD API -- - adminRouter.Methods(http.MethodGet).Path(adminAPIVersionPrefix+"/obdinfo").HandlerFunc(httpTraceHdrs(adminAPI.OBDInfoHandler)).Queries("perfdrive", "{perfdrive:true|false}", "perfnet", "{perfnet:true|false}", "minioinfo", "{minioinfo:true|false}", "minioconfig", "{minioconfig:true|false}", "syscpu", "{syscpu:true|false}", "sysdiskhw", "{sysdiskhw:true|false}", "sysosinfo", "{sysosinfo:true|false}", "sysmem", "{sysmem:true|false}", "sysprocess", "{sysprocess:true|false}") + // -- OBD API -- + adminRouter.Methods(http.MethodGet).Path(adminVersion+"/obdinfo").HandlerFunc(httpTraceHdrs(adminAPI.OBDInfoHandler)).Queries("perfdrive", "{perfdrive:true|false}", "perfnet", "{perfnet:true|false}", "minioinfo", "{minioinfo:true|false}", "minioconfig", "{minioconfig:true|false}", "syscpu", "{syscpu:true|false}", "sysdiskhw", "{sysdiskhw:true|false}", "sysosinfo", "{sysosinfo:true|false}", "sysmem", "{sysmem:true|false}", "sysprocess", "{sysprocess:true|false}") + } } // If none of the routes match add default error handler routes diff --git a/cmd/iam.go b/cmd/iam.go index 570e95aed..e70d06149 100644 --- a/cmd/iam.go +++ b/cmd/iam.go @@ -20,7 +20,6 @@ import ( "bytes" "context" "encoding/base64" - "encoding/json" "fmt" "github.com/minio/minio-go/v6/pkg/set" @@ -457,10 +456,10 @@ func (sys *IAMSys) DeletePolicy(policyName string) error { } // InfoPolicy - expands the canned policy into its JSON structure. -func (sys *IAMSys) InfoPolicy(policyName string) ([]byte, error) { +func (sys *IAMSys) InfoPolicy(policyName string) (iampolicy.Policy, error) { objectAPI := newObjectLayerWithoutSafeModeFn() if objectAPI == nil || sys == nil || sys.store == nil { - return nil, errServerNotInitialized + return iampolicy.Policy{}, errServerNotInitialized } sys.store.rlock() @@ -468,29 +467,25 @@ func (sys *IAMSys) InfoPolicy(policyName string) ([]byte, error) { v, ok := sys.iamPolicyDocsMap[policyName] if !ok { - return nil, errNoSuchPolicy + return iampolicy.Policy{}, errNoSuchPolicy } - return json.Marshal(v) + + return v, nil } // ListPolicies - lists all canned policies. -func (sys *IAMSys) ListPolicies() (map[string][]byte, error) { +func (sys *IAMSys) ListPolicies() (map[string]iampolicy.Policy, error) { objectAPI := newObjectLayerWithoutSafeModeFn() if objectAPI == nil || sys == nil || sys.store == nil { return nil, errServerNotInitialized } - var policyDocsMap = make(map[string][]byte) - sys.store.rlock() defer sys.store.runlock() + policyDocsMap := make(map[string]iampolicy.Policy, len(sys.iamPolicyDocsMap)) for k, v := range sys.iamPolicyDocsMap { - data, err := json.Marshal(v) - if err != nil { - return nil, err - } - policyDocsMap[k] = data + policyDocsMap[k] = v } return policyDocsMap, nil diff --git a/pkg/madmin/README.md b/pkg/madmin/README.md index cb68e07e0..86c72ddfb 100644 --- a/pkg/madmin/README.md +++ b/pkg/madmin/README.md @@ -71,7 +71,7 @@ __Parameters__ ## 2. Service operations -### ServiceStatus() (ServiceStatusMetadata, error) +### ServiceStatus(ctx context.Context) (ServiceStatusMetadata, error) Fetch service status, replies disk space used, backend type and total disks offline/online (applicable in distributed mode). | Param | Type | Description | @@ -89,7 +89,7 @@ Fetch service status, replies disk space used, backend type and total disks offl ```go - st, err := madmClnt.ServiceStatus() + st, err := madmClnt.ServiceStatus(context.Background()) if err != nil { log.Fatalln(err) } @@ -98,14 +98,14 @@ Fetch service status, replies disk space used, backend type and total disks offl ``` -### ServiceRestart() error +### ServiceRestart(ctx context.Context) error Sends a service action restart command to MinIO server. __Example__ ```go // To restart the service, restarts all servers in the cluster. - err := madmClnt.ServiceRestart() + err := madmClnt.ServiceRestart(context.Background()) if err != nil { log.Fatalln(err) } @@ -113,14 +113,14 @@ Sends a service action restart command to MinIO server. ``` -### ServiceStop() error +### ServiceStop(ctx context.Context) error Sends a service action stop command to MinIO server. __Example__ ```go // To stop the service, stops all servers in the cluster. - err := madmClnt.ServiceStop() + err := madmClnt.ServiceStop(context.Background()) if err != nil { log.Fatalln(err) } @@ -128,7 +128,7 @@ Sends a service action stop command to MinIO server. ``` -### ServiceTrace(allTrace bool, doneCh <-chan struct{}) <-chan TraceInfo +### ServiceTrace(ctx context.Context, allTrace bool, doneCh <-chan struct{}) <-chan TraceInfo Enable HTTP request tracing on all nodes in a MinIO cluster __Example__ @@ -139,7 +139,7 @@ __Example__ // listen to all trace including internal API calls allTrace := true // Start listening on all trace activity. - traceCh := madmClnt.ServiceTrace(allTrace, doneCh) + traceCh := madmClnt.ServiceTrace(context.Background(), allTrace, doneCh) for traceInfo := range traceCh { fmt.Println(traceInfo.String()) } @@ -148,7 +148,7 @@ __Example__ ## 3. Info operations -### ServerInfo() ([]ServerInfo, error) +### ServerInfo(ctx context.Context) ([]ServerInfo, error) Fetches information for all cluster nodes, such as server properties, storage information, network statistics, etc. | Param | Type | Description | @@ -199,7 +199,7 @@ Fetches information for all cluster nodes, such as server properties, storage in ```go - serversInfo, err := madmClnt.ServerInfo() + serversInfo, err := madmClnt.ServerInfo(context.Background()) if err != nil { log.Fatalln(err) } @@ -211,7 +211,7 @@ Fetches information for all cluster nodes, such as server properties, storage in ``` -### ServerDrivesPerfInfo() ([]ServerDrivesPerfInfo, error) +### ServerDrivesPerfInfo(ctx context.Context) ([]ServerDrivesPerfInfo, error) Fetches drive performance information for all cluster nodes. @@ -229,7 +229,7 @@ Fetches drive performance information for all cluster nodes. | `disk.Performance.ReadSpeed` | _float64_ | Read speed on above path in Bytes/s. | -### ServerCPULoadInfo() ([]ServerCPULoadInfo, error) +### ServerCPULoadInfo(ctx context.Context) ([]ServerCPULoadInfo, error) Fetches CPU utilization for all cluster nodes. @@ -247,7 +247,7 @@ Fetches CPU utilization for all cluster nodes. | `cpu.Load.Error` | _string_ | Error (if any) encountered while accessing the CPU info | -### ServerMemUsageInfo() ([]ServerMemUsageInfo, error) +### ServerMemUsageInfo(ctx context.Context) ([]ServerMemUsageInfo, error) Fetches Mem utilization for all cluster nodes. @@ -263,7 +263,7 @@ Fetches Mem utilization for all cluster nodes. | `mem.Usage.Error` | _string_ | Error (if any) encountered while accessing the CPU info | -### NetPerfInfo(int size) (map[string][]NetPerfInfo, error) +### NetPerfInfo(ctx context.Context, int size) (map[string][]NetPerfInfo, error) Fetches network performance of all cluster nodes using given sized payload. Returned value is a map containing each node indexed list of performance of other nodes. @@ -275,7 +275,7 @@ Fetches network performance of all cluster nodes using given sized payload. Retu -### ServerCPUHardwareInfo() ([]ServerCPUHardwareInfo, error) +### ServerCPUHardwareInfo(ctx context.Context) ([]ServerCPUHardwareInfo, error) Fetches hardware information of CPU. @@ -302,7 +302,7 @@ Fetches hardware information of CPU. | `CPUInfo.Microcode` | _string_ | Micro codes | -### ServerNetworkHardwareInfo() ([]ServerNetworkHardwareInfo, error) +### ServerNetworkHardwareInfo(ctx context.Context) ([]ServerNetworkHardwareInfo, error) Fetches hardware information of CPU. @@ -321,7 +321,7 @@ Fetches hardware information of CPU. | `NetworkInfo.Flags` | _uint32_ | e.g., FlagUp, FlagLoopback, FlagMulticast | -### StorageInfo() (StorageInfo, error) +### StorageInfo(ctx context.Context) (StorageInfo, error) Fetches Storage information for all cluster nodes. @@ -347,7 +347,7 @@ __Example__ ```go - storageInfo, err := madmClnt.StorageInfo() + storageInfo, err := madmClnt.StorageInfo(context.Background()) if err != nil { log.Fatalln(err) } @@ -359,7 +359,7 @@ __Example__ ## 5. Heal operations -### Heal(bucket, prefix string, healOpts HealOpts, clientToken string, forceStart bool, forceStop bool) (start HealStartSuccess, status HealTaskStatus, err error) +### Heal(ctx context.Context, bucket, prefix string, healOpts HealOpts, clientToken string, forceStart bool, forceStop bool) (start HealStartSuccess, status HealTaskStatus, err error) Start a heal sequence that scans data under given (possible empty) `bucket` and `prefix`. The `recursive` bool turns on recursive @@ -384,7 +384,7 @@ __Example__ } forceStart := false forceStop := false - healPath, err := madmClnt.Heal("", "", opts, "", forceStart, forceStop) + healPath, err := madmClnt.Heal(context.Background(), "", "", opts, "", forceStart, forceStop) if err != nil { log.Fatalln(err) } @@ -424,13 +424,13 @@ __Example__ ## 6. Config operations -### GetConfig() ([]byte, error) +### GetConfig(ctx context.Context) ([]byte, error) Get current `config.json` of a MinIO server. __Example__ ``` go - configBytes, err := madmClnt.GetConfig() + configBytes, err := madmClnt.GetConfig(context.Background()) if err != nil { log.Fatalf("failed due to: %v", err) } @@ -447,14 +447,14 @@ __Example__ -### SetConfig(config io.Reader) error +### SetConfig(ctx context.Context, config io.Reader) error Set a new `config.json` for a MinIO server. __Example__ ``` go config := bytes.NewReader([]byte(`config.json contents go here`)) - if err := madmClnt.SetConfig(config); err != nil { + if err := madmClnt.SetConfig(context.Background(), config); err != nil { log.Fatalf("failed due to: %v", err) } log.Println("SetConfig was successful") @@ -463,13 +463,13 @@ __Example__ ## 7. Top operations -### TopLocks() (LockEntries, error) +### TopLocks(ctx context.Context) (LockEntries, error) Get the oldest locks from MinIO server. __Example__ ``` go - locks, err := madmClnt.TopLocks() + locks, err := madmClnt.TopLocks(context.Background()) if err != nil { log.Fatalf("failed due to: %v", err) } @@ -485,51 +485,54 @@ __Example__ ## 8. IAM operations -### AddCannedPolicy(policyName string, policy string) error +### AddCannedPolicy(ctx context.Context, policyName string, policy *iampolicy.Policy) error Create a new canned policy on MinIO server. __Example__ ``` - policy := `{"Version": "2012-10-17","Statement": [{"Action": ["s3:GetObject"],"Effect": "Allow","Resource": ["arn:aws:s3:::my-bucketname/*"],"Sid": ""}]}` + policy, err := iampolicy.ParseConfig(strings.NewReader(`{"Version": "2012-10-17","Statement": [{"Action": ["s3:GetObject"],"Effect": "Allow","Resource": ["arn:aws:s3:::my-bucketname/*"],"Sid": ""}]}`)) + if err != nil { + log.Fatalln(err) + } - if err = madmClnt.AddCannedPolicy("get-only", policy); err != nil { + if err = madmClnt.AddCannedPolicy(context.Background(), "get-only", policy); err != nil { log.Fatalln(err) } ``` -### AddUser(user string, secret string) error +### AddUser(ctx context.Context, user string, secret string) error Add a new user on a MinIO server. __Example__ ``` go - if err = madmClnt.AddUser("newuser", "newstrongpassword"); err != nil { + if err = madmClnt.AddUser(context.Background(), "newuser", "newstrongpassword"); err != nil { log.Fatalln(err) } ``` -### SetUserPolicy(user string, policyName string) error +### SetUserPolicy(ctx context.Context, user string, policyName string) error Enable a canned policy `get-only` for a given user on MinIO server. __Example__ ``` go - if err = madmClnt.SetUserPolicy("newuser", "get-only"); err != nil { + if err = madmClnt.SetUserPolicy(context.Background(), "newuser", "get-only"); err != nil { log.Fatalln(err) } ``` -### ListUsers() (map[string]UserInfo, error) +### ListUsers(ctx context.Context) (map[string]UserInfo, error) Lists all users on MinIO server. __Example__ ``` go - users, err := madmClnt.ListUsers(); + users, err := madmClnt.ListUsers(context.Background()); if err != nil { log.Fatalln(err) } @@ -541,7 +544,7 @@ __Example__ ## 9. Misc operations -### ServerUpdate(updateURL string) (ServerUpdateStatus, error) +### ServerUpdate(ctx context.Context, updateURL string) (ServerUpdateStatus, error) Sends a update command to MinIO server, to update MinIO server to latest release. In distributed setup it updates all servers atomically. __Example__ @@ -549,7 +552,7 @@ Sends a update command to MinIO server, to update MinIO server to latest release ```go // Updates all servers and restarts all the servers in the cluster. // optionally takes an updateURL, which is used to update the binary. - us, err := madmClnt.ServerUpdate(updateURL) + us, err := madmClnt.ServerUpdate(context.Background(), updateURL) if err != nil { log.Fatalln(err) } @@ -559,13 +562,13 @@ Sends a update command to MinIO server, to update MinIO server to latest release ``` -### StartProfiling(profiler string) error +### StartProfiling(ctx context.Context, profiler string) error Ask all nodes to start profiling using the specified profiler mode __Example__ ``` go - startProfilingResults, err = madmClnt.StartProfiling("cpu") + startProfilingResults, err = madmClnt.StartProfiling(context.Background(), "cpu") if err != nil { log.Fatalln(err) } @@ -580,13 +583,13 @@ __Example__ ``` -### DownloadProfilingData() ([]byte, error) +### DownloadProfilingData(ctx context.Context) ([]byte, error) Download profiling data of all nodes in a zip format. __Example__ ``` go - profilingData, err := madmClnt.DownloadProfilingData() + profilingData, err := madmClnt.DownloadProfilingData(context.Background()) if err != nil { log.Fatalln(err) } @@ -614,7 +617,7 @@ __Example__ ## 11. KMS -### GetKeyStatus(keyID string) (*KMSKeyStatus, error) +### GetKeyStatus(ctx context.Context, keyID string) (*KMSKeyStatus, error) Requests status information about one particular KMS master key from a MinIO server. The keyID is optional and the server will use the default master key (configured via `MINIO_KMS_VAULT_KEY_NAME` @@ -623,7 +626,7 @@ or `MINIO_KMS_MASTER_KEY`) if the keyID is empty. __Example__ ``` go - keyInfo, err := madmClnt.GetKeyStatus("my-minio-key") + keyInfo, err := madmClnt.GetKeyStatus(context.Background(), "my-minio-key") if err != nil { log.Fatalln(err) } diff --git a/pkg/madmin/config-commands.go b/pkg/madmin/config-commands.go index 941cbf871..3cdf43ac6 100644 --- a/pkg/madmin/config-commands.go +++ b/pkg/madmin/config-commands.go @@ -26,7 +26,7 @@ import ( // GetConfig - returns the config.json of a minio setup, incoming data is encrypted. func (adm *AdminClient) GetConfig(ctx context.Context) ([]byte, error) { - // Execute GET on /minio/admin/v2/config to get config of a setup. + // Execute GET on /minio/admin/v3/config to get config of a setup. resp, err := adm.executeMethod(ctx, http.MethodGet, requestData{relPath: adminAPIPrefix + "/config"}) @@ -66,7 +66,7 @@ func (adm *AdminClient) SetConfig(ctx context.Context, config io.Reader) (err er content: econfigBytes, } - // Execute PUT on /minio/admin/v2/config to set config. + // Execute PUT on /minio/admin/v3/config to set config. resp, err := adm.executeMethod(ctx, http.MethodPut, reqData) defer closeResponse(resp) diff --git a/pkg/madmin/config-help-commands.go b/pkg/madmin/config-help-commands.go index f97e3b45b..4d64c35b8 100644 --- a/pkg/madmin/config-help-commands.go +++ b/pkg/madmin/config-help-commands.go @@ -59,7 +59,7 @@ func (adm *AdminClient) HelpConfigKV(ctx context.Context, subSys, key string, en queryValues: v, } - // Execute GET on /minio/admin/v2/help-config-kv + // Execute GET on /minio/admin/v3/help-config-kv resp, err := adm.executeMethod(ctx, http.MethodGet, reqData) if err != nil { return Help{}, err diff --git a/pkg/madmin/config-history-commands.go b/pkg/madmin/config-history-commands.go index cd74bed42..a1838ac8c 100644 --- a/pkg/madmin/config-history-commands.go +++ b/pkg/madmin/config-history-commands.go @@ -37,7 +37,7 @@ func (adm *AdminClient) ClearConfigHistoryKV(ctx context.Context, restoreID stri queryValues: v, } - // Execute DELETE on /minio/admin/v2/clear-config-history-kv + // Execute DELETE on /minio/admin/v3/clear-config-history-kv resp, err := adm.executeMethod(ctx, http.MethodDelete, reqData) defer closeResponse(resp) @@ -62,7 +62,7 @@ func (adm *AdminClient) RestoreConfigHistoryKV(ctx context.Context, restoreID st queryValues: v, } - // Execute PUT on /minio/admin/v2/set-config-kv to set config key/value. + // Execute PUT on /minio/admin/v3/set-config-kv to set config key/value. resp, err := adm.executeMethod(ctx, http.MethodPut, reqData) defer closeResponse(resp) @@ -98,7 +98,7 @@ func (adm *AdminClient) ListConfigHistoryKV(ctx context.Context, count int) ([]C v := url.Values{} v.Set("count", strconv.Itoa(count)) - // Execute GET on /minio/admin/v2/list-config-history-kv + // Execute GET on /minio/admin/v3/list-config-history-kv resp, err := adm.executeMethod(ctx, http.MethodGet, requestData{ diff --git a/pkg/madmin/config-kv-commands.go b/pkg/madmin/config-kv-commands.go index 314a30132..3d9653aab 100644 --- a/pkg/madmin/config-kv-commands.go +++ b/pkg/madmin/config-kv-commands.go @@ -35,7 +35,7 @@ func (adm *AdminClient) DelConfigKV(ctx context.Context, k string) (err error) { content: econfigBytes, } - // Execute DELETE on /minio/admin/v2/del-config-kv to delete config key. + // Execute DELETE on /minio/admin/v3/del-config-kv to delete config key. resp, err := adm.executeMethod(ctx, http.MethodDelete, reqData) defer closeResponse(resp) @@ -62,7 +62,7 @@ func (adm *AdminClient) SetConfigKV(ctx context.Context, kv string) (err error) content: econfigBytes, } - // Execute PUT on /minio/admin/v2/set-config-kv to set config key/value. + // Execute PUT on /minio/admin/v3/set-config-kv to set config key/value. resp, err := adm.executeMethod(ctx, http.MethodPut, reqData) defer closeResponse(resp) @@ -82,7 +82,7 @@ func (adm *AdminClient) GetConfigKV(ctx context.Context, key string) (Targets, e v := url.Values{} v.Set("key", key) - // Execute GET on /minio/admin/v2/get-config-kv?key={key} to get value of key. + // Execute GET on /minio/admin/v3/get-config-kv?key={key} to get value of key. resp, err := adm.executeMethod(ctx, http.MethodGet, requestData{ diff --git a/pkg/madmin/group-commands.go b/pkg/madmin/group-commands.go index a2f689146..fa31116bb 100644 --- a/pkg/madmin/group-commands.go +++ b/pkg/madmin/group-commands.go @@ -46,7 +46,7 @@ func (adm *AdminClient) UpdateGroupMembers(ctx context.Context, g GroupAddRemove content: data, } - // Execute PUT on /minio/admin/v2/update-group-members + // Execute PUT on /minio/admin/v3/update-group-members resp, err := adm.executeMethod(ctx, http.MethodPut, reqData) defer closeResponse(resp) diff --git a/pkg/madmin/kms-commands.go b/pkg/madmin/kms-commands.go index 7e3cf0322..064b4dce8 100644 --- a/pkg/madmin/kms-commands.go +++ b/pkg/madmin/kms-commands.go @@ -25,9 +25,9 @@ import ( // GetKeyStatus requests status information about the key referenced by keyID // from the KMS connected to a MinIO by performing a Admin-API request. -// It basically hits the `/minio/admin/v2/kms/key/status` API endpoint. +// It basically hits the `/minio/admin/v3/kms/key/status` API endpoint. func (adm *AdminClient) GetKeyStatus(ctx context.Context, keyID string) (*KMSKeyStatus, error) { - // GET /minio/admin/v2/kms/key/status?key-id= + // GET /minio/admin/v3/kms/key/status?key-id= qv := url.Values{} qv.Set("key-id", keyID) reqData := requestData{ diff --git a/pkg/madmin/policy-commands.go b/pkg/madmin/policy-commands.go index 0bdb4dede..8b1844826 100644 --- a/pkg/madmin/policy-commands.go +++ b/pkg/madmin/policy-commands.go @@ -1,5 +1,5 @@ /* - * MinIO Cloud Storage, (C) 2018 MinIO, Inc. + * MinIO Cloud Storage, (C) 2018-2020 MinIO, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,10 +23,12 @@ import ( "io/ioutil" "net/http" "net/url" + + iampolicy "github.com/minio/minio/pkg/iam/policy" ) // InfoCannedPolicy - expand canned policy into JSON structure. -func (adm *AdminClient) InfoCannedPolicy(ctx context.Context, policyName string) ([]byte, error) { +func (adm *AdminClient) InfoCannedPolicy(ctx context.Context, policyName string) (*iampolicy.Policy, error) { queryValues := url.Values{} queryValues.Set("name", policyName) @@ -35,7 +37,7 @@ func (adm *AdminClient) InfoCannedPolicy(ctx context.Context, policyName string) queryValues: queryValues, } - // Execute GET on /minio/admin/v2/info-canned-policy + // Execute GET on /minio/admin/v3/info-canned-policy resp, err := adm.executeMethod(ctx, http.MethodGet, reqData) defer closeResponse(resp) @@ -47,16 +49,16 @@ func (adm *AdminClient) InfoCannedPolicy(ctx context.Context, policyName string) return nil, httpRespToErrorResponse(resp) } - return ioutil.ReadAll(resp.Body) + return iampolicy.ParseConfig(resp.Body) } // ListCannedPolicies - list all configured canned policies. -func (adm *AdminClient) ListCannedPolicies(ctx context.Context) (map[string][]byte, error) { +func (adm *AdminClient) ListCannedPolicies(ctx context.Context) (map[string]*iampolicy.Policy, error) { reqData := requestData{ relPath: adminAPIPrefix + "/list-canned-policies", } - // Execute GET on /minio/admin/v2/list-canned-policies + // Execute GET on /minio/admin/v3/list-canned-policies resp, err := adm.executeMethod(ctx, http.MethodGet, reqData) defer closeResponse(resp) @@ -73,7 +75,7 @@ func (adm *AdminClient) ListCannedPolicies(ctx context.Context) (map[string][]by return nil, err } - var policies = make(map[string][]byte) + var policies = make(map[string]*iampolicy.Policy) if err = json.Unmarshal(respBytes, &policies); err != nil { return nil, err } @@ -91,7 +93,7 @@ func (adm *AdminClient) RemoveCannedPolicy(ctx context.Context, policyName strin queryValues: queryValues, } - // Execute DELETE on /minio/admin/v2/remove-canned-policy to remove policy. + // Execute DELETE on /minio/admin/v3/remove-canned-policy to remove policy. resp, err := adm.executeMethod(ctx, http.MethodDelete, reqData) defer closeResponse(resp) @@ -107,17 +109,26 @@ func (adm *AdminClient) RemoveCannedPolicy(ctx context.Context, policyName strin } // AddCannedPolicy - adds a policy for a canned. -func (adm *AdminClient) AddCannedPolicy(ctx context.Context, policyName, policy string) error { +func (adm *AdminClient) AddCannedPolicy(ctx context.Context, policyName string, policy *iampolicy.Policy) error { + if policy == nil { + return ErrInvalidArgument("policy input cannot be empty") + } + + buf, err := json.Marshal(policy) + if err != nil { + return err + } + queryValues := url.Values{} queryValues.Set("name", policyName) reqData := requestData{ relPath: adminAPIPrefix + "/add-canned-policy", queryValues: queryValues, - content: []byte(policy), + content: buf, } - // Execute PUT on /minio/admin/v2/add-canned-policy to set policy. + // Execute PUT on /minio/admin/v3/add-canned-policy to set policy. resp, err := adm.executeMethod(ctx, http.MethodPut, reqData) defer closeResponse(resp) @@ -148,7 +159,7 @@ func (adm *AdminClient) SetPolicy(ctx context.Context, policyName, entityName st queryValues: queryValues, } - // Execute PUT on /minio/admin/v2/set-user-or-group-policy to set policy. + // Execute PUT on /minio/admin/v3/set-user-or-group-policy to set policy. resp, err := adm.executeMethod(ctx, http.MethodPut, reqData) defer closeResponse(resp) if err != nil { diff --git a/pkg/madmin/top-commands.go b/pkg/madmin/top-commands.go index fed76b5ea..9469b69bc 100644 --- a/pkg/madmin/top-commands.go +++ b/pkg/madmin/top-commands.go @@ -55,7 +55,7 @@ func (l LockEntries) Swap(i, j int) { // TopLocks - returns the oldest locks in a minio setup. func (adm *AdminClient) TopLocks(ctx context.Context) (LockEntries, error) { - // Execute GET on /minio/admin/v2/top/locks + // Execute GET on /minio/admin/v3/top/locks // to get the oldest locks in a minio setup. resp, err := adm.executeMethod(ctx, http.MethodGet, diff --git a/pkg/madmin/user-commands.go b/pkg/madmin/user-commands.go index e0ed1a01a..4e93564bb 100644 --- a/pkg/madmin/user-commands.go +++ b/pkg/madmin/user-commands.go @@ -54,7 +54,7 @@ func (adm *AdminClient) RemoveUser(ctx context.Context, accessKey string) error queryValues: queryValues, } - // Execute DELETE on /minio/admin/v2/remove-user to remove a user. + // Execute DELETE on /minio/admin/v3/remove-user to remove a user. resp, err := adm.executeMethod(ctx, http.MethodDelete, reqData) defer closeResponse(resp) @@ -75,7 +75,7 @@ func (adm *AdminClient) ListUsers(ctx context.Context) (map[string]UserInfo, err relPath: adminAPIPrefix + "/list-users", } - // Execute GET on /minio/admin/v2/list-users + // Execute GET on /minio/admin/v3/list-users resp, err := adm.executeMethod(ctx, http.MethodGet, reqData) defer closeResponse(resp) @@ -110,7 +110,7 @@ func (adm *AdminClient) GetUserInfo(ctx context.Context, name string) (u UserInf queryValues: queryValues, } - // Execute GET on /minio/admin/v2/user-info + // Execute GET on /minio/admin/v3/user-info resp, err := adm.executeMethod(ctx, http.MethodGet, reqData) defer closeResponse(resp) @@ -166,7 +166,7 @@ func (adm *AdminClient) SetUser(ctx context.Context, accessKey, secretKey string content: econfigBytes, } - // Execute PUT on /minio/admin/v2/add-user to set a user. + // Execute PUT on /minio/admin/v3/add-user to set a user. resp, err := adm.executeMethod(ctx, http.MethodPut, reqData) defer closeResponse(resp) @@ -197,7 +197,7 @@ func (adm *AdminClient) SetUserStatus(ctx context.Context, accessKey string, sta queryValues: queryValues, } - // Execute PUT on /minio/admin/v2/set-user-status to set status. + // Execute PUT on /minio/admin/v3/set-user-status to set status. resp, err := adm.executeMethod(ctx, http.MethodPut, reqData) defer closeResponse(resp) @@ -249,7 +249,7 @@ func (adm *AdminClient) AddServiceAccount(ctx context.Context, parentUser string content: econfigBytes, } - // Execute PUT on /minio/admin/v2/add-service-account to set a user. + // Execute PUT on /minio/admin/v3/add-service-account to set a user. resp, err := adm.executeMethod(ctx, http.MethodPut, reqData) defer closeResponse(resp) if err != nil { @@ -287,7 +287,7 @@ func (adm *AdminClient) GetServiceAccount(ctx context.Context, serviceAccountAcc queryValues: queryValues, } - // Execute GET on /minio/admin/v2/get-service-account to set a user. + // Execute GET on /minio/admin/v3/get-service-account to set a user. resp, err := adm.executeMethod(ctx, http.MethodGet, reqData) defer closeResponse(resp) if err != nil { diff --git a/pkg/madmin/utils.go b/pkg/madmin/utils.go index fd8de4420..125ebf9f8 100644 --- a/pkg/madmin/utils.go +++ b/pkg/madmin/utils.go @@ -30,10 +30,11 @@ import ( "github.com/minio/minio-go/v6/pkg/s3utils" ) +// AdminAPIVersion - admin api version used in the request. const ( - // AdminAPIVersion - admin api version used in the request. - AdminAPIVersion = "v2" - adminAPIPrefix = "/" + AdminAPIVersion + AdminAPIVersion = "v3" + AdminAPIVersionV2 = "v2" + adminAPIPrefix = "/" + AdminAPIVersion ) // sum256 calculate sha256 sum for an input byte array.