mirror of
https://github.com/minio/minio.git
synced 2024-12-25 14:45:54 -05:00
4a4048fe27
etcd when used in federated setups, currently mandates that all clusters should have same config.json, which is too restrictive and makes federation a restrictive environment. This change makes it apparent that each cluster needs to be independently managed if necessary from `mc admin info` command line. Each cluster with in federation can have their own root credentials and as well as separate regions. This way buckets get further restrictions and allows for root creds to be not common across clusters/data centers. Existing data in etcd gets migrated to backend on each clusters, upon start. Once done users can change their config entries independently.
132 lines
4.2 KiB
Go
132 lines
4.2 KiB
Go
/*
|
|
* MinIO Cloud Storage, (C) 2018 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 cmd
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
|
|
etcd "github.com/coreos/etcd/clientv3"
|
|
"github.com/minio/minio/cmd/logger"
|
|
"github.com/minio/minio/pkg/hash"
|
|
)
|
|
|
|
var errConfigNotFound = errors.New("config file not found")
|
|
|
|
func readConfig(ctx context.Context, objAPI ObjectLayer, configFile string) ([]byte, error) {
|
|
var buffer bytes.Buffer
|
|
// Read entire content by setting size to -1
|
|
if err := objAPI.GetObject(ctx, minioMetaBucket, configFile, 0, -1, &buffer, "", ObjectOptions{}); err != nil {
|
|
// Treat object not found as config not found.
|
|
if isErrObjectNotFound(err) {
|
|
return nil, errConfigNotFound
|
|
}
|
|
|
|
logger.GetReqInfo(ctx).AppendTags("configFile", configFile)
|
|
logger.LogIf(ctx, err)
|
|
return nil, err
|
|
}
|
|
|
|
// Return config not found on empty content.
|
|
if buffer.Len() == 0 {
|
|
return nil, errConfigNotFound
|
|
}
|
|
|
|
return buffer.Bytes(), nil
|
|
}
|
|
|
|
func deleteConfigEtcd(ctx context.Context, client *etcd.Client, configFile string) error {
|
|
timeoutCtx, cancel := context.WithTimeout(ctx, defaultContextTimeout)
|
|
defer cancel()
|
|
|
|
_, err := client.Delete(timeoutCtx, configFile)
|
|
if err != nil {
|
|
if err == context.DeadlineExceeded {
|
|
return fmt.Errorf("etcd setup is unreachable, please check your endpoints %s",
|
|
client.Endpoints())
|
|
}
|
|
return fmt.Errorf("unexpected error %s returned by etcd setup, please check your endpoints %s",
|
|
err, client.Endpoints())
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func deleteConfig(ctx context.Context, objAPI ObjectLayer, configFile string) error {
|
|
return objAPI.DeleteObject(ctx, minioMetaBucket, configFile)
|
|
}
|
|
|
|
func saveConfigEtcd(ctx context.Context, client *etcd.Client, configFile string, data []byte) error {
|
|
timeoutCtx, cancel := context.WithTimeout(ctx, defaultContextTimeout)
|
|
defer cancel()
|
|
_, err := client.Put(timeoutCtx, configFile, string(data))
|
|
if err == context.DeadlineExceeded {
|
|
return fmt.Errorf("etcd setup is unreachable, please check your endpoints %s", client.Endpoints())
|
|
} else if err != nil {
|
|
return fmt.Errorf("unexpected error %s returned by etcd setup, please check your endpoints %s", err, client.Endpoints())
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func saveConfig(ctx context.Context, objAPI ObjectLayer, configFile string, data []byte) error {
|
|
hashReader, err := hash.NewReader(bytes.NewReader(data), int64(len(data)), "", getSHA256Hash(data), int64(len(data)), globalCLIContext.StrictS3Compat)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
_, err = objAPI.PutObject(ctx, minioMetaBucket, configFile, NewPutObjReader(hashReader, nil, nil), ObjectOptions{})
|
|
return err
|
|
}
|
|
|
|
func readConfigEtcd(ctx context.Context, client *etcd.Client, configFile string) ([]byte, error) {
|
|
timeoutCtx, cancel := context.WithTimeout(ctx, defaultContextTimeout)
|
|
defer cancel()
|
|
resp, err := client.Get(timeoutCtx, configFile)
|
|
if err != nil {
|
|
if err == context.DeadlineExceeded {
|
|
return nil, fmt.Errorf("etcd setup is unreachable, please check your endpoints %s",
|
|
client.Endpoints())
|
|
}
|
|
return nil, fmt.Errorf("unexpected error %s returned by etcd setup, please check your endpoints %s",
|
|
err, client.Endpoints())
|
|
}
|
|
if resp.Count == 0 {
|
|
return nil, errConfigNotFound
|
|
}
|
|
for _, ev := range resp.Kvs {
|
|
if string(ev.Key) == configFile {
|
|
return ev.Value, nil
|
|
}
|
|
}
|
|
return nil, errConfigNotFound
|
|
}
|
|
|
|
func checkConfig(ctx context.Context, objAPI ObjectLayer, configFile string) error {
|
|
if _, err := objAPI.GetObjectInfo(ctx, minioMetaBucket, configFile, ObjectOptions{}); err != nil {
|
|
// Treat object not found as config not found.
|
|
if isErrObjectNotFound(err) {
|
|
return errConfigNotFound
|
|
}
|
|
|
|
logger.GetReqInfo(ctx).AppendTags("configFile", configFile)
|
|
logger.LogIf(ctx, err)
|
|
return err
|
|
}
|
|
return nil
|
|
}
|