diff --git a/cmd/admin-handlers.go b/cmd/admin-handlers.go
index 84a20c1c6..97b341ed0 100644
--- a/cmd/admin-handlers.go
+++ b/cmd/admin-handlers.go
@@ -17,12 +17,9 @@
package cmd
import (
- "bytes"
"context"
"crypto/subtle"
- "encoding/base64"
"encoding/json"
- "errors"
"fmt"
"io"
"io/ioutil"
@@ -38,8 +35,6 @@ import (
humanize "github.com/dustin/go-humanize"
"github.com/gorilla/mux"
- "github.com/tidwall/gjson"
- "github.com/tidwall/sjson"
"github.com/minio/minio/cmd/crypto"
xhttp "github.com/minio/minio/cmd/http"
@@ -952,25 +947,6 @@ func (a adminAPIHandlers) GetConfigHandler(w http.ResponseWriter, r *http.Reques
writeSuccessResponseJSON(w, econfigData)
}
-// Disable tidwall json array notation in JSON key path so
-// users can set json with a key as a number.
-// In tidwall json, notify.webhook.0 = val means { "notify" : { "webhook" : [val] }}
-// In MinIO, notify.webhook.0 = val means { "notify" : { "webhook" : {"0" : val}}}
-func normalizeJSONKey(input string) (key string) {
- subKeys := strings.Split(input, ".")
- for i, k := range subKeys {
- if i > 0 {
- key += "."
- }
- if _, err := strconv.Atoi(k); err == nil {
- key += ":" + k
- } else {
- key += k
- }
- }
- return
-}
-
func validateAdminReq(ctx context.Context, w http.ResponseWriter, r *http.Request) ObjectLayer {
// Get current object layer instance.
objectAPI := newObjectLayerFn()
@@ -989,60 +965,6 @@ func validateAdminReq(ctx context.Context, w http.ResponseWriter, r *http.Reques
return objectAPI
}
-// GetConfigHandler - GET /minio/admin/v1/config-keys
-// Get some keys in config.json of this minio setup.
-func (a adminAPIHandlers) GetConfigKeysHandler(w http.ResponseWriter, r *http.Request) {
- ctx := newContext(r, w, "GetConfigKeysHandler")
-
- objectAPI := validateAdminReq(ctx, w, r)
- if objectAPI == nil {
- return
- }
-
- var keys []string
- queries := r.URL.Query()
-
- for k := range queries {
- keys = append(keys, k)
- }
-
- config, err := readServerConfig(ctx, objectAPI)
- if err != nil {
- writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
- return
- }
-
- configData, err := json.Marshal(config)
- if err != nil {
- writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
- return
- }
-
- configStr := string(configData)
- newConfigStr := `{}`
-
- for _, key := range keys {
- // sjson.Set does not return an error if key is empty
- // we should check by ourselves here
- if key == "" {
- continue
- }
- val := gjson.Get(configStr, key)
- if j, ierr := sjson.Set(newConfigStr, normalizeJSONKey(key), val.Value()); ierr == nil {
- newConfigStr = j
- }
- }
-
- password := config.GetCredential().SecretKey
- econfigData, err := madmin.EncryptData(password, []byte(newConfigStr))
- if err != nil {
- writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
- return
- }
-
- writeSuccessResponseJSON(w, []byte(econfigData))
-}
-
// AdminError - is a generic error for all admin APIs.
type AdminError struct {
Code string
@@ -1624,130 +1546,6 @@ func (a adminAPIHandlers) SetConfigHandler(w http.ResponseWriter, r *http.Reques
writeSuccessResponseHeadersOnly(w)
}
-func convertValueType(elem []byte, jsonType gjson.Type) (interface{}, error) {
- str := string(elem)
- switch jsonType {
- case gjson.False, gjson.True:
- return strconv.ParseBool(str)
- case gjson.JSON:
- if gjson.Valid(str) {
- return gjson.Parse(str).Value(), nil
- }
- return nil, errors.New("invalid json")
- case gjson.String:
- return str, nil
- case gjson.Number:
- return strconv.ParseFloat(str, 64)
- default:
- return nil, nil
- }
-}
-
-// SetConfigKeysHandler - PUT /minio/admin/v1/config-keys
-func (a adminAPIHandlers) SetConfigKeysHandler(w http.ResponseWriter, r *http.Request) {
- ctx := newContext(r, w, "SetConfigKeysHandler")
-
- objectAPI := validateAdminReq(ctx, w, r)
- if objectAPI == nil {
- return
- }
-
- // Deny if WORM is enabled
- if globalWORMEnabled {
- writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL)
- return
- }
-
- // Load config
- configStruct, err := readServerConfig(ctx, objectAPI)
- if err != nil {
- writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
- return
- }
-
- // Convert config to json bytes
- configBytes, err := json.Marshal(configStruct)
- if err != nil {
- writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
- return
- }
-
- configStr := string(configBytes)
-
- queries := r.URL.Query()
- password := globalServerConfig.GetCredential().SecretKey
-
- // Set key values in the JSON config
- for k := range queries {
- // Decode encrypted data associated to the current key
- encryptedElem, dErr := base64.StdEncoding.DecodeString(queries.Get(k))
- if dErr != nil {
- reqInfo := (&logger.ReqInfo{}).AppendTags("key", k)
- ctx = logger.SetReqInfo(ctx, reqInfo)
- logger.LogIf(ctx, dErr)
- writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), dErr.Error(), r.URL)
- return
- }
-
- elem, dErr := madmin.DecryptData(password, bytes.NewBuffer([]byte(encryptedElem)))
- if dErr != nil {
- logger.LogIf(ctx, dErr)
- writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), dErr.Error(), r.URL)
- return
- }
-
- // Calculate the type of the current key from the
- // original config json
- jsonFieldType := gjson.Get(configStr, k).Type
- // Convert passed value to json filed type
- val, cErr := convertValueType(elem, jsonFieldType)
- if cErr != nil {
- writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), cErr.Error(), r.URL)
- return
- }
- // Set the key/value in the new json document
- if s, sErr := sjson.Set(configStr, normalizeJSONKey(k), val); sErr == nil {
- configStr = s
- }
- }
-
- configBytes = []byte(configStr)
-
- // Validate config
- var config serverConfig
- if err = json.Unmarshal(configBytes, &config); err != nil {
- writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), err.Error(), r.URL)
- return
- }
-
- if err = config.Validate(); err != nil {
- writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), err.Error(), r.URL)
- return
- }
-
- if err = config.TestNotificationTargets(); err != nil {
- writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), err.Error(), r.URL)
- return
- }
-
- // If credentials for the server are provided via environment,
- // then credentials in the provided configuration must match.
- if globalIsEnvCreds {
- if !globalServerConfig.GetCredential().Equal(config.Credential) {
- writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminCredentialsMismatch), r.URL)
- return
- }
- }
-
- if err = saveServerConfig(ctx, objectAPI, &config); err != nil {
- writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
- return
- }
-
- // Send success response
- writeSuccessResponseHeadersOnly(w)
-}
-
// Returns true if the trace.Info should be traced,
// false if certain conditions are not met.
// - input entry is not of the type *trace.Info*
diff --git a/cmd/admin-handlers_test.go b/cmd/admin-handlers_test.go
index 531d9503a..82eaa9d7f 100644
--- a/cmd/admin-handlers_test.go
+++ b/cmd/admin-handlers_test.go
@@ -25,7 +25,6 @@ import (
"net/http"
"net/http/httptest"
"net/url"
- "reflect"
"strings"
"sync"
"testing"
@@ -34,7 +33,6 @@ import (
"github.com/gorilla/mux"
"github.com/minio/minio/pkg/auth"
"github.com/minio/minio/pkg/madmin"
- "github.com/tidwall/gjson"
)
var (
@@ -750,52 +748,3 @@ func TestExtractHealInitParams(t *testing.T) {
}
}
-
-func TestNormalizeJSONKey(t *testing.T) {
- cases := []struct {
- input string
- correctResult string
- }{
- {"notify.webhook.1", "notify.webhook.:1"},
- {"notify.webhook.ok", "notify.webhook.ok"},
- {"notify.webhook.1.2", "notify.webhook.:1.:2"},
- {"abc", "abc"},
- }
- for i, tcase := range cases {
- res := normalizeJSONKey(tcase.input)
- if res != tcase.correctResult {
- t.Errorf("Case %d: failed to match", i)
- }
- }
-}
-
-func TestConvertValueType(t *testing.T) {
- cases := []struct {
- elem []byte
- jt gjson.Type
- correctResult interface{}
- isError bool
- }{
- {[]byte(""), gjson.Null, nil, false},
- {[]byte("t"), gjson.False, true, false},
- {[]byte("f"), gjson.False, false, false},
- {[]byte(`{"a": 1}`), gjson.JSON, map[string]interface{}{"a": float64(1)}, false},
- {[]byte(`abc`), gjson.String, "abc", false},
- {[]byte(`1`), gjson.Number, float64(1), false},
- {[]byte(`a1`), gjson.Number, nil, true},
- {[]byte(`{"A": `), gjson.JSON, nil, true},
- {[]byte(`2`), gjson.False, nil, true},
- }
- for i, tc := range cases {
- res, err := convertValueType(tc.elem, tc.jt)
- if err != nil {
- if !tc.isError {
- t.Errorf("Case %d: got an error when none was expected", i)
- }
- } else if err == nil && tc.isError {
- t.Errorf("Case %d: got no error though we expected one", i)
- } else if !reflect.DeepEqual(res, tc.correctResult) {
- t.Errorf("Case %d: result mismatch - got %#v", i, res)
- }
- }
-}
diff --git a/cmd/admin-router.go b/cmd/admin-router.go
index 47bdd61a6..59a585e9b 100644
--- a/cmd/admin-router.go
+++ b/cmd/admin-router.go
@@ -77,11 +77,6 @@ func registerAdminRouter(router *mux.Router, enableConfigOps, enableIAMOps bool)
adminV1Router.Methods(http.MethodGet).Path("/config").HandlerFunc(httpTraceHdrs(adminAPI.GetConfigHandler))
// Set config
adminV1Router.Methods(http.MethodPut).Path("/config").HandlerFunc(httpTraceHdrs(adminAPI.SetConfigHandler))
-
- // Get config keys/values
- adminV1Router.Methods(http.MethodGet).Path("/config-keys").HandlerFunc(httpTraceHdrs(adminAPI.GetConfigKeysHandler))
- // Set config keys/values
- adminV1Router.Methods(http.MethodPut).Path("/config-keys").HandlerFunc(httpTraceHdrs(adminAPI.SetConfigKeysHandler))
}
if enableIAMOps {
diff --git a/pkg/madmin/README.md b/pkg/madmin/README.md
index d1a38e7c3..57d59b187 100644
--- a/pkg/madmin/README.md
+++ b/pkg/madmin/README.md
@@ -42,14 +42,14 @@ func main() {
}
```
-| Service operations | Info operations | Healing operations | Config operations | Top operations | IAM operations | Misc | KMS |
-|:------------------------------------|:------------------------------------------------|:-------------------|:----------------------------------|:------------------------|:--------------------------------------|:--------------------------------------------------|:----------------------------------|
-| [`ServiceRestart`](#ServiceRestart) | [`ServerInfo`](#ServerInfo) | [`Heal`](#Heal) | [`GetConfig`](#GetConfig) | [`TopLocks`](#TopLocks) | [`AddUser`](#AddUser) | | [`GetKeyStatus`](#GetKeyStatus) |
-| [`ServiceStop`](#ServiceStop) | [`ServerCPULoadInfo`](#ServerCPULoadInfo) | | [`SetConfig`](#SetConfig) | | [`SetUserPolicy`](#SetUserPolicy) | [`StartProfiling`](#StartProfiling) | |
-| | [`ServerMemUsageInfo`](#ServerMemUsageInfo) | | [`GetConfigKeys`](#GetConfigKeys) | | [`ListUsers`](#ListUsers) | [`DownloadProfilingData`](#DownloadProfilingData) | |
-| [`ServiceTrace`](#ServiceTrace) | [`ServerDrivesPerfInfo`](#ServerDrivesPerfInfo) | | [`SetConfigKeys`](#SetConfigKeys) | | [`AddCannedPolicy`](#AddCannedPolicy) | [`ServerUpdate`](#ServerUpdate) | |
-| | [`NetPerfInfo`](#NetPerfInfo) | | | | | | |
-
+| Service operations | Info operations | Healing operations | Config operations | Top operations | IAM operations | Misc | KMS |
+|:------------------------------------|:------------------------------------------------|:-------------------|:--------------------------|:------------------------|:--------------------------------------|:--------------------------------------------------|:--------------------------------|
+| [`ServiceRestart`](#ServiceRestart) | [`ServerInfo`](#ServerInfo) | [`Heal`](#Heal) | [`GetConfig`](#GetConfig) | [`TopLocks`](#TopLocks) | [`AddUser`](#AddUser) | | [`GetKeyStatus`](#GetKeyStatus) |
+| [`ServiceStop`](#ServiceStop) | [`ServerCPULoadInfo`](#ServerCPULoadInfo) | | [`SetConfig`](#SetConfig) | | [`SetUserPolicy`](#SetUserPolicy) | [`StartProfiling`](#StartProfiling) | |
+| | [`ServerMemUsageInfo`](#ServerMemUsageInfo) | | | | [`ListUsers`](#ListUsers) | [`DownloadProfilingData`](#DownloadProfilingData) | |
+| [`ServiceTrace`](#ServiceTrace) | [`ServerDrivesPerfInfo`](#ServerDrivesPerfInfo) | | | | [`AddCannedPolicy`](#AddCannedPolicy) | [`ServerUpdate`](#ServerUpdate) | |
+| | [`NetPerfInfo`](#NetPerfInfo) | | | | | | |
+
## 1. Constructor
@@ -390,45 +390,6 @@ __Example__
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")
-```
-
## 7. Top operations
@@ -582,7 +543,7 @@ __Example__
## 11. KMS
-
+
### GetKeyStatus(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
diff --git a/pkg/madmin/config-commands.go b/pkg/madmin/config-commands.go
index e06208877..5e75ad51d 100644
--- a/pkg/madmin/config-commands.go
+++ b/pkg/madmin/config-commands.go
@@ -19,12 +19,10 @@ package madmin
import (
"bytes"
- "encoding/base64"
"encoding/json"
"errors"
"io"
"net/http"
- "net/url"
"github.com/minio/minio/pkg/quick"
)
@@ -47,31 +45,6 @@ func (adm *AdminClient) GetConfig() ([]byte, error) {
return DecryptData(adm.secretAccessKey, resp.Body)
}
-// GetConfigKeys - returns partial json or json value from config.json of a minio setup.
-func (adm *AdminClient) GetConfigKeys(keys []string) ([]byte, error) {
- queryVals := make(url.Values)
- for _, k := range keys {
- queryVals.Add(k, "")
- }
-
- // Execute GET on /minio/admin/v1/config-keys to get config of a setup.
- resp, err := adm.executeMethod("GET",
- requestData{
- relPath: "/v1/config-keys",
- queryValues: queryVals,
- })
- defer closeResponse(resp)
- if err != nil {
- return nil, err
- }
-
- if resp.StatusCode != http.StatusOK {
- return nil, httpRespToErrorResponse(resp)
- }
-
- return DecryptData(adm.secretAccessKey, resp.Body)
-}
-
// SetConfig - set config supplied as config.json for the setup.
func (adm *AdminClient) SetConfig(config io.Reader) (err error) {
const maxConfigJSONSize = 256 * 1024 // 256KiB
@@ -130,35 +103,3 @@ func (adm *AdminClient) SetConfig(config io.Reader) (err error) {
return nil
}
-
-// SetConfigKeys - set config keys supplied as config.json for the setup.
-func (adm *AdminClient) SetConfigKeys(params map[string]string) error {
- queryVals := make(url.Values)
- for k, v := range params {
- encryptedVal, err := EncryptData(adm.secretAccessKey, []byte(v))
- if err != nil {
- return err
- }
- encodedVal := base64.StdEncoding.EncodeToString(encryptedVal)
- queryVals.Add(k, string(encodedVal))
- }
-
- reqData := requestData{
- relPath: "/v1/config-keys",
- queryValues: queryVals,
- }
-
- // Execute PUT on /minio/admin/v1/config-keys to set config.
- resp, err := adm.executeMethod("PUT", reqData)
-
- defer closeResponse(resp)
- if err != nil {
- return err
- }
-
- if resp.StatusCode != http.StatusOK {
- return httpRespToErrorResponse(resp)
- }
-
- return nil
-}
diff --git a/pkg/madmin/examples/get-config-keys.go b/pkg/madmin/examples/get-config-keys.go
deleted file mode 100644
index 641ba08ad..000000000
--- a/pkg/madmin/examples/get-config-keys.go
+++ /dev/null
@@ -1,54 +0,0 @@
-// +build ignore
-
-/*
- * MinIO Cloud Storage, (C) 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 main
-
-import (
- "bytes"
- "encoding/json"
- "log"
-
- "github.com/minio/minio/pkg/madmin"
-)
-
-func main() {
- // Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY are
- // dummy values, please replace them with original values.
-
- // API requests are secure (HTTPS) if secure=true and insecure (HTTP) 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)
- }
-
- configBytes, err := madmClnt.GetConfigKeys([]string{"notify.amqp.1", "version"})
- 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()))
-}
diff --git a/pkg/madmin/examples/set-config-keys.go b/pkg/madmin/examples/set-config-keys.go
deleted file mode 100644
index b0eb94a47..000000000
--- a/pkg/madmin/examples/set-config-keys.go
+++ /dev/null
@@ -1,53 +0,0 @@
-// +build ignore
-
-/*
- * MinIO Cloud Storage, (C) 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 main
-
-import (
- "fmt"
- "log"
-
- "github.com/minio/minio/pkg/madmin"
-)
-
-func main() {
- // Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY are
- // dummy values, please replace them with original values.
-
- // Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY are
- // dummy values, please replace them with original values.
-
- // API requests are secure (HTTPS) if secure=true and insecure (HTTP) 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.SetConfigKeys(map[string]string{
- "domain": "example.com",
- "notify.webhook.1": "{\"enable\": true, \"endpoint\": \"http://example.com/api/object-notifications\"}",
- })
-
- if err != nil {
- log.Fatalln(err)
- }
-
- fmt.Println("Setting new configuration successfully executed.")
-}