Update to latest minio version and fix updates (#530)

This commit is contained in:
Cesar N
2020-12-21 17:11:46 -06:00
committed by GitHub
parent 9789ec36db
commit e3c6e22b4e
13 changed files with 684 additions and 137 deletions

View File

@@ -49,10 +49,11 @@ func registerConfigHandlers(api *operations.ConsoleAPI) {
})
// Set Configuration
api.AdminAPISetConfigHandler = admin_api.SetConfigHandlerFunc(func(params admin_api.SetConfigParams, session *models.Principal) middleware.Responder {
if err := setConfigResponse(session, params.Name, params.Body); err != nil {
resp, err := setConfigResponse(session, params.Name, params.Body)
if err != nil {
return admin_api.NewSetConfigDefault(int(err.Code)).WithPayload(err)
}
return admin_api.NewSetConfigNoContent()
return admin_api.NewSetConfigOK().WithPayload(resp)
})
}
@@ -144,15 +145,16 @@ func getConfigResponse(session *models.Principal, params admin_api.ConfigInfoPar
}
// setConfig sets a configuration with the defined key values
func setConfig(ctx context.Context, client MinioAdmin, configName *string, kvs []*models.ConfigurationKV) error {
func setConfig(ctx context.Context, client MinioAdmin, configName *string, kvs []*models.ConfigurationKV) (restart bool, err error) {
config := buildConfig(configName, kvs)
if err := client.setConfigKV(ctx, *config); err != nil {
return err
restart, err = client.setConfigKV(ctx, *config)
if err != nil {
return false, err
}
return nil
return restart, nil
}
func setConfigWithARNAccountID(ctx context.Context, client MinioAdmin, configName *string, kvs []*models.ConfigurationKV, arnAccountID string) error {
func setConfigWithARNAccountID(ctx context.Context, client MinioAdmin, configName *string, kvs []*models.ConfigurationKV, arnAccountID string) (restart bool, err error) {
// if arnAccountID is not empty the configuration will be treated as a notification target
// arnAccountID will be used as an identifier for that specific target
// docs: https://docs.min.io/docs/minio-bucket-notification-guide.html
@@ -174,10 +176,10 @@ func buildConfig(configName *string, kvs []*models.ConfigurationKV) *string {
}
// setConfigResponse implements setConfig() to be used by handler
func setConfigResponse(session *models.Principal, name string, configRequest *models.SetConfigRequest) *models.Error {
func setConfigResponse(session *models.Principal, name string, configRequest *models.SetConfigRequest) (*models.SetConfigResponse, *models.Error) {
mAdmin, err := newMAdminClient(session)
if err != nil {
return prepareError(err)
return nil, prepareError(err)
}
// create a MinIO Admin Client interface implementation
// defining the client to be used
@@ -186,8 +188,9 @@ func setConfigResponse(session *models.Principal, name string, configRequest *mo
ctx := context.Background()
if err := setConfigWithARNAccountID(ctx, adminClient, &configName, configRequest.KeyValues, configRequest.ArnResourceID); err != nil {
return prepareError(err)
needsRestart, err := setConfigWithARNAccountID(ctx, adminClient, &configName, configRequest.KeyValues, configRequest.ArnResourceID)
if err != nil {
return nil, prepareError(err)
}
return nil
return &models.SetConfigResponse{Restart: needsRestart}, nil
}

View File

@@ -37,7 +37,7 @@ import (
// assigning mock at runtime instead of compile time
var minioHelpConfigKVMock func(subSys, key string, envOnly bool) (madmin.Help, error)
var minioGetConfigKVMock func(key string) ([]byte, error)
var minioSetConfigKVMock func(kv string) error
var minioSetConfigKVMock func(kv string) (restart bool, err error)
// mock function helpConfigKV()
func (ac adminClientMock) helpConfigKV(ctx context.Context, subSys, key string, envOnly bool) (madmin.Help, error) {
@@ -50,7 +50,7 @@ func (ac adminClientMock) getConfigKV(ctx context.Context, name string) ([]byte,
}
// mock function setConfigKV()
func (ac adminClientMock) setConfigKV(ctx context.Context, kv string) error {
func (ac adminClientMock) setConfigKV(ctx context.Context, kv string) (restart bool, err error) {
return minioSetConfigKVMock(kv)
}
@@ -108,8 +108,8 @@ func TestSetConfig(t *testing.T) {
adminClient := adminClientMock{}
function := "setConfig()"
// mock function response from setConfig()
minioSetConfigKVMock = func(kv string) error {
return nil
minioSetConfigKVMock = func(kv string) (restart bool, err error) {
return false, nil
}
configName := "notify_postgres"
kvs := []*models.ConfigurationKV{
@@ -125,18 +125,31 @@ func TestSetConfig(t *testing.T) {
ctx := context.Background()
// Test-1 : setConfig() sets a config with two key value pairs
err := setConfig(ctx, adminClient, &configName, kvs)
restart, err := setConfig(ctx, adminClient, &configName, kvs)
if err != nil {
t.Errorf("Failed on %s:, error occurred: %s", function, err.Error())
}
assert.Equal(restart, false)
// Test-2 : setConfig() returns error, handle properly
minioSetConfigKVMock = func(kv string) error {
return errors.New("error")
minioSetConfigKVMock = func(kv string) (restart bool, err error) {
return false, errors.New("error")
}
if err := setConfig(ctx, adminClient, &configName, kvs); assert.Error(err) {
restart, err = setConfig(ctx, adminClient, &configName, kvs)
if assert.Error(err) {
assert.Equal("error", err.Error())
}
assert.Equal(restart, false)
// Test-4 : setConfig() set config, need restart
minioSetConfigKVMock = func(kv string) (restart bool, err error) {
return true, nil
}
restart, err = setConfig(ctx, adminClient, &configName, kvs)
if err != nil {
t.Errorf("Failed on %s:, error occurred: %s", function, err.Error())
}
assert.Equal(restart, true)
}
@@ -201,6 +214,7 @@ func Test_buildConfig(t *testing.T) {
}
func Test_setConfigWithARN(t *testing.T) {
assert := assert.New(t)
client := adminClientMock{}
type args struct {
@@ -213,8 +227,9 @@ func Test_setConfigWithARN(t *testing.T) {
tests := []struct {
name string
args args
mockSetConfig func(kv string) error
mockSetConfig func(kv string) (restart bool, err error)
wantErr bool
expected bool
}{
{
name: "Set valid config with arn",
@@ -230,10 +245,31 @@ func Test_setConfigWithARN(t *testing.T) {
},
arn: "1",
},
mockSetConfig: func(kv string) error {
return nil
mockSetConfig: func(kv string) (restart bool, err error) {
return false, nil
},
wantErr: false,
wantErr: false,
expected: false,
},
{
name: "Set valid config, expect restart",
args: args{
ctx: context.Background(),
client: client,
configName: swag.String("notify_kafka"),
kvs: []*models.ConfigurationKV{
{
Key: "brokers",
Value: "http://localhost:8080/broker1,http://localhost:8080/broker2",
},
},
arn: "1",
},
mockSetConfig: func(kv string) (restart bool, err error) {
return true, nil
},
wantErr: false,
expected: true,
},
{
name: "Set valid config without arn",
@@ -249,10 +285,11 @@ func Test_setConfigWithARN(t *testing.T) {
},
arn: "",
},
mockSetConfig: func(kv string) error {
return nil
mockSetConfig: func(kv string) (restart bool, err error) {
return false, nil
},
wantErr: false,
wantErr: false,
expected: false,
},
{
name: "Setting an incorrect config",
@@ -268,19 +305,22 @@ func Test_setConfigWithARN(t *testing.T) {
},
arn: "",
},
mockSetConfig: func(kv string) error {
return errors.New("error")
mockSetConfig: func(kv string) (restart bool, err error) {
return false, errors.New("error")
},
wantErr: true,
wantErr: true,
expected: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// mock function response from setConfig()
minioSetConfigKVMock = tt.mockSetConfig
if err := setConfigWithARNAccountID(tt.args.ctx, tt.args.client, tt.args.configName, tt.args.kvs, tt.args.arn); (err != nil) != tt.wantErr {
restart, err := setConfigWithARNAccountID(tt.args.ctx, tt.args.client, tt.args.configName, tt.args.kvs, tt.args.arn)
if (err != nil) != tt.wantErr {
t.Errorf("setConfigWithARNAccountID() error = %v, wantErr %v", err, tt.wantErr)
}
assert.Equal(restart, tt.expected)
})
}
}

View File

@@ -95,7 +95,7 @@ func getNotificationEndpointsResponse(session *models.Principal) (*models.NotifE
return notfEndpointResp, nil
}
func addNotificationEndpoint(ctx context.Context, client MinioAdmin, params *admin_api.AddNotificationEndpointParams) (*models.NotificationEndpoint, error) {
func addNotificationEndpoint(ctx context.Context, client MinioAdmin, params *admin_api.AddNotificationEndpointParams) (*models.SetNotificationEndpointResponse, error) {
configs := []*models.ConfigurationKV{}
var configName string
@@ -133,20 +133,21 @@ func addNotificationEndpoint(ctx context.Context, client MinioAdmin, params *adm
})
}
err := setConfigWithARNAccountID(ctx, client, &configName, configs, *params.Body.AccountID)
needsRestart, err := setConfigWithARNAccountID(ctx, client, &configName, configs, *params.Body.AccountID)
if err != nil {
return nil, err
}
return &models.NotificationEndpoint{
return &models.SetNotificationEndpointResponse{
AccountID: params.Body.AccountID,
Properties: params.Body.Properties,
Service: params.Body.Service,
Restart: needsRestart,
}, nil
}
// getNotificationEndpointsResponse returns a list of notification endpoints in the instance
func getAddNotificationEndpointResponse(session *models.Principal, params *admin_api.AddNotificationEndpointParams) (*models.NotificationEndpoint, *models.Error) {
func getAddNotificationEndpointResponse(session *models.Principal, params *admin_api.AddNotificationEndpointParams) (*models.SetNotificationEndpointResponse, *models.Error) {
mAdmin, err := newMAdminClient(session)
if err != nil {
return nil, prepareError(err)

View File

@@ -39,8 +39,8 @@ func Test_addNotificationEndpoint(t *testing.T) {
tests := []struct {
name string
args args
mockSetConfig func(kv string) error
want *models.NotificationEndpoint
mockSetConfig func(kv string) (restart bool, err error)
want *models.SetNotificationEndpointResponse
wantErr bool
}{
{
@@ -61,10 +61,10 @@ func Test_addNotificationEndpoint(t *testing.T) {
},
},
},
mockSetConfig: func(kv string) error {
return nil
mockSetConfig: func(kv string) (restart bool, err error) {
return false, nil
},
want: &models.NotificationEndpoint{
want: &models.SetNotificationEndpointResponse{
AccountID: swag.String("1"),
Properties: map[string]string{
"host": "localhost",
@@ -72,6 +72,7 @@ func Test_addNotificationEndpoint(t *testing.T) {
"password": "passwrd",
},
Service: "postgres",
Restart: false,
},
wantErr: false,
},
@@ -93,8 +94,8 @@ func Test_addNotificationEndpoint(t *testing.T) {
},
},
},
mockSetConfig: func(kv string) error {
return errors.New("error")
mockSetConfig: func(kv string) (restart bool, err error) {
return false, errors.New("error")
},
want: nil,
wantErr: true,
@@ -117,10 +118,10 @@ func Test_addNotificationEndpoint(t *testing.T) {
},
},
},
mockSetConfig: func(kv string) error {
return nil
mockSetConfig: func(kv string) (restart bool, err error) {
return false, nil
},
want: &models.NotificationEndpoint{
want: &models.SetNotificationEndpointResponse{
AccountID: swag.String("1"),
Properties: map[string]string{
"host": "localhost",
@@ -128,6 +129,7 @@ func Test_addNotificationEndpoint(t *testing.T) {
"password": "passwrd",
},
Service: "mysql",
Restart: false,
},
wantErr: false,
},
@@ -147,15 +149,16 @@ func Test_addNotificationEndpoint(t *testing.T) {
},
},
},
mockSetConfig: func(kv string) error {
return nil
mockSetConfig: func(kv string) (restart bool, err error) {
return false, nil
},
want: &models.NotificationEndpoint{
want: &models.SetNotificationEndpointResponse{
AccountID: swag.String("1"),
Properties: map[string]string{
"brokers": "http://localhost:8080/broker1",
},
Service: "kafka",
Restart: false,
},
wantErr: false,
},
@@ -175,15 +178,16 @@ func Test_addNotificationEndpoint(t *testing.T) {
},
},
},
mockSetConfig: func(kv string) error {
return nil
mockSetConfig: func(kv string) (restart bool, err error) {
return false, nil
},
want: &models.NotificationEndpoint{
want: &models.SetNotificationEndpointResponse{
AccountID: swag.String("1"),
Properties: map[string]string{
"url": "http://localhost:8080/broker1",
},
Service: "amqp",
Restart: false,
},
wantErr: false,
},
@@ -204,16 +208,17 @@ func Test_addNotificationEndpoint(t *testing.T) {
},
},
},
mockSetConfig: func(kv string) error {
return nil
mockSetConfig: func(kv string) (restart bool, err error) {
return false, nil
},
want: &models.NotificationEndpoint{
want: &models.SetNotificationEndpointResponse{
AccountID: swag.String("1"),
Properties: map[string]string{
"broker": "http://localhost:8080/broker1",
"topic": "minio",
},
Service: "mqtt",
Restart: false,
},
wantErr: false,
},
@@ -235,10 +240,10 @@ func Test_addNotificationEndpoint(t *testing.T) {
},
},
},
mockSetConfig: func(kv string) error {
return nil
mockSetConfig: func(kv string) (restart bool, err error) {
return false, nil
},
want: &models.NotificationEndpoint{
want: &models.SetNotificationEndpointResponse{
AccountID: swag.String("1"),
Properties: map[string]string{
"url": "http://localhost:8080/broker1",
@@ -246,6 +251,7 @@ func Test_addNotificationEndpoint(t *testing.T) {
"format": "namespace",
},
Service: "elasticsearch",
Restart: false,
},
wantErr: false,
},
@@ -267,10 +273,10 @@ func Test_addNotificationEndpoint(t *testing.T) {
},
},
},
mockSetConfig: func(kv string) error {
return nil
mockSetConfig: func(kv string) (restart bool, err error) {
return false, nil
},
want: &models.NotificationEndpoint{
want: &models.SetNotificationEndpointResponse{
AccountID: swag.String("1"),
Properties: map[string]string{
"address": "http://localhost:8080/broker1",
@@ -278,6 +284,7 @@ func Test_addNotificationEndpoint(t *testing.T) {
"format": "namespace",
},
Service: "redis",
Restart: false,
},
wantErr: false,
},
@@ -298,16 +305,17 @@ func Test_addNotificationEndpoint(t *testing.T) {
},
},
},
mockSetConfig: func(kv string) error {
return nil
mockSetConfig: func(kv string) (restart bool, err error) {
return false, nil
},
want: &models.NotificationEndpoint{
want: &models.SetNotificationEndpointResponse{
AccountID: swag.String("1"),
Properties: map[string]string{
"address": "http://localhost:8080/broker1",
"subject": "minio",
},
Service: "nats",
Restart: false,
},
wantErr: false,
},
@@ -327,15 +335,16 @@ func Test_addNotificationEndpoint(t *testing.T) {
},
},
},
mockSetConfig: func(kv string) error {
return nil
mockSetConfig: func(kv string) (restart bool, err error) {
return false, nil
},
want: &models.NotificationEndpoint{
want: &models.SetNotificationEndpointResponse{
AccountID: swag.String("1"),
Properties: map[string]string{
"endpoint": "http://localhost:8080/broker1",
},
Service: "webhook",
Restart: false,
},
wantErr: false,
},
@@ -356,16 +365,17 @@ func Test_addNotificationEndpoint(t *testing.T) {
},
},
},
mockSetConfig: func(kv string) error {
return nil
mockSetConfig: func(kv string) (restart bool, err error) {
return false, nil
},
want: &models.NotificationEndpoint{
want: &models.SetNotificationEndpointResponse{
AccountID: swag.String("1"),
Properties: map[string]string{
"nsqd_address": "http://localhost:8080/broker1",
"topic": "minio",
},
Service: "nsq",
Restart: false,
},
wantErr: false,
},
@@ -387,12 +397,45 @@ func Test_addNotificationEndpoint(t *testing.T) {
},
},
},
mockSetConfig: func(kv string) error {
return errors.New("invalid config")
mockSetConfig: func(kv string) (restart bool, err error) {
return false, errors.New("invalid config")
},
want: nil,
wantErr: true,
},
{
name: "valid config, restart required",
args: args{
ctx: context.Background(),
client: client,
params: &admin_api.AddNotificationEndpointParams{
HTTPRequest: nil,
Body: &models.NotificationEndpoint{
AccountID: swag.String("1"),
Properties: map[string]string{
"host": "localhost",
"user": "user",
"password": "passwrd",
},
Service: "postgres",
},
},
},
mockSetConfig: func(kv string) (restart bool, err error) {
return true, nil
},
want: &models.SetNotificationEndpointResponse{
AccountID: swag.String("1"),
Properties: map[string]string{
"host": "localhost",
"user": "user",
"password": "passwrd",
},
Service: "postgres",
Restart: true,
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {

View File

@@ -86,7 +86,7 @@ type MinioAdmin interface {
setPolicy(ctx context.Context, policyName, entityName string, isGroup bool) error
getConfigKV(ctx context.Context, key string) ([]byte, error)
helpConfigKV(ctx context.Context, subSys, key string, envOnly bool) (madmin.Help, error)
setConfigKV(ctx context.Context, kv string) (err error)
setConfigKV(ctx context.Context, kv string) (restart bool, err error)
serviceRestart(ctx context.Context) error
serverInfo(ctx context.Context) (madmin.InfoMessage, error)
startProfiling(ctx context.Context, profiler madmin.ProfilerType) ([]madmin.StartProfilingResult, error)
@@ -202,7 +202,7 @@ func (ac adminClient) helpConfigKV(ctx context.Context, subSys, key string, envO
}
// implements madmin.SetConfigKV()
func (ac adminClient) setConfigKV(ctx context.Context, kv string) (err error) {
func (ac adminClient) setConfigKV(ctx context.Context, kv string) (restart bool, err error) {
return ac.client.SetConfigKV(ctx, kv)
}

View File

@@ -173,7 +173,7 @@ func init() {
"201": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/notificationEndpoint"
"$ref": "#/definitions/setNotificationEndpointResponse"
}
},
"default": {
@@ -1356,8 +1356,11 @@ func init() {
}
],
"responses": {
"204": {
"description": "A successful response."
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/setConfigResponse"
}
},
"default": {
"description": "Generic error response.",
@@ -4824,6 +4827,40 @@ func init() {
}
}
},
"setConfigResponse": {
"type": "object",
"properties": {
"restart": {
"description": "Returns wheter server needs to restart to apply changes or not",
"type": "boolean"
}
}
},
"setNotificationEndpointResponse": {
"type": "object",
"required": [
"service",
"account_id",
"properties"
],
"properties": {
"account_id": {
"type": "string"
},
"properties": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"restart": {
"type": "boolean"
},
"service": {
"$ref": "#/definitions/nofiticationService"
}
}
},
"setPolicyMultipleRequest": {
"type": "object",
"properties": {
@@ -5297,7 +5334,7 @@ func init() {
"201": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/notificationEndpoint"
"$ref": "#/definitions/setNotificationEndpointResponse"
}
},
"default": {
@@ -6480,8 +6517,11 @@ func init() {
}
],
"responses": {
"204": {
"description": "A successful response."
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/setConfigResponse"
}
},
"default": {
"description": "Generic error response.",
@@ -10336,6 +10376,40 @@ func init() {
}
}
},
"setConfigResponse": {
"type": "object",
"properties": {
"restart": {
"description": "Returns wheter server needs to restart to apply changes or not",
"type": "boolean"
}
}
},
"setNotificationEndpointResponse": {
"type": "object",
"required": [
"service",
"account_id",
"properties"
],
"properties": {
"account_id": {
"type": "string"
},
"properties": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"restart": {
"type": "boolean"
},
"service": {
"$ref": "#/definitions/nofiticationService"
}
}
},
"setPolicyMultipleRequest": {
"type": "object",
"properties": {

View File

@@ -42,7 +42,7 @@ type AddNotificationEndpointCreated struct {
/*
In: Body
*/
Payload *models.NotificationEndpoint `json:"body,omitempty"`
Payload *models.SetNotificationEndpointResponse `json:"body,omitempty"`
}
// NewAddNotificationEndpointCreated creates AddNotificationEndpointCreated with default headers values
@@ -52,13 +52,13 @@ func NewAddNotificationEndpointCreated() *AddNotificationEndpointCreated {
}
// WithPayload adds the payload to the add notification endpoint created response
func (o *AddNotificationEndpointCreated) WithPayload(payload *models.NotificationEndpoint) *AddNotificationEndpointCreated {
func (o *AddNotificationEndpointCreated) WithPayload(payload *models.SetNotificationEndpointResponse) *AddNotificationEndpointCreated {
o.Payload = payload
return o
}
// SetPayload sets the payload to the add notification endpoint created response
func (o *AddNotificationEndpointCreated) SetPayload(payload *models.NotificationEndpoint) {
func (o *AddNotificationEndpointCreated) SetPayload(payload *models.SetNotificationEndpointResponse) {
o.Payload = payload
}

View File

@@ -30,28 +30,48 @@ import (
"github.com/minio/console/models"
)
// SetConfigNoContentCode is the HTTP code returned for type SetConfigNoContent
const SetConfigNoContentCode int = 204
// SetConfigOKCode is the HTTP code returned for type SetConfigOK
const SetConfigOKCode int = 200
/*SetConfigNoContent A successful response.
/*SetConfigOK A successful response.
swagger:response setConfigNoContent
swagger:response setConfigOK
*/
type SetConfigNoContent struct {
type SetConfigOK struct {
/*
In: Body
*/
Payload *models.SetConfigResponse `json:"body,omitempty"`
}
// NewSetConfigNoContent creates SetConfigNoContent with default headers values
func NewSetConfigNoContent() *SetConfigNoContent {
// NewSetConfigOK creates SetConfigOK with default headers values
func NewSetConfigOK() *SetConfigOK {
return &SetConfigNoContent{}
return &SetConfigOK{}
}
// WithPayload adds the payload to the set config o k response
func (o *SetConfigOK) WithPayload(payload *models.SetConfigResponse) *SetConfigOK {
o.Payload = payload
return o
}
// SetPayload sets the payload to the set config o k response
func (o *SetConfigOK) SetPayload(payload *models.SetConfigResponse) {
o.Payload = payload
}
// WriteResponse to the client
func (o *SetConfigNoContent) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
func (o *SetConfigOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses
rw.WriteHeader(204)
rw.WriteHeader(200)
if o.Payload != nil {
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}
}
/*SetConfigDefault Generic error response.