mirror of
https://github.com/minio/minio.git
synced 2024-12-26 07:05:55 -05:00
ae4361cc45
Validate Minio config by checking if there is double json key in any scope level. The returned error contains the json path to the duplicated key.
164 lines
3.6 KiB
Go
164 lines
3.6 KiB
Go
/*
|
|
* 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 cmd
|
|
|
|
import (
|
|
"io/ioutil"
|
|
"net"
|
|
|
|
"github.com/Sirupsen/logrus"
|
|
"github.com/streadway/amqp"
|
|
)
|
|
|
|
// amqpNotify - represents logrus compatible AMQP hook.
|
|
// All fields represent AMQP configuration details.
|
|
type amqpNotify struct {
|
|
Enable bool `json:"enable"`
|
|
URL string `json:"url"`
|
|
Exchange string `json:"exchange"`
|
|
RoutingKey string `json:"routingKey"`
|
|
ExchangeType string `json:"exchangeType"`
|
|
Mandatory bool `json:"mandatory"`
|
|
Immediate bool `json:"immediate"`
|
|
Durable bool `json:"durable"`
|
|
Internal bool `json:"internal"`
|
|
NoWait bool `json:"noWait"`
|
|
AutoDeleted bool `json:"autoDeleted"`
|
|
}
|
|
|
|
func (a *amqpNotify) Validate() error {
|
|
if !a.Enable {
|
|
return nil
|
|
}
|
|
if _, err := checkNetURL(a.URL); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
type amqpConn struct {
|
|
params amqpNotify
|
|
*amqp.Connection
|
|
}
|
|
|
|
// dialAMQP - dials and returns an amqpConnection instance,
|
|
// for sending notifications. Returns error if amqp logger
|
|
// is not enabled.
|
|
func dialAMQP(amqpL amqpNotify) (amqpConn, error) {
|
|
if !amqpL.Enable {
|
|
return amqpConn{}, errNotifyNotEnabled
|
|
}
|
|
conn, err := amqp.Dial(amqpL.URL)
|
|
if err != nil {
|
|
return amqpConn{}, err
|
|
}
|
|
return amqpConn{Connection: conn, params: amqpL}, nil
|
|
}
|
|
|
|
func newAMQPNotify(accountID string) (*logrus.Logger, error) {
|
|
amqpL := serverConfig.Notify.GetAMQPByID(accountID)
|
|
|
|
// Connect to amqp server.
|
|
amqpC, err := dialAMQP(amqpL)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
amqpLog := logrus.New()
|
|
|
|
// Disable writing to console.
|
|
amqpLog.Out = ioutil.Discard
|
|
|
|
// Add a amqp hook.
|
|
amqpLog.Hooks.Add(amqpC)
|
|
|
|
// Set default JSON formatter.
|
|
amqpLog.Formatter = new(logrus.JSONFormatter)
|
|
|
|
// Successfully enabled all AMQPs.
|
|
return amqpLog, nil
|
|
}
|
|
|
|
// Fire is called when an event should be sent to the message broker.
|
|
func (q amqpConn) Fire(entry *logrus.Entry) error {
|
|
ch, err := q.Connection.Channel()
|
|
if err != nil {
|
|
// Any other error other than connection closed, return.
|
|
isClosedErr := false
|
|
if neterr, ok := err.(*net.OpError); ok &&
|
|
neterr.Err.Error() == "use of closed network connection" {
|
|
isClosedErr = true
|
|
} else if err == amqp.ErrClosed {
|
|
isClosedErr = true
|
|
}
|
|
if !isClosedErr {
|
|
return err
|
|
}
|
|
// Attempt to connect again.
|
|
var conn *amqp.Connection
|
|
conn, err = amqp.Dial(q.params.URL)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
ch, err = conn.Channel()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
defer ch.Close()
|
|
|
|
err = ch.ExchangeDeclare(
|
|
q.params.Exchange,
|
|
q.params.ExchangeType,
|
|
q.params.Durable,
|
|
q.params.AutoDeleted,
|
|
q.params.Internal,
|
|
q.params.NoWait,
|
|
nil,
|
|
)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
body, err := entry.String()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = ch.Publish(
|
|
q.params.Exchange,
|
|
q.params.RoutingKey,
|
|
q.params.Mandatory,
|
|
q.params.Immediate,
|
|
amqp.Publishing{
|
|
ContentType: "application/json",
|
|
Body: []byte(body),
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Levels is available logging levels.
|
|
func (q amqpConn) Levels() []logrus.Level {
|
|
return []logrus.Level{
|
|
logrus.InfoLevel,
|
|
}
|
|
}
|