From ae002aa7241bd35d5fd9b47e8b62df2176ad2ab1 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Wed, 24 Apr 2019 12:54:44 -0700 Subject: [PATCH] Deprecate updating admin credentials using API calls (#7570) Root credentials are not allowed to change in all of our distributed setup deployments, this PR simply removes that behavior. --- cmd/admin-handlers.go | 68 --- cmd/admin-handlers_test.go | 80 ---- cmd/admin-router.go | 2 - pkg/madmin/API.md | 549 ------------------------ pkg/madmin/README.md | 565 +++++++++++++++++++++---- pkg/madmin/examples/set-credentials.go | 44 -- pkg/madmin/generic-commands.go | 66 --- 7 files changed, 492 insertions(+), 882 deletions(-) delete mode 100644 pkg/madmin/API.md delete mode 100644 pkg/madmin/examples/set-credentials.go delete mode 100644 pkg/madmin/generic-commands.go diff --git a/cmd/admin-handlers.go b/cmd/admin-handlers.go index fa3cdaad3..a747a52e2 100644 --- a/cmd/admin-handlers.go +++ b/cmd/admin-handlers.go @@ -35,7 +35,6 @@ import ( "github.com/tidwall/sjson" "github.com/minio/minio/cmd/logger" - "github.com/minio/minio/pkg/auth" "github.com/minio/minio/pkg/cpu" "github.com/minio/minio/pkg/disk" "github.com/minio/minio/pkg/handlers" @@ -1416,70 +1415,3 @@ func (a adminAPIHandlers) SetConfigKeysHandler(w http.ResponseWriter, r *http.Re // Send success response writeSuccessResponseHeadersOnly(w) } - -// UpdateAdminCredsHandler - POST /minio/admin/v1/config/credential -// ---------- -// Update admin credentials in a minio server -func (a adminAPIHandlers) UpdateAdminCredentialsHandler(w http.ResponseWriter, - r *http.Request) { - - ctx := newContext(r, w, "UpdateCredentialsHandler") - - objectAPI := validateAdminReq(ctx, w, r) - if objectAPI == nil { - return - } - - // Avoid setting new credentials when they are already passed - // by the environment. Deny if WORM is enabled. - if globalIsEnvCreds || globalWORMEnabled { - writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL) - return - } - - if r.ContentLength > maxEConfigJSONSize || r.ContentLength == -1 { - // More than maxConfigSize bytes were available - writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigTooLarge), r.URL) - return - } - - password := globalServerConfig.GetCredential().SecretKey - configBytes, err := madmin.DecryptData(password, io.LimitReader(r.Body, r.ContentLength)) - if err != nil { - logger.LogIf(ctx, err) - writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), err.Error(), r.URL) - return - } - - // Decode request body - var req madmin.SetCredsReq - if err = json.Unmarshal(configBytes, &req); err != nil { - logger.LogIf(ctx, err) - writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrRequestBodyParse), r.URL) - return - } - - creds, err := auth.CreateCredentials(req.AccessKey, req.SecretKey) - if err != nil { - writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) - return - } - - // Acquire lock before updating global configuration. - globalServerConfigMu.Lock() - defer globalServerConfigMu.Unlock() - - // Update local credentials in memory. - globalServerConfig.SetCredential(creds) - - // Set active creds. - globalActiveCred = creds - - if err = saveServerConfig(ctx, objectAPI, globalServerConfig); err != nil { - writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) - return - } - - // Reply to the client before restarting minio server. - writeSuccessResponseHeadersOnly(w) -} diff --git a/cmd/admin-handlers_test.go b/cmd/admin-handlers_test.go index 010c7e03f..78cdbb056 100644 --- a/cmd/admin-handlers_test.go +++ b/cmd/admin-handlers_test.go @@ -599,86 +599,6 @@ func TestServiceRestartHandler(t *testing.T) { testServicesCmdHandler(restartCmd, t) } -// Test for service set creds management REST API. -func TestServiceSetCreds(t *testing.T) { - adminTestBed, err := prepareAdminXLTestBed() - if err != nil { - t.Fatal("Failed to initialize a single node XL backend for admin handler tests.") - } - defer adminTestBed.TearDown() - - // Initialize admin peers to make admin RPC calls. Note: In a - // single node setup, this degenerates to a simple function - // call under the hood. - globalMinioAddr = "127.0.0.1:9000" - - credentials := globalServerConfig.GetCredential() - - testCases := []struct { - AccessKey string - SecretKey string - EnvKeysSet bool - ExpectedStatusCode int - }{ - // Bad secret key - {"minio", "minio", false, http.StatusBadRequest}, - // Bad secret key set from the env - {"minio", "minio", true, http.StatusMethodNotAllowed}, - // Good keys set from the env - {"minio", "minio123", true, http.StatusMethodNotAllowed}, - // Successful operation should be the last one to - // not change server credentials during tests. - {"minio", "minio123", false, http.StatusOK}, - } - for i, testCase := range testCases { - // Set or unset environement keys - globalIsEnvCreds = testCase.EnvKeysSet - - // Construct setCreds request body - body, err := json.Marshal(madmin.SetCredsReq{ - AccessKey: testCase.AccessKey, - SecretKey: testCase.SecretKey}) - if err != nil { - t.Fatalf("JSONify err: %v", err) - } - - ebody, err := madmin.EncryptData(credentials.SecretKey, body) - if err != nil { - t.Fatal(err) - } - - // Construct setCreds request - req, err := getServiceCmdRequest(setCreds, credentials, ebody) - if err != nil { - t.Fatalf("Failed to build service status request %v", err) - } - - rec := httptest.NewRecorder() - - // Execute request - adminTestBed.router.ServeHTTP(rec, req) - - // Check if the http code response is expected - if rec.Code != testCase.ExpectedStatusCode { - t.Errorf("Test %d: Wrong status code, expected = %d, found = %d", i+1, testCase.ExpectedStatusCode, rec.Code) - resp, _ := ioutil.ReadAll(rec.Body) - t.Errorf("Expected to receive %d status code but received %d. Body (%s)", - http.StatusOK, rec.Code, string(resp)) - } - - // If we got 200 OK, check if new credentials are really set - if rec.Code == http.StatusOK { - cred := globalServerConfig.GetCredential() - if cred.AccessKey != testCase.AccessKey { - t.Errorf("Test %d: Wrong access key, expected = %s, found = %s", i+1, testCase.AccessKey, cred.AccessKey) - } - if cred.SecretKey != testCase.SecretKey { - t.Errorf("Test %d: Wrong secret key, expected = %s, found = %s", i+1, testCase.SecretKey, cred.SecretKey) - } - } - } -} - // buildAdminRequest - helper function to build an admin API request. func buildAdminRequest(queryVal url.Values, method, path string, contentLength int64, bodySeeker io.ReadSeeker) (*http.Request, error) { diff --git a/cmd/admin-router.go b/cmd/admin-router.go index 7ed80556b..7c506172a 100644 --- a/cmd/admin-router.go +++ b/cmd/admin-router.go @@ -74,8 +74,6 @@ func registerAdminRouter(router *mux.Router, enableConfigOps, enableIAMOps bool) /// Config operations if enableConfigOps { - // Update credentials - adminV1Router.Methods(http.MethodPut).Path("/config/credential").HandlerFunc(httpTraceHdrs(adminAPI.UpdateAdminCredentialsHandler)) // Get config adminV1Router.Methods(http.MethodGet).Path("/config").HandlerFunc(httpTraceHdrs(adminAPI.GetConfigHandler)) // Set config diff --git a/pkg/madmin/API.md b/pkg/madmin/API.md deleted file mode 100644 index 6ec901c02..000000000 --- a/pkg/madmin/API.md +++ /dev/null @@ -1,549 +0,0 @@ -# Golang Admin Client API Reference [![Slack](https://slack.min.io/slack?type=svg)](https://slack.min.io) - -## Initialize MinIO Admin Client object. - -## MinIO - -```go - -package main - -import ( - "fmt" - - "github.com/minio/minio/pkg/madmin" -) - -func main() { - // Use a secure connection. - ssl := true - - // Initialize minio client object. - mdmClnt, err := madmin.New("your-minio.example.com:9000", "YOUR-ACCESSKEYID", "YOUR-SECRETKEY", ssl) - if err != nil { - fmt.Println(err) - return - } - - // Fetch service status. - st, err := mdmClnt.ServiceStatus() - if err != nil { - fmt.Println(err) - return - } - fmt.Printf("%#v\n", st) -} - -``` - -| Service operations | Info operations | Healing operations | Config operations | Top operations | IAM operations | Misc | -|:----------------------------|:----------------------------|:--------------------------------------|:--------------------------|:--------------------------|:------------------------------------|:------------------------------------| -| [`ServiceStatus`](#ServiceStatus) | [`ServerInfo`](#ServerInfo) | [`Heal`](#Heal) | [`GetConfig`](#GetConfig) | [`TopLocks`](#TopLocks) | [`AddUser`](#AddUser) | [`SetAdminCredentials`](#SetAdminCredentials) | -| [`ServiceSendAction`](#ServiceSendAction) | [`ServerCPULoadInfo`](#ServerCPULoadInfo) | | [`SetConfig`](#SetConfig) | | [`SetUserPolicy`](#SetUserPolicy) | [`StartProfiling`](#StartProfiling) | -| |[`ServerMemUsageInfo`](#ServerMemUsageInfo) | | [`GetConfigKeys`](#GetConfigKeys) | | [`ListUsers`](#ListUsers) | [`DownloadProfilingData`](#DownloadProfilingData) | -| | | | [`SetConfigKeys`](#SetConfigKeys) | | [`AddCannedPolicy`](#AddCannedPolicy) | | - - -## 1. Constructor - - -### New(endpoint string, accessKeyID string, secretAccessKey string, ssl bool) (*AdminClient, error) -Initializes a new admin client object. - -__Parameters__ - -|Param |Type |Description | -|:---|:---| :---| -|`endpoint` | _string_ |MinIO endpoint. | -|`accessKeyID` |_string_ | Access key for the object storage endpoint. | -|`secretAccessKey` | _string_ |Secret key for the object storage endpoint. | -|`ssl` | _bool_ | Set this value to 'true' to enable secure (HTTPS) access. | - -## 2. Admin API Version - - -### VersionInfo() (AdminAPIVersionInfo, error) -Fetch server's supported Administrative API version. - - __Example__ - -``` go - - info, err := madmClnt.VersionInfo() - if err != nil { - log.Fatalln(err) - } - log.Printf("%s\n", info.Version) - -``` - -## 3. Service operations - - -### ServiceStatus() (ServiceStatusMetadata, error) -Fetch service status, replies disk space used, backend type and total disks offline/online (applicable in distributed mode). - -| Param | Type | Description | -|---|---|---| -|`serviceStatus` | _ServiceStatusMetadata_ | Represents current server status info in following format: | - - -| Param | Type | Description | -|---|---|---| -|`st.ServerVersion.Version` | _string_ | Server version. | -|`st.ServerVersion.CommitID` | _string_ | Server commit id. | -|`st.Uptime` | _time.Duration_ | Server uptime duration in seconds. | - - __Example__ - - ```go - - st, err := madmClnt.ServiceStatus() - if err != nil { - log.Fatalln(err) - } - log.Printf("%#v\n", st) - - ``` - - -### ServiceSendAction(act ServiceActionValue) (error) -Sends a service action command to service - possible actions are restarting and stopping the server. - - __Example__ - - - ```go - // to restart - st, err := madmClnt.ServiceSendAction(ServiceActionValueRestart) - // or to stop - // st, err := madmClnt.ServiceSendAction(ServiceActionValueStop) - if err != nil { - log.Fatalln(err) - } - log.Printf("Success") - ``` - -## 4. Info operations - - -### ServerInfo() ([]ServerInfo, error) -Fetches information for all cluster nodes, such as server properties, storage information, network statistics, etc. - -| Param | Type | Description | -|---------------------------------|--------------------|--------------------------------------------------------------------| -| `si.Addr` | _string_ | Address of the server the following information is retrieved from. | -| `si.ConnStats` | _ServerConnStats_ | Connection statistics from the given server. | -| `si.HTTPStats` | _ServerHTTPStats_ | HTTP connection statistics from the given server. | -| `si.Properties` | _ServerProperties_ | Server properties such as region, notification targets. | -| `si.Data.StorageInfo.Used` | _int64_ | Used disk space. | -| `si.Data.StorageInfo.Total` | _int64_ | Total disk space. | -| `si.Data.StorageInfo.Available` | _int64_ | Available disk space. | -| `si.Data.StorageInfo.Backend` | _struct{}_ | Represents backend type embedded structure. | - -| Param | Type | Description | -|-----------------------------|-----------------|----------------------------------------------------| -| `ServerProperties.Uptime` | _time.Duration_ | Total duration in seconds since server is running. | -| `ServerProperties.Version` | _string_ | Current server version. | -| `ServerProperties.CommitID` | _string_ | Current server commitID. | -| `ServerProperties.Region` | _string_ | Configured server region. | -| `ServerProperties.SQSARN` | _[]string_ | List of notification target ARNs. | - -| Param | Type | Description | -|------------------------------------|----------|-------------------------------------| -| `ServerConnStats.TotalInputBytes` | _uint64_ | Total bytes received by the server. | -| `ServerConnStats.TotalOutputBytes` | _uint64_ | Total bytes sent by the server. | - -| Param | Type | Description | -|--------------------------------------|-------------------------|---------------------------------------------------------| -| `ServerHTTPStats.TotalHEADStats` | _ServerHTTPMethodStats_ | Total statistics regarding HEAD operations | -| `ServerHTTPStats.SuccessHEADStats` | _ServerHTTPMethodStats_ | Total statistics regarding successful HEAD operations | -| `ServerHTTPStats.TotalGETStats` | _ServerHTTPMethodStats_ | Total statistics regarding GET operations | -| `ServerHTTPStats.SuccessGETStats` | _ServerHTTPMethodStats_ | Total statistics regarding successful GET operations | -| `ServerHTTPStats.TotalPUTStats` | _ServerHTTPMethodStats_ | Total statistics regarding PUT operations | -| `ServerHTTPStats.SuccessPUTStats` | _ServerHTTPMethodStats_ | Total statistics regarding successful PUT operations | -| `ServerHTTPStats.TotalPOSTStats` | _ServerHTTPMethodStats_ | Total statistics regarding POST operations | -| `ServerHTTPStats.SuccessPOSTStats` | _ServerHTTPMethodStats_ | Total statistics regarding successful POST operations | -| `ServerHTTPStats.TotalDELETEStats` | _ServerHTTPMethodStats_ | Total statistics regarding DELETE operations | -| `ServerHTTPStats.SuccessDELETEStats` | _ServerHTTPMethodStats_ | Total statistics regarding successful DELETE operations | - - -| Param | Type | Description | -|-------------------------------------|----------|-------------------------------------------------| -| `ServerHTTPMethodStats.Count` | _uint64_ | Total number of operations. | -| `ServerHTTPMethodStats.AvgDuration` | _string_ | Average duration of Count number of operations. | - -| Param | Type | Description | -|----------------------------|-----------------|-----------------------------------------------------------------------------------| -| `Backend.Type` | _BackendType_ | Type of backend used by the server currently only FS or Erasure. | -| `Backend.OnlineDisks` | _int_ | Total number of disks online (only applies to Erasure backend), is empty for FS. | -| `Backend.OfflineDisks` | _int_ | Total number of disks offline (only applies to Erasure backend), is empty for FS. | -| `Backend.StandardSCData` | _int_ | Data disks set for standard storage class, is empty for FS. | -| `Backend.StandardSCParity` | _int_ | Parity disks set for standard storage class, is empty for FS. | -| `Backend.RRSCData` | _int_ | Data disks set for reduced redundancy storage class, is empty for FS. | -| `Backend.RRSCParity` | _int_ | Parity disks set for reduced redundancy storage class, is empty for FS. | -| `Backend.Sets` | _[][]DriveInfo_ | Represents topology of drives in erasure coded sets. | - -| Param | Type | Description | -|----------------------|----------|-------------------------------------------------------| -| `DriveInfo.UUID` | _string_ | Unique ID for each disk provisioned by server format. | -| `DriveInfo.Endpoint` | _string_ | Endpoint location of the remote/local disk. | -| `DriveInfo.State` | _string_ | Current state of the disk at endpoint. | - - __Example__ - - ```go - - serversInfo, err := madmClnt.ServerInfo() - if err != nil { - log.Fatalln(err) - } - - for _, peerInfo := range serversInfo { - log.Printf("Node: %s, Info: %v\n", peerInfo.Addr, peerInfo.Data) - } - - ``` - - -### ServerDrivesPerfInfo() ([]ServerDrivesPerfInfo, error) - -Fetches drive performance information for all cluster nodes. Returned value is in Bytes/s. - -| Param | Type | Description | -|---|---|---| -|`di.Addr` | _string_ | Address of the server the following information is retrieved from. | -|`di.Error` | _string _ | Errors (if any) encountered while reaching this node | -|`di.DrivesPerf` | _disk.Performance_ | Path of the drive mount on above server and read, write speed. | - -| Param | Type | Description | -|---|---|---| -|`disk.Performance.Path` | _string_ | Path of drive mount. | -|`disk.Performance.Error` | _string_ | Error (if any) encountered while accessing this drive. | -|`disk.Performance.WriteSpeed` | _float64_ | Write speed on above path in Bytes/s. | -|`disk.Performance.ReadSpeed` | _float64_ | Read speed on above path in Bytes/s. | - - -### ServerCPULoadInfo() ([]ServerCPULoadInfo, error) - -Fetches CPU utilization for all cluster nodes. Returned value is in Bytes. - -| Param | Type | Description | -|-------|------|-------------| -|`cpui.Addr` | _string_ | Address of the server the following information is retrieved from. | -|`cpui.Error` | _string_ | Errors (if any) encountered while reaching this node | -|`cpui.CPULoad` | _cpu.Load_ | The load on the CPU. | - -| Param | Type | Description | -|-------|------|-------------| -|`cpu.Load.Avg` | _float64_ | The average utilization of the CPU measured in a 200ms interval | -|`cpu.Load.Min` | _float64_ | The minimum utilization of the CPU measured in a 200ms interval | -|`cpu.Load.Max` | _float64_ | The maximum utilization of the CPU measured in a 200ms interval | -|`cpu.Load.Error` | _string_ | Error (if any) encountered while accesing the CPU info | - - -### ServerMemUsageInfo() ([]ServerMemUsageInfo, error) - -Fetches Mem utilization for all cluster nodes. Returned value is in Bytes. - -| Param | Type | Description | -|-------|------|-------------| -|`memi.Addr` | _string_ | Address of the server the following information is retrieved from. | -|`memi.Error` | _string_ | Errors (if any) encountered while reaching this node | -|`memi.MemUsage` | _mem.Usage_ | The utilitzation of Memory | - -| Param | Type | Description | -|-------|------|-------------| -|`mem.Usage.Mem` | _uint64_ | The total number of bytes obtained from the OS | -|`mem.Usage.Error` | _string_ | Error (if any) encountered while accesing the CPU info | - -## 6. Heal operations - - -### Heal(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 -traversal under the given path. `dryRun` does not mutate on-disk data, -but performs data validation. - -Two heal sequences on overlapping paths may not be initiated. - -The progress of a heal should be followed using the same API `Heal` -by providing the `clientToken` previously obtained from a `Heal` -API. The server accumulates results of the heal traversal and waits -for the client to receive and acknowledge them using the status -request by providing `clientToken`. - -__Example__ - -``` go - - opts := madmin.HealOpts{ - Recursive: true, - DryRun: false, - } - forceStart := false - forceStop := false - healPath, err := madmClnt.Heal("", "", opts, "", forceStart, forceStop) - if err != nil { - log.Fatalln(err) - } - log.Printf("Heal sequence started at %s", healPath) - -``` - -#### HealStartSuccess structure - -| Param | Type | Description | -|----|--------|--------| -| s.ClientToken | _string_ | A unique token for a successfully started heal operation, this token is used to request realtime progress of the heal operation. | -| s.ClientAddress | _string_ | Address of the client which initiated the heal operation, the client address has the form "host:port".| -| s.StartTime | _time.Time_ | Time when heal was initially started.| - -#### HealTaskStatus structure - -| Param | Type | Description | -|----|--------|--------| -| s.Summary | _string_ | Short status of heal sequence | -| s.FailureDetail | _string_ | Error message in case of heal sequence failure | -| s.HealSettings | _HealOpts_ | Contains the booleans set in the `HealStart` call | -| s.Items | _[]HealResultItem_ | Heal records for actions performed by server | - -#### HealResultItem structure - -| Param | Type | Description | -|------|-------|---------| -| ResultIndex | _int64_ | Index of the heal-result record | -| Type | _HealItemType_ | Represents kind of heal operation in the heal record | -| Bucket | _string_ | Bucket name | -| Object | _string_ | Object name | -| Detail | _string_ | Details about heal operation | -| DiskInfo.AvailableOn | _[]int_ | List of disks on which the healed entity is present and healthy | -| DiskInfo.HealedOn | _[]int_ | List of disks on which the healed entity was restored | - -## 7. Config operations - - -### GetConfig() ([]byte, error) -Get current `config.json` of a MinIO server. - -__Example__ - -``` go - configBytes, err := madmClnt.GetConfig() - if err != nil { - log.Fatalf("failed due to: %v", err) - } - - // Pretty-print config received as json. - var buf bytes.Buffer - err = json.Indent(buf, configBytes, "", "\t") - if err != nil { - log.Fatalf("failed due to: %v", err) - } - - log.Println("config received successfully: ", string(buf.Bytes())) -``` - - - -### SetConfig(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 { - log.Fatalf("failed due to: %v", err) - } - log.Println("SetConfig was successful") -``` - - -### GetConfigKeys(keys []string) ([]byte, error) -Get a json document which contains a set of keys and their values from config.json. - -__Example__ - -``` go - configBytes, err := madmClnt.GetConfigKeys([]string{"version", "notify.amqp.1"}) - if err != nil { - log.Fatalf("failed due to: %v", err) - } - - // Pretty-print config received as json. - var buf bytes.Buffer - err = json.Indent(buf, configBytes, "", "\t") - if err != nil { - log.Fatalf("failed due to: %v", err) - } - - log.Println("config received successfully: ", string(buf.Bytes())) -``` - - - -### SetConfigKeys(params map[string]string) error -Set a set of keys and values for MinIO server or distributed setup and restart the MinIO -server for the new configuration changes to take effect. - -__Example__ - -``` go - err := madmClnt.SetConfigKeys(map[string]string{"notify.webhook.1": "{\"enable\": true, \"endpoint\": \"http://example.com/api\"}"}) - if err != nil { - log.Fatalf("failed due to: %v", err) - } - - log.Println("New configuration successfully set") -``` - -## 8. Top operations - - -### TopLocks() (LockEntries, error) -Get the oldest locks from MinIO server. - -__Example__ - -``` go - locks, err := madmClnt.TopLocks() - if err != nil { - log.Fatalf("failed due to: %v", err) - } - - out, err := json.Marshal(locks) - if err != nil { - log.Fatalf("Marshal failed due to: %v", err) - } - - log.Println("TopLocks received successfully: ", string(out)) -``` - -## 9. IAM operations - - -### AddCannedPolicy(policyName string, policy string) 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": ""}]}` - - if err = madmClnt.AddCannedPolicy("get-only", policy); err != nil { - log.Fatalln(err) - } -``` - - -### AddUser(user string, secret string) error -Add a new user on a MinIO server. - -__Example__ - -``` go - if err = madmClnt.AddUser("newuser", "newstrongpassword"); err != nil { - log.Fatalln(err) - } -``` - - -### SetUserPolicy(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 { - log.Fatalln(err) - } -``` - - -### ListUsers() (map[string]UserInfo, error) -Lists all users on MinIO server. - -__Example__ - -``` go - users, err := madmClnt.ListUsers(); - if err != nil { - log.Fatalln(err) - } - for k, v := range users { - fmt.Printf("User %s Status %s\n", k, v.Status) - } -``` - -## 10. Misc operations - - -### SetAdminCredentials() error -Set new credentials of a MinIO setup. - -__Example__ - -``` go - err = madmClnt.SetAdminCredentials("YOUR-NEW-ACCESSKEY", "YOUR-NEW-SECRETKEY") - if err != nil { - log.Fatalln(err) - } - log.Println("New credentials successfully set.") - -``` - - -### StartProfiling(profiler string) error -Ask all nodes to start profiling using the specified profiler mode - -__Example__ - -``` go - startProfilingResults, err = madmClnt.StartProfiling("cpu") - if err != nil { - log.Fatalln(err) - } - for _, result := range startProfilingResults { - if !result.Success { - log.Printf("Unable to start profiling on node `%s`, reason = `%s`\n", result.NodeName, result.Error) - } else { - log.Printf("Profiling successfully started on node `%s`\n", result.NodeName) - } - } - -``` - - -### DownloadProfilingData() ([]byte, error) -Download profiling data of all nodes in a zip format. - -__Example__ - -``` go - profilingData, err := madmClnt.DownloadProfilingData() - if err != nil { - log.Fatalln(err) - } - - profilingFile, err := os.Create("/tmp/profiling-data.zip") - if err != nil { - log.Fatal(err) - } - - if _, err := io.Copy(profilingFile, profilingData); err != nil { - log.Fatal(err) - } - - if err := profilingFile.Close(); err != nil { - log.Fatal(err) - } - - if err := profilingData.Close(); err != nil { - log.Fatal(err) - } - - log.Println("Profiling data successfully downloaded.") -``` diff --git a/pkg/madmin/README.md b/pkg/madmin/README.md index a7d94852d..ae15c785f 100644 --- a/pkg/madmin/README.md +++ b/pkg/madmin/README.md @@ -1,120 +1,539 @@ -# MinIO Admin Library. [![Slack](https://slack.min.io/slack?type=svg)](https://slack.min.io) +# Golang Admin Client API Reference [![Slack](https://slack.min.io/slack?type=svg)](https://slack.min.io) The MinIO Admin Golang Client SDK provides APIs to manage MinIO services. This quickstart guide will show you how to install the MinIO Admin client SDK, connect to MinIO admin service, and provide a walkthrough of a simple file uploader. This document assumes that you have a working [Golang setup](https://docs.min.io/docs/how-to-install-golang). -## Download from GitHub - -```sh - -go get -u github.com/minio/minio/pkg/madmin - -``` - -## Initialize MinIO Admin Client - -You need four items to connect to MinIO admin services. - - -| Parameter | Description| -| :--- | :--- | -| endpoint | URL to object storage service. | -| accessKeyID | Access key is the user ID that uniquely identifies your account. | -| secretAccessKey | Secret key is the password to your account. | -| secure | Set this value to 'true' to enable secure (HTTPS) access. | +## Initialize MinIO Admin Client object. +## MinIO ```go package main import ( - "github.com/minio/minio/pkg/madmin" - "log" + "fmt" + + "github.com/minio/minio/pkg/madmin" ) func main() { - endpoint := "your-minio.example.com:9000" - accessKeyID := "YOUR-ACCESSKEYID" - secretAccessKey := "YOUR-SECRETKEY" - useSSL := true + // Use a secure connection. + ssl := true - // Initialize minio admin client object. - madmClnt, err := madmin.New(endpoint, accessKeyID, secretAccessKey, useSSL) - if err != nil { - log.Fatalln(err) - } + // Initialize minio client object. + mdmClnt, err := madmin.New("your-minio.example.com:9000", "YOUR-ACCESSKEYID", "YOUR-SECRETKEY", ssl) + if err != nil { + fmt.Println(err) + return + } - log.Println("%v", madmClnt) // MinIO admin client is now setup + // Fetch service status. + st, err := mdmClnt.ServiceStatus() + if err != nil { + fmt.Println(err) + return + } + fmt.Printf("%#v\n", st) } + ``` -## Quick Start Example - Server Info +| Service operations | Info operations | Healing operations | Config operations | Top operations | IAM operations | Misc | +|:------------------------------------------|:--------------------------------------------|:-------------------|:----------------------------------|:------------------------|:--------------------------------------|:--------------------------------------------------| +| [`ServiceStatus`](#ServiceStatus) | [`ServerInfo`](#ServerInfo) | [`Heal`](#Heal) | [`GetConfig`](#GetConfig) | [`TopLocks`](#TopLocks) | [`AddUser`](#AddUser) | | +| [`ServiceSendAction`](#ServiceSendAction) | [`ServerCPULoadInfo`](#ServerCPULoadInfo) | | [`SetConfig`](#SetConfig) | | [`SetUserPolicy`](#SetUserPolicy) | [`StartProfiling`](#StartProfiling) | +| | [`ServerMemUsageInfo`](#ServerMemUsageInfo) | | [`GetConfigKeys`](#GetConfigKeys) | | [`ListUsers`](#ListUsers) | [`DownloadProfilingData`](#DownloadProfilingData) | +| | | | [`SetConfigKeys`](#SetConfigKeys) | | [`AddCannedPolicy`](#AddCannedPolicy) | | -This example program connects to minio server, gets the current disk status and other useful server information. -#### ServiceStatus.go +## 1. Constructor + -```go -package main +### New(endpoint string, accessKeyID string, secretAccessKey string, ssl bool) (*AdminClient, error) +Initializes a new admin client object. -import ( - "encoding/json" - "fmt" - "log" +__Parameters__ - "github.com/minio/minio/pkg/madmin" -) +| Param | Type | Description | +|:------------------|:---------|:----------------------------------------------------------| +| `endpoint` | _string_ | MinIO endpoint. | +| `accessKeyID` | _string_ | Access key for the object storage endpoint. | +| `secretAccessKey` | _string_ | Secret key for the object storage endpoint. | +| `ssl` | _bool_ | Set this value to 'true' to enable secure (HTTPS) access. | -func main() { - endpoint := "your-minio.example.com:9000" - accessKeyID := "YOUR-ACCESSKEYID" - secretAccessKey := "YOUR-SECRETKEY" - useSSL := true +## 2. Admin API Version - // Initialize minio admin client. - mdmClnt, err := madmin.New(endpoint, accessKeyID, secretAccessKey, useSSL) + +### VersionInfo() (AdminAPIVersionInfo, error) +Fetch server's supported Administrative API version. + + __Example__ + +``` go + + info, err := madmClnt.VersionInfo() + if err != nil { + log.Fatalln(err) + } + log.Printf("%s\n", info.Version) + +``` + +## 3. Service operations + + +### ServiceStatus() (ServiceStatusMetadata, error) +Fetch service status, replies disk space used, backend type and total disks offline/online (applicable in distributed mode). + +| Param | Type | Description | +|-----------------|-------------------------|------------------------------------------------------------| +| `serviceStatus` | _ServiceStatusMetadata_ | Represents current server status info in following format: | + + +| Param | Type | Description | +|-----------------------------|-----------------|------------------------------------| +| `st.ServerVersion.Version` | _string_ | Server version. | +| `st.ServerVersion.CommitID` | _string_ | Server commit id. | +| `st.Uptime` | _time.Duration_ | Server uptime duration in seconds. | + + __Example__ + + ```go + + st, err := madmClnt.ServiceStatus() + if err != nil { + log.Fatalln(err) + } + log.Printf("%#v\n", st) + + ``` + + +### ServiceSendAction(act ServiceActionValue) (error) +Sends a service action command to service - possible actions are restarting and stopping the server. + + __Example__ + + + ```go + // to restart + st, err := madmClnt.ServiceSendAction(ServiceActionValueRestart) + // or to stop + // st, err := madmClnt.ServiceSendAction(ServiceActionValueStop) + if err != nil { + log.Fatalln(err) + } + log.Printf("Success") + ``` + +## 4. Info operations + + +### ServerInfo() ([]ServerInfo, error) +Fetches information for all cluster nodes, such as server properties, storage information, network statistics, etc. + +| Param | Type | Description | +|---------------------------------|--------------------|--------------------------------------------------------------------| +| `si.Addr` | _string_ | Address of the server the following information is retrieved from. | +| `si.ConnStats` | _ServerConnStats_ | Connection statistics from the given server. | +| `si.HTTPStats` | _ServerHTTPStats_ | HTTP connection statistics from the given server. | +| `si.Properties` | _ServerProperties_ | Server properties such as region, notification targets. | +| `si.Data.StorageInfo.Used` | _int64_ | Used disk space. | +| `si.Data.StorageInfo.Total` | _int64_ | Total disk space. | +| `si.Data.StorageInfo.Available` | _int64_ | Available disk space. | +| `si.Data.StorageInfo.Backend` | _struct{}_ | Represents backend type embedded structure. | + +| Param | Type | Description | +|-----------------------------|-----------------|----------------------------------------------------| +| `ServerProperties.Uptime` | _time.Duration_ | Total duration in seconds since server is running. | +| `ServerProperties.Version` | _string_ | Current server version. | +| `ServerProperties.CommitID` | _string_ | Current server commitID. | +| `ServerProperties.Region` | _string_ | Configured server region. | +| `ServerProperties.SQSARN` | _[]string_ | List of notification target ARNs. | + +| Param | Type | Description | +|------------------------------------|----------|-------------------------------------| +| `ServerConnStats.TotalInputBytes` | _uint64_ | Total bytes received by the server. | +| `ServerConnStats.TotalOutputBytes` | _uint64_ | Total bytes sent by the server. | + +| Param | Type | Description | +|--------------------------------------|-------------------------|---------------------------------------------------------| +| `ServerHTTPStats.TotalHEADStats` | _ServerHTTPMethodStats_ | Total statistics regarding HEAD operations | +| `ServerHTTPStats.SuccessHEADStats` | _ServerHTTPMethodStats_ | Total statistics regarding successful HEAD operations | +| `ServerHTTPStats.TotalGETStats` | _ServerHTTPMethodStats_ | Total statistics regarding GET operations | +| `ServerHTTPStats.SuccessGETStats` | _ServerHTTPMethodStats_ | Total statistics regarding successful GET operations | +| `ServerHTTPStats.TotalPUTStats` | _ServerHTTPMethodStats_ | Total statistics regarding PUT operations | +| `ServerHTTPStats.SuccessPUTStats` | _ServerHTTPMethodStats_ | Total statistics regarding successful PUT operations | +| `ServerHTTPStats.TotalPOSTStats` | _ServerHTTPMethodStats_ | Total statistics regarding POST operations | +| `ServerHTTPStats.SuccessPOSTStats` | _ServerHTTPMethodStats_ | Total statistics regarding successful POST operations | +| `ServerHTTPStats.TotalDELETEStats` | _ServerHTTPMethodStats_ | Total statistics regarding DELETE operations | +| `ServerHTTPStats.SuccessDELETEStats` | _ServerHTTPMethodStats_ | Total statistics regarding successful DELETE operations | + + +| Param | Type | Description | +|-------------------------------------|----------|-------------------------------------------------| +| `ServerHTTPMethodStats.Count` | _uint64_ | Total number of operations. | +| `ServerHTTPMethodStats.AvgDuration` | _string_ | Average duration of Count number of operations. | + +| Param | Type | Description | +|----------------------------|-----------------|-----------------------------------------------------------------------------------| +| `Backend.Type` | _BackendType_ | Type of backend used by the server currently only FS or Erasure. | +| `Backend.OnlineDisks` | _int_ | Total number of disks online (only applies to Erasure backend), is empty for FS. | +| `Backend.OfflineDisks` | _int_ | Total number of disks offline (only applies to Erasure backend), is empty for FS. | +| `Backend.StandardSCData` | _int_ | Data disks set for standard storage class, is empty for FS. | +| `Backend.StandardSCParity` | _int_ | Parity disks set for standard storage class, is empty for FS. | +| `Backend.RRSCData` | _int_ | Data disks set for reduced redundancy storage class, is empty for FS. | +| `Backend.RRSCParity` | _int_ | Parity disks set for reduced redundancy storage class, is empty for FS. | +| `Backend.Sets` | _[][]DriveInfo_ | Represents topology of drives in erasure coded sets. | + +| Param | Type | Description | +|----------------------|----------|-------------------------------------------------------| +| `DriveInfo.UUID` | _string_ | Unique ID for each disk provisioned by server format. | +| `DriveInfo.Endpoint` | _string_ | Endpoint location of the remote/local disk. | +| `DriveInfo.State` | _string_ | Current state of the disk at endpoint. | + + __Example__ + + ```go + + serversInfo, err := madmClnt.ServerInfo() if err != nil { log.Fatalln(err) } - si, err := mdmClnt.ServerInfo() - if err != nil { + for _, peerInfo := range serversInfo { + log.Printf("Node: %s, Info: %v\n", peerInfo.Addr, peerInfo.Data) + } + + ``` + + +### ServerDrivesPerfInfo() ([]ServerDrivesPerfInfo, error) + +Fetches drive performance information for all cluster nodes. Returned value is in Bytes/s. + +| Param | Type | Description | +|-----------------|--------------------|--------------------------------------------------------------------| +| `di.Addr` | _string_ | Address of the server the following information is retrieved from. | +| `di.Error` | _string_ | Errors (if any) encountered while reaching this node | +| `di.DrivesPerf` | _disk.Performance_ | Path of the drive mount on above server and read, write speed. | + +| Param | Type | Description | +|-------------------------------|-----------|--------------------------------------------------------| +| `disk.Performance.Path` | _string_ | Path of drive mount. | +| `disk.Performance.Error` | _string_ | Error (if any) encountered while accessing this drive. | +| `disk.Performance.WriteSpeed` | _float64_ | Write speed on above path in Bytes/s. | +| `disk.Performance.ReadSpeed` | _float64_ | Read speed on above path in Bytes/s. | + + +### ServerCPULoadInfo() ([]ServerCPULoadInfo, error) + +Fetches CPU utilization for all cluster nodes. Returned value is in Bytes. + +| Param | Type | Description | +|----------------|------------|---------------------------------------------------------------------| +| `cpui.Addr` | _string_ | Address of the server the following information is retrieved from. | +| `cpui.Error` | _string_ | Errors (if any) encountered while reaching this node | +| `cpui.CPULoad` | _cpu.Load_ | The load on the CPU. | + +| Param | Type | Description | +|------------------|-----------|-----------------------------------------------------------------| +| `cpu.Load.Avg` | _float64_ | The average utilization of the CPU measured in a 200ms interval | +| `cpu.Load.Min` | _float64_ | The minimum utilization of the CPU measured in a 200ms interval | +| `cpu.Load.Max` | _float64_ | The maximum utilization of the CPU measured in a 200ms interval | +| `cpu.Load.Error` | _string_ | Error (if any) encountered while accesing the CPU info | + + +### ServerMemUsageInfo() ([]ServerMemUsageInfo, error) + +Fetches Mem utilization for all cluster nodes. Returned value is in Bytes. + +| Param | Type | Description | +|-----------------|-------------|---------------------------------------------------------------------| +| `memi.Addr` | _string_ | Address of the server the following information is retrieved from. | +| `memi.Error` | _string_ | Errors (if any) encountered while reaching this node | +| `memi.MemUsage` | _mem.Usage_ | The utilitzation of Memory | + +| Param | Type | Description | +|-------------------|----------|--------------------------------------------------------| +| `mem.Usage.Mem` | _uint64_ | The total number of bytes obtained from the OS | +| `mem.Usage.Error` | _string_ | Error (if any) encountered while accesing the CPU info | + +## 6. Heal operations + + +### Heal(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 +traversal under the given path. `dryRun` does not mutate on-disk data, +but performs data validation. + +Two heal sequences on overlapping paths may not be initiated. + +The progress of a heal should be followed using the same API `Heal` +by providing the `clientToken` previously obtained from a `Heal` +API. The server accumulates results of the heal traversal and waits +for the client to receive and acknowledge them using the status +request by providing `clientToken`. + +__Example__ + +``` go + + opts := madmin.HealOpts{ + Recursive: true, + DryRun: false, + } + forceStart := false + forceStop := false + healPath, err := madmClnt.Heal("", "", opts, "", forceStart, forceStop) + if err != nil { + log.Fatalln(err) + } + log.Printf("Heal sequence started at %s", healPath) + +``` + +#### HealStartSuccess structure + +| Param | Type | Description | +|-------------------|-------------|----------------------------------------------------------------------------------------------------------------------------------| +| `s.ClientToken` | _string_ | A unique token for a successfully started heal operation, this token is used to request realtime progress of the heal operation. | +| `s.ClientAddress` | _string_ | Address of the client which initiated the heal operation, the client address has the form "host:port". | +| `s.StartTime` | _time.Time_ | Time when heal was initially started. | + +#### HealTaskStatus structure + +| Param | Type | Description | +|-------------------|--------------------|---------------------------------------------------| +| `s.Summary` | _string_ | Short status of heal sequence | +| `s.FailureDetail` | _string_ | Error message in case of heal sequence failure | +| `s.HealSettings` | _HealOpts_ | Contains the booleans set in the `HealStart` call | +| `s.Items` | _[]HealResultItem_ | Heal records for actions performed by server | + +#### HealResultItem structure + +| Param | Type | Description | +|------------------------|----------------|-----------------------------------------------------------------| +| `ResultIndex` | _int64_ | Index of the heal-result record | +| `Type` | _HealItemType_ | Represents kind of heal operation in the heal record | +| `Bucket` | _string_ | Bucket name | +| `Object` | _string_ | Object name | +| `Detail` | _string_ | Details about heal operation | +| `DiskInfo.AvailableOn` | _[]int_ | List of disks on which the healed entity is present and healthy | +| `DiskInfo.HealedOn` | _[]int_ | List of disks on which the healed entity was restored | + +## 7. Config operations + + +### GetConfig() ([]byte, error) +Get current `config.json` of a MinIO server. + +__Example__ + +``` go + configBytes, err := madmClnt.GetConfig() + if err != nil { + log.Fatalf("failed due to: %v", err) + } + + // Pretty-print config received as json. + var buf bytes.Buffer + err = json.Indent(buf, configBytes, "", "\t") + if err != nil { + log.Fatalf("failed due to: %v", err) + } + + log.Println("config received successfully: ", string(buf.Bytes())) +``` + + + +### SetConfig(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 { + log.Fatalf("failed due to: %v", err) + } + log.Println("SetConfig was successful") +``` + + +### GetConfigKeys(keys []string) ([]byte, error) +Get a json document which contains a set of keys and their values from config.json. + +__Example__ + +``` go + configBytes, err := madmClnt.GetConfigKeys([]string{"version", "notify.amqp.1"}) + if err != nil { + log.Fatalf("failed due to: %v", err) + } + + // Pretty-print config received as json. + var buf bytes.Buffer + err = json.Indent(buf, configBytes, "", "\t") + if err != nil { + log.Fatalf("failed due to: %v", err) + } + + log.Println("config received successfully: ", string(buf.Bytes())) +``` + + + +### SetConfigKeys(params map[string]string) error +Set a set of keys and values for MinIO server or distributed setup and restart the MinIO +server for the new configuration changes to take effect. + +__Example__ + +``` go + err := madmClnt.SetConfigKeys(map[string]string{"notify.webhook.1": "{\"enable\": true, \"endpoint\": \"http://example.com/api\"}"}) + if err != nil { + log.Fatalf("failed due to: %v", err) + } + + log.Println("New configuration successfully set") +``` + +## 8. Top operations + + +### TopLocks() (LockEntries, error) +Get the oldest locks from MinIO server. + +__Example__ + +``` go + locks, err := madmClnt.TopLocks() + if err != nil { + log.Fatalf("failed due to: %v", err) + } + + out, err := json.Marshal(locks) + if err != nil { + log.Fatalf("Marshal failed due to: %v", err) + } + + log.Println("TopLocks received successfully: ", string(out)) +``` + +## 9. IAM operations + + +### AddCannedPolicy(policyName string, policy string) 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": ""}]}` + + if err = madmClnt.AddCannedPolicy("get-only", policy); err != nil { log.Fatalln(err) } - b, err := json.Marshal(si) - fmt.Printf("%s\n", string(b)) -} ``` -Replace the endpoint and access credentials above according to an actual setup. + +### AddUser(user string, secret string) error +Add a new user on a MinIO server. -#### Run ServiceStatus +__Example__ -The sample output below shows the result of executing the above program against a locally hosted server. - -```sh -[{"error":"","addr":"localhost:9000","data":{"storage":{"Total":460373336064,"Free":77001187328,"Backend":{"Type":2,"OnlineDisks":4,"OfflineDisks":0,"StandardSCParity":2,"RRSCParity":2}},"network":{"transferred":30599,"received":36370},"http":{"totalHEADs":{"count":0,"avgDuration":"0s"},"successHEADs":{"count":0,"avgDuration":"0s"},"totalGETs":{"count":11,"avgDuration":"0s"},"successGETs":{"count":11,"avgDuration":"0s"},"totalPUTs":{"count":0,"avgDuration":"0s"},"successPUTs":{"count":0,"avgDuration":"0s"},"totalPOSTs":{"count":0,"avgDuration":"0s"},"successPOSTs":{"count":0,"avgDuration":"0s"},"totalDELETEs":{"count":0,"avgDuration":"0s"},"successDELETEs":{"count":0,"avgDuration":"0s"}},"server":{"uptime":596915001694,"version":"2018-01-18T20:33:21Z","commitID":"e2d5a87b2676e3e01f0f4fa7ebd01205364cfb16","region":"us-east-1","sqsARN":null}}},{"error":"","addr":"minio2:9000","data":{"storage":{"Total":460373336064,"Free":77001187328,"Backend":{"Type":2,"OnlineDisks":4,"OfflineDisks":0,"StandardSCParity":2,"RRSCParity":2}},"network":{"transferred":28538,"received":11845},"http":{"totalHEADs":{"count":0,"avgDuration":"0s"},"successHEADs":{"count":0,"avgDuration":"0s"},"totalGETs":{"count":0,"avgDuration":"0s"},"successGETs":{"count":0,"avgDuration":"0s"},"totalPUTs":{"count":0,"avgDuration":"0s"},"successPUTs":{"count":0,"avgDuration":"0s"},"totalPOSTs":{"count":0,"avgDuration":"0s"},"successPOSTs":{"count":0,"avgDuration":"0s"},"totalDELETEs":{"count":0,"avgDuration":"0s"},"successDELETEs":{"count":0,"avgDuration":"0s"}},"server":{"uptime":595852367296,"version":"2018-01-18T20:33:21Z","commitID":"e2d5a87b2676e3e01f0f4fa7ebd01205364cfb16","region":"us-east-1","sqsARN":null}}},{"error":"","addr":"minio3:9000","data":{"storage":{"Total":460373336064,"Free":77001187328,"Backend":{"Type":2,"OnlineDisks":4,"OfflineDisks":0,"StandardSCParity":2,"RRSCParity":2}},"network":{"transferred":27624,"received":11708},"http":{"totalHEADs":{"count":0,"avgDuration":"0s"},"successHEADs":{"count":0,"avgDuration":"0s"},"totalGETs":{"count":0,"avgDuration":"0s"},"successGETs":{"count":0,"avgDuration":"0s"},"totalPUTs":{"count":0,"avgDuration":"0s"},"successPUTs":{"count":0,"avgDuration":"0s"},"totalPOSTs":{"count":0,"avgDuration":"0s"},"successPOSTs":{"count":0,"avgDuration":"0s"},"totalDELETEs":{"count":0,"avgDuration":"0s"},"successDELETEs":{"count":0,"avgDuration":"0s"}},"server":{"uptime":595831126778,"version":"2018-01-18T20:33:21Z","commitID":"e2d5a87b2676e3e01f0f4fa7ebd01205364cfb16","region":"us-east-1","sqsARN":null}}},{"error":"","addr":"minio4:9000","data":{"storage":{"Total":460373336064,"Free":77001187328,"Backend":{"Type":2,"OnlineDisks":4,"OfflineDisks":0,"StandardSCParity":2,"RRSCParity":2}},"network":{"transferred":27740,"received":12116},"http":{"totalHEADs":{"count":0,"avgDuration":"0s"},"successHEADs":{"count":0,"avgDuration":"0s"},"totalGETs":{"count":0,"avgDuration":"0s"},"successGETs":{"count":0,"avgDuration":"0s"},"totalPUTs":{"count":0,"avgDuration":"0s"},"successPUTs":{"count":0,"avgDuration":"0s"},"totalPOSTs":{"count":0,"avgDuration":"0s"},"successPOSTs":{"count":0,"avgDuration":"0s"},"totalDELETEs":{"count":0,"avgDuration":"0s"},"successDELETEs":{"count":0,"avgDuration":"0s"}},"server":{"uptime":595349958375,"version":"2018-01-18T20:33:21Z","commitID":"e2d5a87b2676e3e01f0f4fa7ebd01205364cfb16","region":"us-east-1","sqsARN":null}}}] +``` go + if err = madmClnt.AddUser("newuser", "newstrongpassword"); err != nil { + log.Fatalln(err) + } ``` -## API Reference + +### SetUserPolicy(user string, policyName string) error +Enable a canned policy `get-only` for a given user on MinIO server. -### API Reference : Service Operations +__Example__ -* [`ServiceStatus`](./API.md#ServiceStatus) -* [`ServiceRestart`](./API.md#ServiceRestart) -* [`ServiceSetCredentials`](./API.md#ServiceSetCredentials) +``` go + if err = madmClnt.SetUserPolicy("newuser", "get-only"); err != nil { + log.Fatalln(err) + } +``` -## Full Examples + +### ListUsers() (map[string]UserInfo, error) +Lists all users on MinIO server. -#### Full Examples : Service Operations +__Example__ -* [service-status.go](https://github.com/minio/minio/blob/master/pkg/madmin/examples/service-status.go) -* [service-restart.go](https://github.com/minio/minio/blob/master/pkg/madmin/examples/service-restart.go) -* [set-credentials.go](https://github.com/minio/minio/blob/master/pkg/madmin/examples/set-credentials.go) +``` go + users, err := madmClnt.ListUsers(); + if err != nil { + log.Fatalln(err) + } + for k, v := range users { + fmt.Printf("User %s Status %s\n", k, v.Status) + } +``` -## Contribute +## 10. Misc operations -[Contributors Guide](https://github.com/minio/minio/blob/master/CONTRIBUTING.md) + +### StartProfiling(profiler string) error +Ask all nodes to start profiling using the specified profiler mode + +__Example__ + +``` go + startProfilingResults, err = madmClnt.StartProfiling("cpu") + if err != nil { + log.Fatalln(err) + } + for _, result := range startProfilingResults { + if !result.Success { + log.Printf("Unable to start profiling on node `%s`, reason = `%s`\n", result.NodeName, result.Error) + } else { + log.Printf("Profiling successfully started on node `%s`\n", result.NodeName) + } + } + +``` + + +### DownloadProfilingData() ([]byte, error) +Download profiling data of all nodes in a zip format. + +__Example__ + +``` go + profilingData, err := madmClnt.DownloadProfilingData() + if err != nil { + log.Fatalln(err) + } + + profilingFile, err := os.Create("/tmp/profiling-data.zip") + if err != nil { + log.Fatal(err) + } + + if _, err := io.Copy(profilingFile, profilingData); err != nil { + log.Fatal(err) + } + + if err := profilingFile.Close(); err != nil { + log.Fatal(err) + } + + if err := profilingData.Close(); err != nil { + log.Fatal(err) + } + + log.Println("Profiling data successfully downloaded.") +``` diff --git a/pkg/madmin/examples/set-credentials.go b/pkg/madmin/examples/set-credentials.go deleted file mode 100644 index d4270f344..000000000 --- a/pkg/madmin/examples/set-credentials.go +++ /dev/null @@ -1,44 +0,0 @@ -// +build ignore - -/* - * MinIO Cloud Storage, (C) 2016 MinIO, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package main - -import ( - "log" - - "github.com/minio/minio/pkg/madmin" -) - -func main() { - // Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY and my-bucketname are - // dummy values, please replace them with original values. - - // API requests are secure (HTTPS) if secure=true and insecure (HTTPS) otherwise. - // New returns an MinIO Admin client object. - madmClnt, err := madmin.New("your-minio.example.com:9000", "YOUR-ACCESSKEYID", "YOUR-SECRETACCESSKEY", true) - if err != nil { - log.Fatalln(err) - } - - err = madmClnt.SetAdminCredentials("YOUR-NEW-ACCESSKEY", "YOUR-NEW-SECRETKEY") - if err != nil { - log.Fatalln(err) - } - log.Println("New credentials successfully set.") -} diff --git a/pkg/madmin/generic-commands.go b/pkg/madmin/generic-commands.go deleted file mode 100644 index fc1204d2e..000000000 --- a/pkg/madmin/generic-commands.go +++ /dev/null @@ -1,66 +0,0 @@ -/* - * MinIO Cloud Storage, (C) 2016, 2017 MinIO, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package madmin - -import ( - "encoding/json" - "net/http" -) - -// SetCredsReq - xml to send to the server to set new credentials -type SetCredsReq struct { - AccessKey string `json:"accessKey"` - SecretKey string `json:"secretKey"` -} - -// SetAdminCredentials - Call Set Credentials API to set new access and -// secret keys in the specified MinIO server -func (adm *AdminClient) SetAdminCredentials(access, secret string) error { - // Setup request's body - body, err := json.Marshal(SetCredsReq{access, secret}) - if err != nil { - return err - } - - ebody, err := EncryptData(adm.secretAccessKey, body) - if err != nil { - return err - } - - // Setup new request - reqData := requestData{ - relPath: "/v1/config/credential", - content: ebody, - } - - // Execute GET on bucket to list objects. - resp, err := adm.executeMethod("PUT", reqData) - - defer closeResponse(resp) - if err != nil { - return err - } - - // Return error to the caller if http response code is - // different from 200 - if resp.StatusCode != http.StatusOK { - return httpRespToErrorResponse(resp) - } - - return nil -}