mirror of https://github.com/minio/minio.git
				
				
				
			
		
			
				
	
	
		
			190 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			190 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			Go
		
	
	
	
| // Copyright (c) 2015-2021 MinIO, Inc.
 | |
| //
 | |
| // This file is part of MinIO Object Storage stack
 | |
| //
 | |
| // This program is free software: you can redistribute it and/or modify
 | |
| // it under the terms of the GNU Affero General Public License as published by
 | |
| // the Free Software Foundation, either version 3 of the License, or
 | |
| // (at your option) any later version.
 | |
| //
 | |
| // This program is distributed in the hope that it will be useful
 | |
| // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
| // GNU Affero General Public License for more details.
 | |
| //
 | |
| // You should have received a copy of the GNU Affero General Public License
 | |
| // along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | |
| 
 | |
| package cmd
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"encoding/json"
 | |
| 	"errors"
 | |
| 	"path"
 | |
| 	"strings"
 | |
| 
 | |
| 	"github.com/minio/minio/internal/config"
 | |
| 	"github.com/minio/minio/internal/config/compress"
 | |
| 	xldap "github.com/minio/minio/internal/config/identity/ldap"
 | |
| 	"github.com/minio/minio/internal/config/identity/openid"
 | |
| 	"github.com/minio/minio/internal/config/notify"
 | |
| 	"github.com/minio/minio/internal/config/policy/opa"
 | |
| 	"github.com/minio/minio/internal/config/storageclass"
 | |
| 	"github.com/minio/minio/internal/event/target"
 | |
| 	"github.com/minio/minio/internal/logger"
 | |
| 	xnet "github.com/minio/pkg/v3/net"
 | |
| 	"github.com/minio/pkg/v3/quick"
 | |
| )
 | |
| 
 | |
| // Save config file to corresponding backend
 | |
| func Save(configFile string, data interface{}) error {
 | |
| 	return quick.SaveConfig(data, configFile, globalEtcdClient)
 | |
| }
 | |
| 
 | |
| // Load config from backend
 | |
| func Load(configFile string, data interface{}) (quick.Config, error) {
 | |
| 	return quick.LoadConfig(configFile, globalEtcdClient, data)
 | |
| }
 | |
| 
 | |
| func readConfigWithoutMigrate(ctx context.Context, objAPI ObjectLayer) (config.Config, error) {
 | |
| 	// Construct path to config.json for the given bucket.
 | |
| 	configFile := path.Join(minioConfigPrefix, minioConfigFile)
 | |
| 
 | |
| 	configFiles := []string{
 | |
| 		getConfigFile(),
 | |
| 		getConfigFile() + ".deprecated",
 | |
| 		configFile,
 | |
| 	}
 | |
| 
 | |
| 	newServerCfg := func() (config.Config, error) {
 | |
| 		// Initialize server config.
 | |
| 		srvCfg := newServerConfig()
 | |
| 
 | |
| 		return srvCfg, saveServerConfig(ctx, objAPI, srvCfg)
 | |
| 	}
 | |
| 
 | |
| 	var data []byte
 | |
| 	var err error
 | |
| 
 | |
| 	cfg := &serverConfigV33{}
 | |
| 	for _, cfgFile := range configFiles {
 | |
| 		if _, err = Load(cfgFile, cfg); err != nil {
 | |
| 			if !osIsNotExist(err) && !osIsPermission(err) {
 | |
| 				return nil, err
 | |
| 			}
 | |
| 			continue
 | |
| 		}
 | |
| 		data, _ = json.Marshal(cfg)
 | |
| 		break
 | |
| 	}
 | |
| 	if osIsPermission(err) {
 | |
| 		logger.Info("Older config found but is not readable %s, proceeding to read config from other places", err)
 | |
| 	}
 | |
| 	if osIsNotExist(err) || osIsPermission(err) || len(data) == 0 {
 | |
| 		data, err = readConfig(GlobalContext, objAPI, configFile)
 | |
| 		if err != nil {
 | |
| 			// when config.json is not found, then we freshly initialize.
 | |
| 			if errors.Is(err, errConfigNotFound) {
 | |
| 				return newServerCfg()
 | |
| 			}
 | |
| 			return nil, err
 | |
| 		}
 | |
| 
 | |
| 		data, err = decryptData(data, configFile)
 | |
| 		if err != nil {
 | |
| 			return nil, err
 | |
| 		}
 | |
| 
 | |
| 		newCfg, err := readServerConfig(GlobalContext, objAPI, data)
 | |
| 		if err == nil {
 | |
| 			return newCfg, nil
 | |
| 		}
 | |
| 
 | |
| 		// Read older `.minio.sys/config/config.json`, if not
 | |
| 		// possible just fail.
 | |
| 		if err = json.Unmarshal(data, cfg); err != nil {
 | |
| 			// Unable to parse old JSON simply re-initialize a new one.
 | |
| 			return newServerCfg()
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	if !globalCredViaEnv && cfg.Credential.IsValid() {
 | |
| 		// Preserve older credential if we do not have
 | |
| 		// root credentials set via environment variable.
 | |
| 		globalActiveCred = cfg.Credential
 | |
| 	}
 | |
| 
 | |
| 	// Init compression config. For future migration, Compression config needs to be copied over from previous version.
 | |
| 	switch cfg.Version {
 | |
| 	case "29":
 | |
| 		// V29 -> V30
 | |
| 		cfg.Compression.Enabled = false
 | |
| 		cfg.Compression.Extensions = strings.Split(compress.DefaultExtensions, config.ValueSeparator)
 | |
| 		cfg.Compression.MimeTypes = strings.Split(compress.DefaultMimeTypes, config.ValueSeparator)
 | |
| 	case "30":
 | |
| 		// V30 -> V31
 | |
| 		cfg.OpenID = openid.Config{}
 | |
| 		cfg.Policy.OPA = opa.Args{
 | |
| 			URL:       &xnet.URL{},
 | |
| 			AuthToken: "",
 | |
| 		}
 | |
| 	case "31":
 | |
| 		// V31 -> V32
 | |
| 		cfg.Notify.NSQ = make(map[string]target.NSQArgs)
 | |
| 		cfg.Notify.NSQ["1"] = target.NSQArgs{}
 | |
| 	}
 | |
| 
 | |
| 	// Move to latest.
 | |
| 	cfg.Version = "33"
 | |
| 
 | |
| 	newCfg := newServerConfig()
 | |
| 
 | |
| 	config.SetRegion(newCfg, cfg.Region)
 | |
| 	storageclass.SetStorageClass(newCfg, cfg.StorageClass)
 | |
| 
 | |
| 	for k, loggerArgs := range cfg.Logger.HTTP {
 | |
| 		logger.SetLoggerHTTP(newCfg, k, loggerArgs)
 | |
| 	}
 | |
| 	for k, auditArgs := range cfg.Logger.AuditWebhook {
 | |
| 		logger.SetLoggerHTTPAudit(newCfg, k, auditArgs)
 | |
| 	}
 | |
| 
 | |
| 	xldap.SetIdentityLDAP(newCfg, cfg.LDAPServerConfig)
 | |
| 	opa.SetPolicyOPAConfig(newCfg, cfg.Policy.OPA)
 | |
| 	compress.SetCompressionConfig(newCfg, cfg.Compression)
 | |
| 
 | |
| 	for k, args := range cfg.Notify.AMQP {
 | |
| 		notify.SetNotifyAMQP(newCfg, k, args)
 | |
| 	}
 | |
| 	for k, args := range cfg.Notify.Elasticsearch {
 | |
| 		notify.SetNotifyES(newCfg, k, args)
 | |
| 	}
 | |
| 	for k, args := range cfg.Notify.Kafka {
 | |
| 		notify.SetNotifyKafka(newCfg, k, args)
 | |
| 	}
 | |
| 	for k, args := range cfg.Notify.MQTT {
 | |
| 		notify.SetNotifyMQTT(newCfg, k, args)
 | |
| 	}
 | |
| 	for k, args := range cfg.Notify.MySQL {
 | |
| 		notify.SetNotifyMySQL(newCfg, k, args)
 | |
| 	}
 | |
| 	for k, args := range cfg.Notify.NATS {
 | |
| 		notify.SetNotifyNATS(newCfg, k, args)
 | |
| 	}
 | |
| 	for k, args := range cfg.Notify.NSQ {
 | |
| 		notify.SetNotifyNSQ(newCfg, k, args)
 | |
| 	}
 | |
| 	for k, args := range cfg.Notify.PostgreSQL {
 | |
| 		notify.SetNotifyPostgres(newCfg, k, args)
 | |
| 	}
 | |
| 	for k, args := range cfg.Notify.Redis {
 | |
| 		notify.SetNotifyRedis(newCfg, k, args)
 | |
| 	}
 | |
| 	for k, args := range cfg.Notify.Webhook {
 | |
| 		notify.SetNotifyWebhook(newCfg, k, args)
 | |
| 	}
 | |
| 
 | |
| 	return newCfg, nil
 | |
| }
 |