mirror of
https://github.com/minio/minio.git
synced 2024-12-25 22:55:54 -05:00
f3248a4b37
This change adds a `Secret` property to `HelpKV` to identify secrets like passwords and auth tokens that should not be revealed by the server in its configuration fetching APIs. Configuration reporting APIs now do not return secrets.
564 lines
17 KiB
Go
564 lines
17 KiB
Go
// Copyright (c) 2015-2023 MinIO, Inc.
|
|
//
|
|
// This file is part of MinIO Object Storage stack
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU Affero General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU Affero General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Affero General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
package cmd
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"io"
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/minio/madmin-go/v3"
|
|
"github.com/minio/minio/internal/config"
|
|
"github.com/minio/minio/internal/config/cache"
|
|
"github.com/minio/minio/internal/config/etcd"
|
|
xldap "github.com/minio/minio/internal/config/identity/ldap"
|
|
"github.com/minio/minio/internal/config/identity/openid"
|
|
idplugin "github.com/minio/minio/internal/config/identity/plugin"
|
|
polplugin "github.com/minio/minio/internal/config/policy/plugin"
|
|
"github.com/minio/minio/internal/config/storageclass"
|
|
"github.com/minio/minio/internal/config/subnet"
|
|
"github.com/minio/minio/internal/logger"
|
|
"github.com/minio/mux"
|
|
iampolicy "github.com/minio/pkg/iam/policy"
|
|
)
|
|
|
|
// DelConfigKVHandler - DELETE /minio/admin/v3/del-config-kv
|
|
func (a adminAPIHandlers) DelConfigKVHandler(w http.ResponseWriter, r *http.Request) {
|
|
ctx := newContext(r, w, "DeleteConfigKV")
|
|
|
|
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
|
|
|
objectAPI, cred := validateAdminReq(ctx, w, r, iampolicy.ConfigUpdateAdminAction)
|
|
if objectAPI == nil {
|
|
return
|
|
}
|
|
|
|
if r.ContentLength > maxEConfigJSONSize || r.ContentLength == -1 {
|
|
// More than maxConfigSize bytes were available
|
|
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigTooLarge), r.URL)
|
|
return
|
|
}
|
|
|
|
password := cred.SecretKey
|
|
kvBytes, err := madmin.DecryptData(password, io.LimitReader(r.Body, r.ContentLength))
|
|
if err != nil {
|
|
logger.LogIf(ctx, err, logger.Application)
|
|
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), r.URL)
|
|
return
|
|
}
|
|
|
|
subSys, _, _, err := config.GetSubSys(string(kvBytes))
|
|
if err != nil {
|
|
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
|
return
|
|
}
|
|
|
|
cfg, err := readServerConfig(ctx, objectAPI, nil)
|
|
if err != nil {
|
|
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
|
return
|
|
}
|
|
|
|
if err = cfg.DelFrom(bytes.NewReader(kvBytes)); err != nil {
|
|
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
|
return
|
|
}
|
|
|
|
if err = validateConfig(ctx, cfg, subSys); err != nil {
|
|
writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), err.Error(), r.URL)
|
|
return
|
|
}
|
|
|
|
// Check if subnet proxy being deleted and if so the value of proxy of subnet
|
|
// target of logger webhook configuration also should be deleted
|
|
loggerWebhookProxyDeleted := setLoggerWebhookSubnetProxy(subSys, cfg)
|
|
|
|
if err = saveServerConfig(ctx, objectAPI, cfg); err != nil {
|
|
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
|
return
|
|
}
|
|
|
|
// freshly retrieve the config so that default values are loaded for reset config
|
|
if cfg, err = getValidConfig(objectAPI); err != nil {
|
|
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
|
return
|
|
}
|
|
|
|
dynamic := config.SubSystemsDynamic.Contains(subSys)
|
|
if dynamic {
|
|
applyDynamic(ctx, objectAPI, cfg, subSys, r, w)
|
|
if subSys == config.SubnetSubSys && loggerWebhookProxyDeleted {
|
|
// Logger webhook proxy deleted, apply the dynamic changes
|
|
applyDynamic(ctx, objectAPI, cfg, config.LoggerWebhookSubSys, r, w)
|
|
}
|
|
}
|
|
}
|
|
|
|
func applyDynamic(ctx context.Context, objectAPI ObjectLayer, cfg config.Config, subSys string,
|
|
r *http.Request, w http.ResponseWriter,
|
|
) {
|
|
// Apply dynamic values.
|
|
if err := applyDynamicConfigForSubSys(GlobalContext, objectAPI, cfg, subSys); err != nil {
|
|
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
|
return
|
|
}
|
|
globalNotificationSys.SignalConfigReload(subSys)
|
|
// Tell the client that dynamic config was applied.
|
|
w.Header().Set(madmin.ConfigAppliedHeader, madmin.ConfigAppliedTrue)
|
|
}
|
|
|
|
type badConfigErr struct {
|
|
Err error
|
|
}
|
|
|
|
// Error - return the error message
|
|
func (bce badConfigErr) Error() string {
|
|
return bce.Err.Error()
|
|
}
|
|
|
|
// Unwrap the error to its underlying error.
|
|
func (bce badConfigErr) Unwrap() error {
|
|
return bce.Err
|
|
}
|
|
|
|
type setConfigResult struct {
|
|
Cfg config.Config
|
|
SubSys string
|
|
Dynamic bool
|
|
LoggerWebhookCfgUpdated bool
|
|
}
|
|
|
|
// SetConfigKVHandler - PUT /minio/admin/v3/set-config-kv
|
|
func (a adminAPIHandlers) SetConfigKVHandler(w http.ResponseWriter, r *http.Request) {
|
|
ctx := newContext(r, w, "SetConfigKV")
|
|
|
|
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
|
|
|
objectAPI, cred := validateAdminReq(ctx, w, r, iampolicy.ConfigUpdateAdminAction)
|
|
if objectAPI == nil {
|
|
return
|
|
}
|
|
|
|
if r.ContentLength > maxEConfigJSONSize || r.ContentLength == -1 {
|
|
// More than maxConfigSize bytes were available
|
|
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigTooLarge), r.URL)
|
|
return
|
|
}
|
|
|
|
password := cred.SecretKey
|
|
kvBytes, err := madmin.DecryptData(password, io.LimitReader(r.Body, r.ContentLength))
|
|
if err != nil {
|
|
logger.LogIf(ctx, err, logger.Application)
|
|
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), r.URL)
|
|
return
|
|
}
|
|
|
|
result, err := setConfigKV(ctx, objectAPI, kvBytes)
|
|
if err != nil {
|
|
switch err.(type) {
|
|
case badConfigErr:
|
|
writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), err.Error(), r.URL)
|
|
default:
|
|
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
|
}
|
|
return
|
|
}
|
|
|
|
if result.Dynamic {
|
|
applyDynamic(ctx, objectAPI, result.Cfg, result.SubSys, r, w)
|
|
// If logger webhook config updated (proxy due to callhome), explicitly dynamically
|
|
// apply the config
|
|
if result.LoggerWebhookCfgUpdated {
|
|
applyDynamic(ctx, objectAPI, result.Cfg, config.LoggerWebhookSubSys, r, w)
|
|
}
|
|
}
|
|
|
|
writeSuccessResponseHeadersOnly(w)
|
|
}
|
|
|
|
func setConfigKV(ctx context.Context, objectAPI ObjectLayer, kvBytes []byte) (result setConfigResult, err error) {
|
|
result.Cfg, err = readServerConfig(ctx, objectAPI, nil)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
result.Dynamic, err = result.Cfg.ReadConfig(bytes.NewReader(kvBytes))
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
result.SubSys, _, _, err = config.GetSubSys(string(kvBytes))
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
tgts, err := config.ParseConfigTargetID(bytes.NewReader(kvBytes))
|
|
if err != nil {
|
|
return
|
|
}
|
|
ctx = context.WithValue(ctx, config.ContextKeyForTargetFromConfig, tgts)
|
|
if verr := validateConfig(ctx, result.Cfg, result.SubSys); verr != nil {
|
|
err = badConfigErr{Err: verr}
|
|
return
|
|
}
|
|
|
|
// Check if subnet proxy being set and if so set the same value to proxy of subnet
|
|
// target of logger webhook configuration
|
|
result.LoggerWebhookCfgUpdated = setLoggerWebhookSubnetProxy(result.SubSys, result.Cfg)
|
|
|
|
// Update the actual server config on disk.
|
|
if err = saveServerConfig(ctx, objectAPI, result.Cfg); err != nil {
|
|
return
|
|
}
|
|
|
|
// Write the config input KV to history.
|
|
err = saveServerConfigHistory(ctx, objectAPI, kvBytes)
|
|
return
|
|
}
|
|
|
|
// GetConfigKVHandler - GET /minio/admin/v3/get-config-kv?key={key}
|
|
//
|
|
// `key` can be one of three forms:
|
|
// 1. `subsys:target` -> request for config of a single subsystem and target pair.
|
|
// 2. `subsys:` -> request for config of a single subsystem and the default target.
|
|
// 3. `subsys` -> request for config of all targets for the given subsystem.
|
|
//
|
|
// This is a reporting API and config secrets are redacted in the response.
|
|
func (a adminAPIHandlers) GetConfigKVHandler(w http.ResponseWriter, r *http.Request) {
|
|
ctx := newContext(r, w, "GetConfigKV")
|
|
|
|
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
|
|
|
objectAPI, cred := validateAdminReq(ctx, w, r, iampolicy.ConfigUpdateAdminAction)
|
|
if objectAPI == nil {
|
|
return
|
|
}
|
|
|
|
cfg := globalServerConfig.Clone()
|
|
vars := mux.Vars(r)
|
|
key := vars["key"]
|
|
|
|
var subSys, target string
|
|
{
|
|
ws := strings.SplitN(key, madmin.SubSystemSeparator, 2)
|
|
subSys = ws[0]
|
|
if len(ws) == 2 {
|
|
if ws[1] == "" {
|
|
target = madmin.Default
|
|
} else {
|
|
target = ws[1]
|
|
}
|
|
}
|
|
}
|
|
|
|
subSysConfigs, err := cfg.GetSubsysInfo(subSys, target, true)
|
|
if err != nil {
|
|
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
|
return
|
|
}
|
|
|
|
var s strings.Builder
|
|
for _, subSysConfig := range subSysConfigs {
|
|
subSysConfig.WriteTo(&s, false)
|
|
}
|
|
|
|
password := cred.SecretKey
|
|
econfigData, err := madmin.EncryptData(password, []byte(s.String()))
|
|
if err != nil {
|
|
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
|
return
|
|
}
|
|
|
|
writeSuccessResponseJSON(w, econfigData)
|
|
}
|
|
|
|
func (a adminAPIHandlers) ClearConfigHistoryKVHandler(w http.ResponseWriter, r *http.Request) {
|
|
ctx := newContext(r, w, "ClearConfigHistoryKV")
|
|
|
|
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
|
|
|
objectAPI, _ := validateAdminReq(ctx, w, r, iampolicy.ConfigUpdateAdminAction)
|
|
if objectAPI == nil {
|
|
return
|
|
}
|
|
|
|
vars := mux.Vars(r)
|
|
restoreID := vars["restoreId"]
|
|
if restoreID == "" {
|
|
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrInvalidRequest), r.URL)
|
|
return
|
|
}
|
|
if restoreID == "all" {
|
|
chEntries, err := listServerConfigHistory(ctx, objectAPI, false, -1)
|
|
if err != nil {
|
|
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
|
return
|
|
}
|
|
for _, chEntry := range chEntries {
|
|
if err = delServerConfigHistory(ctx, objectAPI, chEntry.RestoreID); err != nil {
|
|
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
|
return
|
|
}
|
|
}
|
|
} else if err := delServerConfigHistory(ctx, objectAPI, restoreID); err != nil {
|
|
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
|
return
|
|
}
|
|
}
|
|
|
|
// RestoreConfigHistoryKVHandler - restores a config with KV settings for the given KV id.
|
|
func (a adminAPIHandlers) RestoreConfigHistoryKVHandler(w http.ResponseWriter, r *http.Request) {
|
|
ctx := newContext(r, w, "RestoreConfigHistoryKV")
|
|
|
|
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
|
|
|
objectAPI, _ := validateAdminReq(ctx, w, r, iampolicy.ConfigUpdateAdminAction)
|
|
if objectAPI == nil {
|
|
return
|
|
}
|
|
|
|
vars := mux.Vars(r)
|
|
restoreID := vars["restoreId"]
|
|
if restoreID == "" {
|
|
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrInvalidRequest), r.URL)
|
|
return
|
|
}
|
|
|
|
kvBytes, err := readServerConfigHistory(ctx, objectAPI, restoreID)
|
|
if err != nil {
|
|
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
|
return
|
|
}
|
|
|
|
cfg, err := readServerConfig(ctx, objectAPI, nil)
|
|
if err != nil {
|
|
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
|
return
|
|
}
|
|
|
|
if _, err = cfg.ReadConfig(bytes.NewReader(kvBytes)); err != nil {
|
|
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
|
return
|
|
}
|
|
|
|
if err = validateConfig(ctx, cfg, ""); err != nil {
|
|
writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), err.Error(), r.URL)
|
|
return
|
|
}
|
|
|
|
if err = saveServerConfig(ctx, objectAPI, cfg); err != nil {
|
|
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
|
return
|
|
}
|
|
|
|
delServerConfigHistory(ctx, objectAPI, restoreID)
|
|
}
|
|
|
|
// ListConfigHistoryKVHandler - lists all the KV ids.
|
|
func (a adminAPIHandlers) ListConfigHistoryKVHandler(w http.ResponseWriter, r *http.Request) {
|
|
ctx := newContext(r, w, "ListConfigHistoryKV")
|
|
|
|
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
|
|
|
objectAPI, cred := validateAdminReq(ctx, w, r, iampolicy.ConfigUpdateAdminAction)
|
|
if objectAPI == nil {
|
|
return
|
|
}
|
|
|
|
vars := mux.Vars(r)
|
|
count, err := strconv.Atoi(vars["count"])
|
|
if err != nil {
|
|
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
|
return
|
|
}
|
|
|
|
chEntries, err := listServerConfigHistory(ctx, objectAPI, true, count)
|
|
if err != nil {
|
|
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
|
return
|
|
}
|
|
|
|
data, err := json.Marshal(chEntries)
|
|
if err != nil {
|
|
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
|
return
|
|
}
|
|
|
|
password := cred.SecretKey
|
|
econfigData, err := madmin.EncryptData(password, data)
|
|
if err != nil {
|
|
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
|
return
|
|
}
|
|
|
|
writeSuccessResponseJSON(w, econfigData)
|
|
}
|
|
|
|
// 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, "HelpConfigKV")
|
|
|
|
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
|
|
|
objectAPI, _ := validateAdminReq(ctx, w, r, iampolicy.ConfigUpdateAdminAction)
|
|
if objectAPI == nil {
|
|
return
|
|
}
|
|
|
|
vars := mux.Vars(r)
|
|
|
|
subSys := vars["subSys"]
|
|
key := vars["key"]
|
|
|
|
_, envOnly := r.Form["env"]
|
|
|
|
rd, err := GetHelp(subSys, key, envOnly)
|
|
if err != nil {
|
|
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
|
return
|
|
}
|
|
|
|
json.NewEncoder(w).Encode(rd)
|
|
}
|
|
|
|
// SetConfigHandler - PUT /minio/admin/v3/config
|
|
func (a adminAPIHandlers) SetConfigHandler(w http.ResponseWriter, r *http.Request) {
|
|
ctx := newContext(r, w, "SetConfig")
|
|
|
|
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
|
|
|
objectAPI, cred := validateAdminReq(ctx, w, r, iampolicy.ConfigUpdateAdminAction)
|
|
if objectAPI == nil {
|
|
return
|
|
}
|
|
|
|
if r.ContentLength > maxEConfigJSONSize || r.ContentLength == -1 {
|
|
// More than maxConfigSize bytes were available
|
|
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigTooLarge), r.URL)
|
|
return
|
|
}
|
|
|
|
password := cred.SecretKey
|
|
kvBytes, err := madmin.DecryptData(password, io.LimitReader(r.Body, r.ContentLength))
|
|
if err != nil {
|
|
logger.LogIf(ctx, err, logger.Application)
|
|
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), r.URL)
|
|
return
|
|
}
|
|
|
|
cfg := newServerConfig()
|
|
if _, err = cfg.ReadConfig(bytes.NewReader(kvBytes)); err != nil {
|
|
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
|
return
|
|
}
|
|
|
|
if err = validateConfig(ctx, cfg, ""); err != nil {
|
|
writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), err.Error(), r.URL)
|
|
return
|
|
}
|
|
|
|
// Update the actual server config on disk.
|
|
if err = saveServerConfig(ctx, objectAPI, cfg); err != nil {
|
|
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
|
return
|
|
}
|
|
|
|
// Write to the config input KV to history.
|
|
if err = saveServerConfigHistory(ctx, objectAPI, kvBytes); err != nil {
|
|
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
|
return
|
|
}
|
|
|
|
writeSuccessResponseHeadersOnly(w)
|
|
}
|
|
|
|
// GetConfigHandler - GET /minio/admin/v3/config
|
|
//
|
|
// This endpoint is mainly for exporting and backing up the configuration.
|
|
// Secrets are not redacted.
|
|
func (a adminAPIHandlers) GetConfigHandler(w http.ResponseWriter, r *http.Request) {
|
|
ctx := newContext(r, w, "GetConfig")
|
|
|
|
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
|
|
|
objectAPI, cred := validateAdminReq(ctx, w, r, iampolicy.ConfigUpdateAdminAction)
|
|
if objectAPI == nil {
|
|
return
|
|
}
|
|
|
|
cfg := globalServerConfig.Clone()
|
|
|
|
var s strings.Builder
|
|
hkvs := config.HelpSubSysMap[""]
|
|
for _, hkv := range hkvs {
|
|
// We ignore the error below, as we cannot get one.
|
|
cfgSubsysItems, _ := cfg.GetSubsysInfo(hkv.Key, "", false)
|
|
|
|
for _, item := range cfgSubsysItems {
|
|
off := item.Config.Get(config.Enable) == config.EnableOff
|
|
switch hkv.Key {
|
|
case config.EtcdSubSys:
|
|
off = !etcd.Enabled(item.Config)
|
|
case config.CacheSubSys:
|
|
off = !cache.Enabled(item.Config)
|
|
case config.StorageClassSubSys:
|
|
off = !storageclass.Enabled(item.Config)
|
|
case config.PolicyPluginSubSys:
|
|
off = !polplugin.Enabled(item.Config)
|
|
case config.IdentityOpenIDSubSys:
|
|
off = !openid.Enabled(item.Config)
|
|
case config.IdentityLDAPSubSys:
|
|
off = !xldap.Enabled(item.Config)
|
|
case config.IdentityTLSSubSys:
|
|
off = !globalIAMSys.STSTLSConfig.Enabled
|
|
case config.IdentityPluginSubSys:
|
|
off = !idplugin.Enabled(item.Config)
|
|
}
|
|
item.WriteTo(&s, off)
|
|
}
|
|
}
|
|
|
|
password := cred.SecretKey
|
|
econfigData, err := madmin.EncryptData(password, []byte(s.String()))
|
|
if err != nil {
|
|
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
|
|
return
|
|
}
|
|
|
|
writeSuccessResponseJSON(w, econfigData)
|
|
}
|
|
|
|
// setLoggerWebhookSubnetProxy - Sets the logger webhook's subnet proxy value to
|
|
// one being set for subnet proxy
|
|
func setLoggerWebhookSubnetProxy(subSys string, cfg config.Config) bool {
|
|
if subSys == config.SubnetSubSys || subSys == config.LoggerWebhookSubSys {
|
|
subnetWebhookCfg := cfg[config.LoggerWebhookSubSys][subnet.LoggerWebhookName]
|
|
loggerWebhookSubnetProxy := subnetWebhookCfg.Get(logger.Proxy)
|
|
subnetProxy := cfg[config.SubnetSubSys][config.Default].Get(logger.Proxy)
|
|
if loggerWebhookSubnetProxy != subnetProxy {
|
|
subnetWebhookCfg.Set(logger.Proxy, subnetProxy)
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|