Compare commits

...

10 Commits

Author SHA1 Message Date
Minio Trusted
aeaa1a23ce update to v0.3.22 2020-09-07 17:14:21 -07:00
Lenin Alevski
a8d403a216 fix bug for tenant image pull credentials (#271)
Co-authored-by: Daniel Valdivia <hola@danielvaldivia.com>
2020-09-06 23:20:27 -07:00
Minio Trusted
7bd898b2c7 update to v0.3.21 2020-09-05 23:50:46 -07:00
Lenin Alevski
dad66db49a Support for adding prometheus annotations on update minio tenant (#269) 2020-09-05 23:48:51 -07:00
Daniel Valdivia
adf3f929a4 Add Tenant Deletion Date to tenant responses (#270) 2020-09-05 23:37:01 -07:00
Lenin Alevski
3b23e877b5 delete unnecessary logs (#268) 2020-09-05 17:39:21 -07:00
Minio Trusted
af4bebb6eb fix go mod tidy 2020-09-04 20:42:30 -07:00
Minio Trusted
8530eb5368 update to v0.3.20 2020-09-04 20:41:46 -07:00
Lenin Alevski
0ba1e76400 centralize errors on a single error function (#266)
prepareError receives an array of errors and return *model.Error object
with a message and error code, we can extend this function to add more
error types/code
2020-09-04 20:32:57 -07:00
Daniel Valdivia
94096ee657 Fix Bug Creating Tenant Pull Secret. (#267) 2020-09-04 17:09:17 -07:00
34 changed files with 1259 additions and 603 deletions

4
go.mod
View File

@@ -19,14 +19,14 @@ require (
github.com/minio/mc v0.0.0-20200808005614-7e52c104bee1
github.com/minio/minio v0.0.0-20200808024306-2a9819aff876
github.com/minio/minio-go/v7 v7.0.5-0.20200807085956-d7db33ea7618
github.com/minio/operator v0.0.0-20200806194125-c2ff646f4af1
github.com/minio/operator v0.0.0-20200904194631-b8aa01dc5d70
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect
github.com/secure-io/sio-go v0.3.1
github.com/stretchr/testify v1.6.1
github.com/unrolled/secure v1.0.7
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de
golang.org/x/net v0.0.0-20200707034311-ab3426394381
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
gopkg.in/yaml.v2 v2.3.0
k8s.io/api v0.18.6
k8s.io/apimachinery v0.18.6

677
go.sum

File diff suppressed because it is too large Load Diff

View File

@@ -15,7 +15,7 @@ spec:
serviceAccountName: console-sa
containers:
- name: console
image: minio/console:v0.3.19
image: minio/console:v0.3.22
imagePullPolicy: "IfNotPresent"
args:
- server

View File

@@ -15,7 +15,7 @@ spec:
serviceAccountName: console-sa
containers:
- name: console
image: minio/console:v0.3.19
image: minio/console:v0.3.22
imagePullPolicy: "IfNotPresent"
env:
- name: CONSOLE_OPERATOR_MODE

View File

@@ -35,7 +35,7 @@ import (
type Error struct {
// code
Code int64 `json:"code,omitempty"`
Code int32 `json:"code,omitempty"`
// message
// Required: true

View File

@@ -35,12 +35,21 @@ import (
// swagger:model tenant
type Tenant struct {
// console image
ConsoleImage string `json:"console_image,omitempty"`
// creation date
CreationDate string `json:"creation_date,omitempty"`
// current state
CurrentState string `json:"currentState,omitempty"`
// deletion date
DeletionDate string `json:"deletion_date,omitempty"`
// enable prometheus
EnablePrometheus bool `json:"enable_prometheus,omitempty"`
// image
Image string `json:"image,omitempty"`

View File

@@ -38,6 +38,9 @@ type TenantList struct {
// current state
CurrentState string `json:"currentState,omitempty"`
// deletion date
DeletionDate string `json:"deletion_date,omitempty"`
// instance count
InstanceCount int64 `json:"instance_count,omitempty"`

View File

@@ -1,113 +0,0 @@
// Code generated by go-swagger; DO NOT EDIT.
// This file is part of MinIO Console Server
// Copyright (c) 2020 MinIO, Inc.
//
// 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 models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// UpdateCertificatesRequest update certificates request
//
// swagger:model updateCertificatesRequest
type UpdateCertificatesRequest struct {
// console
Console *KeyPairConfiguration `json:"console,omitempty"`
// minio
Minio *KeyPairConfiguration `json:"minio,omitempty"`
}
// Validate validates this update certificates request
func (m *UpdateCertificatesRequest) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateConsole(formats); err != nil {
res = append(res, err)
}
if err := m.validateMinio(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *UpdateCertificatesRequest) validateConsole(formats strfmt.Registry) error {
if swag.IsZero(m.Console) { // not required
return nil
}
if m.Console != nil {
if err := m.Console.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("console")
}
return err
}
}
return nil
}
func (m *UpdateCertificatesRequest) validateMinio(formats strfmt.Registry) error {
if swag.IsZero(m.Minio) { // not required
return nil
}
if m.Minio != nil {
if err := m.Minio.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("minio")
}
return err
}
}
return nil
}
// MarshalBinary interface implementation
func (m *UpdateCertificatesRequest) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *UpdateCertificatesRequest) UnmarshalBinary(b []byte) error {
var res UpdateCertificatesRequest
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -38,6 +38,9 @@ type UpdateTenantRequest struct {
// Pattern: ^((.*?)/(.*?):(.+))$
ConsoleImage string `json:"console_image,omitempty"`
// enable prometheus
EnablePrometheus bool `json:"enable_prometheus,omitempty"`
// image
// Pattern: ^((.*?)/(.*?):(.+))$
Image string `json:"image,omitempty"`

View File

@@ -18,11 +18,9 @@ package restapi
import (
"context"
"log"
"time"
"github.com/go-openapi/runtime/middleware"
"github.com/go-openapi/swag"
"github.com/minio/console/models"
"github.com/minio/console/restapi/operations"
"github.com/minio/console/restapi/operations/admin_api"
@@ -33,7 +31,7 @@ func registerAdminArnsHandlers(api *operations.ConsoleAPI) {
api.AdminAPIArnListHandler = admin_api.ArnListHandlerFunc(func(params admin_api.ArnListParams, session *models.Principal) middleware.Responder {
arnsResp, err := getArnsResponse(session)
if err != nil {
return admin_api.NewArnListDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return admin_api.NewArnListDefault(int(err.Code)).WithPayload(err)
}
return admin_api.NewArnListOK().WithPayload(arnsResp)
})
@@ -53,11 +51,10 @@ func getArns(ctx context.Context, client MinioAdmin) (*models.ArnsResponse, erro
}
// getArnsResponse returns a list of active arns in the instance
func getArnsResponse(session *models.Principal) (*models.ArnsResponse, error) {
func getArnsResponse(session *models.Principal) (*models.ArnsResponse, *models.Error) {
mAdmin, err := newMAdminClient(session)
if err != nil {
log.Println("error creating Madmin Client:", err)
return nil, err
return nil, prepareError(err)
}
// create a minioClient interface implementation
// defining the client to be used
@@ -68,8 +65,7 @@ func getArnsResponse(session *models.Principal) (*models.ArnsResponse, error) {
// serialize output
arnsList, err := getArns(ctx, adminClient)
if err != nil {
log.Println("error getting arn list:", err)
return nil, err
return nil, prepareError(err)
}
return arnsList, nil
}

View File

@@ -19,7 +19,6 @@ package restapi
import (
"context"
"fmt"
"log"
"strings"
"github.com/go-openapi/runtime/middleware"
@@ -36,7 +35,7 @@ func registerConfigHandlers(api *operations.ConsoleAPI) {
api.AdminAPIListConfigHandler = admin_api.ListConfigHandlerFunc(func(params admin_api.ListConfigParams, session *models.Principal) middleware.Responder {
configListResp, err := getListConfigResponse(session)
if err != nil {
return admin_api.NewListConfigDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return admin_api.NewListConfigDefault(int(err.Code)).WithPayload(err)
}
return admin_api.NewListConfigOK().WithPayload(configListResp)
})
@@ -44,14 +43,14 @@ func registerConfigHandlers(api *operations.ConsoleAPI) {
api.AdminAPIConfigInfoHandler = admin_api.ConfigInfoHandlerFunc(func(params admin_api.ConfigInfoParams, session *models.Principal) middleware.Responder {
config, err := getConfigResponse(session, params)
if err != nil {
return admin_api.NewConfigInfoDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return admin_api.NewConfigInfoDefault(int(err.Code)).WithPayload(err)
}
return admin_api.NewConfigInfoOK().WithPayload(config)
})
// 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 {
return admin_api.NewSetConfigDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return admin_api.NewSetConfigDefault(int(err.Code)).WithPayload(err)
}
return admin_api.NewSetConfigNoContent()
})
@@ -76,11 +75,10 @@ func listConfig(client MinioAdmin) ([]*models.ConfigDescription, error) {
}
// getListConfigResponse performs listConfig() and serializes it to the handler's output
func getListConfigResponse(session *models.Principal) (*models.ListConfigResponse, error) {
func getListConfigResponse(session *models.Principal) (*models.ListConfigResponse, *models.Error) {
mAdmin, err := newMAdminClient(session)
if err != nil {
log.Println("error creating Madmin Client:", err)
return nil, err
return nil, prepareError(err)
}
// create a MinIO Admin Client interface implementation
// defining the client to be used
@@ -88,8 +86,7 @@ func getListConfigResponse(session *models.Principal) (*models.ListConfigRespons
configDescs, err := listConfig(adminClient)
if err != nil {
log.Println("error listing configurations:", err)
return nil, err
return nil, prepareError(err)
}
listGroupsResponse := &models.ListConfigResponse{
Configurations: configDescs,
@@ -127,11 +124,10 @@ func getConfig(client MinioAdmin, name string) ([]*models.ConfigurationKV, error
}
// getConfigResponse performs getConfig() and serializes it to the handler's output
func getConfigResponse(session *models.Principal, params admin_api.ConfigInfoParams) (*models.Configuration, error) {
func getConfigResponse(session *models.Principal, params admin_api.ConfigInfoParams) (*models.Configuration, *models.Error) {
mAdmin, err := newMAdminClient(session)
if err != nil {
log.Println("error creating Madmin Client:", err)
return nil, err
return nil, prepareError(err)
}
// create a MinIO Admin Client interface implementation
// defining the client to be used
@@ -139,8 +135,7 @@ func getConfigResponse(session *models.Principal, params admin_api.ConfigInfoPar
configkv, err := getConfig(adminClient, params.Name)
if err != nil {
log.Println("error getting configuration:", err)
return nil, err
return nil, prepareError(err)
}
configurationObj := &models.Configuration{
Name: params.Name,
@@ -180,11 +175,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) error {
func setConfigResponse(session *models.Principal, name string, configRequest *models.SetConfigRequest) *models.Error {
mAdmin, err := newMAdminClient(session)
if err != nil {
log.Println("error creating Madmin Client:", err)
return err
return prepareError(err)
}
// create a MinIO Admin Client interface implementation
// defining the client to be used
@@ -194,8 +188,7 @@ func setConfigResponse(session *models.Principal, name string, configRequest *mo
ctx := context.Background()
if err := setConfigWithARNAccountID(ctx, adminClient, &configName, configRequest.KeyValues, configRequest.ArnResourceID); err != nil {
log.Println("error listing configurations:", err)
return err
return prepareError(err)
}
return nil
}

View File

@@ -22,7 +22,6 @@ import (
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime/middleware"
"github.com/go-openapi/swag"
"github.com/minio/console/restapi/operations"
"github.com/minio/minio/pkg/madmin"
@@ -36,7 +35,7 @@ func registerGroupsHandlers(api *operations.ConsoleAPI) {
api.AdminAPIListGroupsHandler = admin_api.ListGroupsHandlerFunc(func(params admin_api.ListGroupsParams, session *models.Principal) middleware.Responder {
listGroupsResponse, err := getListGroupsResponse(session)
if err != nil {
return admin_api.NewListGroupsDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return admin_api.NewListGroupsDefault(int(err.Code)).WithPayload(err)
}
return admin_api.NewListGroupsOK().WithPayload(listGroupsResponse)
})
@@ -44,21 +43,21 @@ func registerGroupsHandlers(api *operations.ConsoleAPI) {
api.AdminAPIGroupInfoHandler = admin_api.GroupInfoHandlerFunc(func(params admin_api.GroupInfoParams, session *models.Principal) middleware.Responder {
groupInfo, err := getGroupInfoResponse(session, params)
if err != nil {
return admin_api.NewGroupInfoDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return admin_api.NewGroupInfoDefault(int(err.Code)).WithPayload(err)
}
return admin_api.NewGroupInfoOK().WithPayload(groupInfo)
})
// Add Group
api.AdminAPIAddGroupHandler = admin_api.AddGroupHandlerFunc(func(params admin_api.AddGroupParams, session *models.Principal) middleware.Responder {
if err := getAddGroupResponse(session, params.Body); err != nil {
return admin_api.NewAddGroupDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return admin_api.NewAddGroupDefault(int(err.Code)).WithPayload(err)
}
return admin_api.NewAddGroupCreated()
})
// Remove Group
api.AdminAPIRemoveGroupHandler = admin_api.RemoveGroupHandlerFunc(func(params admin_api.RemoveGroupParams, session *models.Principal) middleware.Responder {
if err := getRemoveGroupResponse(session, params); err != nil {
return admin_api.NewRemoveGroupDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return admin_api.NewRemoveGroupDefault(int(err.Code)).WithPayload(err)
}
return admin_api.NewRemoveGroupNoContent()
})
@@ -66,7 +65,7 @@ func registerGroupsHandlers(api *operations.ConsoleAPI) {
api.AdminAPIUpdateGroupHandler = admin_api.UpdateGroupHandlerFunc(func(params admin_api.UpdateGroupParams, session *models.Principal) middleware.Responder {
groupUpdateResp, err := getUpdateGroupResponse(session, params)
if err != nil {
return admin_api.NewUpdateGroupDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return admin_api.NewUpdateGroupDefault(int(err.Code)).WithPayload(err)
}
return admin_api.NewUpdateGroupOK().WithPayload(groupUpdateResp)
})
@@ -82,12 +81,11 @@ func listGroups(ctx context.Context, client MinioAdmin) (*[]string, error) {
}
// getListGroupsResponse performs listGroups() and serializes it to the handler's output
func getListGroupsResponse(session *models.Principal) (*models.ListGroupsResponse, error) {
func getListGroupsResponse(session *models.Principal) (*models.ListGroupsResponse, *models.Error) {
ctx := context.Background()
mAdmin, err := newMAdminClient(session)
if err != nil {
log.Println("error creating Madmin Client:", err)
return nil, err
return nil, prepareError(err)
}
// create a MinIO Admin Client interface implementation
// defining the client to be used
@@ -95,8 +93,7 @@ func getListGroupsResponse(session *models.Principal) (*models.ListGroupsRespons
groups, err := listGroups(ctx, adminClient)
if err != nil {
log.Println("error listing groups:", err)
return nil, err
return nil, prepareError(err)
}
// serialize output
listGroupsResponse := &models.ListGroupsResponse{
@@ -116,12 +113,11 @@ func groupInfo(ctx context.Context, client MinioAdmin, group string) (*madmin.Gr
}
// getGroupInfoResponse performs groupInfo() and serializes it to the handler's output
func getGroupInfoResponse(session *models.Principal, params admin_api.GroupInfoParams) (*models.Group, error) {
func getGroupInfoResponse(session *models.Principal, params admin_api.GroupInfoParams) (*models.Group, *models.Error) {
ctx := context.Background()
mAdmin, err := newMAdminClient(session)
if err != nil {
log.Println("error creating Madmin Client:", err)
return nil, err
return nil, prepareError(err)
}
// create a MinIO Admin Client interface implementation
// defining the client to be used
@@ -129,8 +125,7 @@ func getGroupInfoResponse(session *models.Principal, params admin_api.GroupInfoP
groupDesc, err := groupInfo(ctx, adminClient, params.Name)
if err != nil {
log.Println("error getting group info:", err)
return nil, err
return nil, prepareError(err)
}
groupResponse := &models.Group{
@@ -157,26 +152,23 @@ func addGroup(ctx context.Context, client MinioAdmin, group string, members []st
}
// getAddGroupResponse performs addGroup() and serializes it to the handler's output
func getAddGroupResponse(session *models.Principal, params *models.AddGroupRequest) error {
func getAddGroupResponse(session *models.Principal, params *models.AddGroupRequest) *models.Error {
ctx := context.Background()
// AddGroup request needed to proceed
if params == nil {
log.Println("error AddGroup body not in request")
return errors.New(500, "error AddGroup body not in request")
return prepareError(errGroupBodyNotInRequest)
}
mAdmin, err := newMAdminClient(session)
if err != nil {
log.Println("error creating Madmin Client:", err)
return err
return prepareError(err)
}
// create a MinIO Admin Client interface implementation
// defining the client to be used
adminClient := adminClient{client: mAdmin}
if err := addGroup(ctx, adminClient, *params.Group, params.Members); err != nil {
log.Println("error adding group:", err)
return err
return prepareError(err)
}
return nil
}
@@ -196,25 +188,22 @@ func removeGroup(ctx context.Context, client MinioAdmin, group string) error {
}
// getRemoveGroupResponse performs removeGroup() and serializes it to the handler's output
func getRemoveGroupResponse(session *models.Principal, params admin_api.RemoveGroupParams) error {
func getRemoveGroupResponse(session *models.Principal, params admin_api.RemoveGroupParams) *models.Error {
ctx := context.Background()
if params.Name == "" {
log.Println("error group name not in request")
return errors.New(500, "error group name not in request")
return prepareError(errGroupNameNotInRequest)
}
mAdmin, err := newMAdminClient(session)
if err != nil {
log.Println("error creating Madmin Client:", err)
return err
return prepareError(err)
}
// create a MinIO Admin Client interface implementation
// defining the client to be used
adminClient := adminClient{client: mAdmin}
if err := removeGroup(ctx, adminClient, params.Name); err != nil {
log.Println("error removing group:", err)
return err
return prepareError(err)
}
return nil
}
@@ -276,23 +265,21 @@ func setGroupStatus(ctx context.Context, client MinioAdmin, group, status string
// getUpdateGroupResponse updates a group by adding or removing it's members depending on the request,
// also sets the group's status if status in the request is different than the current one.
// Then serializes the output to be used by the handler.
func getUpdateGroupResponse(session *models.Principal, params admin_api.UpdateGroupParams) (*models.Group, error) {
func getUpdateGroupResponse(session *models.Principal, params admin_api.UpdateGroupParams) (*models.Group, *models.Error) {
ctx := context.Background()
if params.Name == "" {
log.Println("error group name not in request")
return nil, errors.New(500, "error group name not in request")
return nil, prepareError(errGroupNameNotInRequest)
}
if params.Body == nil {
log.Println("error body not in request")
return nil, errors.New(500, "error body not in request")
return nil, prepareError(errGroupBodyNotInRequest)
}
expectedGroupUpdate := params.Body
groupName := params.Name
mAdmin, err := newMAdminClient(session)
if err != nil {
log.Println("error creating Madmin Client:", err)
return nil, err
return nil, prepareError(err)
}
// create a MinIO Admin Client interface implementation
// defining the client to be used
@@ -300,8 +287,7 @@ func getUpdateGroupResponse(session *models.Principal, params admin_api.UpdateGr
groupUpdated, err := groupUpdate(ctx, adminClient, groupName, expectedGroupUpdate)
if err != nil {
log.Println("error updating group:", err)
return nil, err
return nil, prepareError(err)
}
groupResponse := &models.Group{
Name: groupUpdated.Name,

View File

@@ -18,11 +18,9 @@ package restapi
import (
"context"
"log"
"time"
"github.com/go-openapi/runtime/middleware"
"github.com/go-openapi/swag"
"github.com/minio/console/models"
"github.com/minio/console/restapi/operations"
"github.com/minio/console/restapi/operations/admin_api"
@@ -33,7 +31,7 @@ func registerAdminInfoHandlers(api *operations.ConsoleAPI) {
api.AdminAPIAdminInfoHandler = admin_api.AdminInfoHandlerFunc(func(params admin_api.AdminInfoParams, session *models.Principal) middleware.Responder {
infoResp, err := getAdminInfoResponse(session)
if err != nil {
return admin_api.NewAdminInfoDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return admin_api.NewAdminInfoDefault(int(err.Code)).WithPayload(err)
}
return admin_api.NewAdminInfoOK().WithPayload(infoResp)
})
@@ -72,11 +70,10 @@ func getAdminInfo(ctx context.Context, client MinioAdmin) (*usageInfo, error) {
}
// getAdminInfoResponse returns the response containing total buckets, objects and usage.
func getAdminInfoResponse(session *models.Principal) (*models.AdminInfoResponse, error) {
func getAdminInfoResponse(session *models.Principal) (*models.AdminInfoResponse, *models.Error) {
mAdmin, err := newMAdminClient(session)
if err != nil {
log.Println("error creating Madmin Client:", err)
return nil, err
return nil, prepareError(err)
}
// create a minioClient interface implementation
// defining the client to be used
@@ -87,8 +84,7 @@ func getAdminInfoResponse(session *models.Principal) (*models.AdminInfoResponse,
// serialize output
usage, err := getAdminInfo(ctx, adminClient)
if err != nil {
log.Println("error getting information:", err)
return nil, err
return nil, prepareError(err)
}
sessionResp := &models.AdminInfoResponse{
Buckets: usage.Buckets,

View File

@@ -18,7 +18,6 @@ package restapi
import (
"context"
"log"
"sort"
"github.com/minio/console/cluster"
@@ -26,7 +25,6 @@ import (
"errors"
"github.com/go-openapi/runtime/middleware"
"github.com/go-openapi/swag"
"github.com/minio/console/models"
"github.com/minio/console/restapi/operations"
"github.com/minio/console/restapi/operations/admin_api"
@@ -39,7 +37,7 @@ func registerNodesHandlers(api *operations.ConsoleAPI) {
api.AdminAPIGetMaxAllocatableMemHandler = admin_api.GetMaxAllocatableMemHandlerFunc(func(params admin_api.GetMaxAllocatableMemParams, principal *models.Principal) middleware.Responder {
resp, err := getMaxAllocatableMemoryResponse(principal, params.NumNodes)
if err != nil {
return admin_api.NewGetMaxAllocatableMemDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return admin_api.NewGetMaxAllocatableMemDefault(int(err.Code)).WithPayload(err)
}
return admin_api.NewGetMaxAllocatableMemOK().WithPayload(resp)
})
@@ -123,19 +121,16 @@ func min(x, y int64) int64 {
return x
}
func getMaxAllocatableMemoryResponse(session *models.Principal, numNodes int32) (*models.MaxAllocatableMemResponse, error) {
func getMaxAllocatableMemoryResponse(session *models.Principal, numNodes int32) (*models.MaxAllocatableMemResponse, *models.Error) {
ctx := context.Background()
client, err := cluster.K8sClient(session.SessionToken)
if err != nil {
log.Println("error getting k8sClient:", err)
return nil, err
return nil, prepareError(err)
}
clusterResources, err := getMaxAllocatableMemory(ctx, client.CoreV1(), numNodes)
if err != nil {
log.Println("error getting cluster's resources:", err)
return nil, err
return nil, prepareError(err)
}
return clusterResources, nil
}

View File

@@ -19,11 +19,9 @@ package restapi
import (
"context"
"errors"
"log"
"time"
"github.com/go-openapi/runtime/middleware"
"github.com/go-openapi/swag"
"github.com/minio/console/models"
"github.com/minio/console/restapi/operations"
"github.com/minio/console/restapi/operations/admin_api"
@@ -34,7 +32,7 @@ func registerAdminNotificationEndpointsHandlers(api *operations.ConsoleAPI) {
api.AdminAPINotificationEndpointListHandler = admin_api.NotificationEndpointListHandlerFunc(func(params admin_api.NotificationEndpointListParams, session *models.Principal) middleware.Responder {
notifEndpoints, err := getNotificationEndpointsResponse(session)
if err != nil {
return admin_api.NewNotificationEndpointListDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return admin_api.NewNotificationEndpointListDefault(int(err.Code)).WithPayload(err)
}
return admin_api.NewNotificationEndpointListOK().WithPayload(notifEndpoints)
})
@@ -42,7 +40,7 @@ func registerAdminNotificationEndpointsHandlers(api *operations.ConsoleAPI) {
api.AdminAPIAddNotificationEndpointHandler = admin_api.AddNotificationEndpointHandlerFunc(func(params admin_api.AddNotificationEndpointParams, session *models.Principal) middleware.Responder {
notifEndpoints, err := getAddNotificationEndpointResponse(session, &params)
if err != nil {
return admin_api.NewAddNotificationEndpointDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return admin_api.NewAddNotificationEndpointDefault(int(err.Code)).WithPayload(err)
}
return admin_api.NewAddNotificationEndpointCreated().WithPayload(notifEndpoints)
})
@@ -78,11 +76,10 @@ func getNotificationEndpoints(ctx context.Context, client MinioAdmin) (*models.N
}
// getNotificationEndpointsResponse returns a list of notification endpoints in the instance
func getNotificationEndpointsResponse(session *models.Principal) (*models.NotifEndpointResponse, error) {
func getNotificationEndpointsResponse(session *models.Principal) (*models.NotifEndpointResponse, *models.Error) {
mAdmin, err := newMAdminClient(session)
if err != nil {
log.Println("error creating Madmin Client:", err)
return nil, err
return nil, prepareError(err)
}
// create a minioClient interface implementation
// defining the client to be used
@@ -93,8 +90,7 @@ func getNotificationEndpointsResponse(session *models.Principal) (*models.NotifE
// serialize output
notfEndpointResp, err := getNotificationEndpoints(ctx, adminClient)
if err != nil {
log.Println("error getting notification endpoint list:", err)
return nil, err
return nil, prepareError(err)
}
return notfEndpointResp, nil
}
@@ -150,11 +146,10 @@ func addNotificationEndpoint(ctx context.Context, client MinioAdmin, params *adm
}
// getNotificationEndpointsResponse returns a list of notification endpoints in the instance
func getAddNotificationEndpointResponse(session *models.Principal, params *admin_api.AddNotificationEndpointParams) (*models.NotificationEndpoint, error) {
func getAddNotificationEndpointResponse(session *models.Principal, params *admin_api.AddNotificationEndpointParams) (*models.NotificationEndpoint, *models.Error) {
mAdmin, err := newMAdminClient(session)
if err != nil {
log.Println("error creating Madmin Client:", err)
return nil, err
return nil, prepareError(err)
}
// create a minioClient interface implementation
// defining the client to be used
@@ -165,8 +160,7 @@ func getAddNotificationEndpointResponse(session *models.Principal, params *admin
// serialize output
notfEndpointResp, err := addNotificationEndpoint(ctx, adminClient, params)
if err != nil {
log.Println("error getting notification endpoint list:", err)
return nil, err
return nil, prepareError(err)
}
return notfEndpointResp, nil
}

View File

@@ -22,10 +22,7 @@ import (
"encoding/json"
"log"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime/middleware"
"github.com/go-openapi/swag"
"github.com/minio/console/models"
"github.com/minio/console/restapi/operations"
"github.com/minio/console/restapi/operations/admin_api"
@@ -37,7 +34,7 @@ func registersPoliciesHandler(api *operations.ConsoleAPI) {
api.AdminAPIListPoliciesHandler = admin_api.ListPoliciesHandlerFunc(func(params admin_api.ListPoliciesParams, session *models.Principal) middleware.Responder {
listPoliciesResponse, err := getListPoliciesResponse(session)
if err != nil {
return admin_api.NewListPoliciesDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return admin_api.NewListPoliciesDefault(int(err.Code)).WithPayload(err)
}
return admin_api.NewListPoliciesOK().WithPayload(listPoliciesResponse)
})
@@ -45,7 +42,7 @@ func registersPoliciesHandler(api *operations.ConsoleAPI) {
api.AdminAPIPolicyInfoHandler = admin_api.PolicyInfoHandlerFunc(func(params admin_api.PolicyInfoParams, session *models.Principal) middleware.Responder {
policyInfo, err := getPolicyInfoResponse(session, params)
if err != nil {
return admin_api.NewPolicyInfoDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return admin_api.NewPolicyInfoDefault(int(err.Code)).WithPayload(err)
}
return admin_api.NewPolicyInfoOK().WithPayload(policyInfo)
})
@@ -53,24 +50,21 @@ func registersPoliciesHandler(api *operations.ConsoleAPI) {
api.AdminAPIAddPolicyHandler = admin_api.AddPolicyHandlerFunc(func(params admin_api.AddPolicyParams, session *models.Principal) middleware.Responder {
policyResponse, err := getAddPolicyResponse(session, params.Body)
if err != nil {
return admin_api.NewAddPolicyDefault(500).WithPayload(&models.Error{
Code: 500,
Message: swag.String(err.Error()),
})
return admin_api.NewAddPolicyDefault(int(err.Code)).WithPayload(err)
}
return admin_api.NewAddPolicyCreated().WithPayload(policyResponse)
})
// Remove Policy
api.AdminAPIRemovePolicyHandler = admin_api.RemovePolicyHandlerFunc(func(params admin_api.RemovePolicyParams, session *models.Principal) middleware.Responder {
if err := getRemovePolicyResponse(session, params); err != nil {
return admin_api.NewRemovePolicyDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return admin_api.NewRemovePolicyDefault(int(err.Code)).WithPayload(err)
}
return admin_api.NewRemovePolicyNoContent()
})
// Set Policy
api.AdminAPISetPolicyHandler = admin_api.SetPolicyHandlerFunc(func(params admin_api.SetPolicyParams, session *models.Principal) middleware.Responder {
if err := getSetPolicyResponse(session, params.Name, params.Body); err != nil {
return admin_api.NewSetPolicyDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return admin_api.NewSetPolicyDefault(int(err.Code)).WithPayload(err)
}
return admin_api.NewSetPolicyNoContent()
})
@@ -97,12 +91,11 @@ func listPolicies(ctx context.Context, client MinioAdmin) ([]*models.Policy, err
}
// getListPoliciesResponse performs listPolicies() and serializes it to the handler's output
func getListPoliciesResponse(session *models.Principal) (*models.ListPoliciesResponse, error) {
func getListPoliciesResponse(session *models.Principal) (*models.ListPoliciesResponse, *models.Error) {
ctx := context.Background()
mAdmin, err := newMAdminClient(session)
if err != nil {
log.Println("error creating Madmin Client:", err)
return nil, err
return nil, prepareError(err)
}
// create a MinIO Admin Client interface implementation
// defining the client to be used
@@ -110,8 +103,7 @@ func getListPoliciesResponse(session *models.Principal) (*models.ListPoliciesRes
policies, err := listPolicies(ctx, adminClient)
if err != nil {
log.Println("error listing policies:", err)
return nil, err
return nil, prepareError(err)
}
// serialize output
listPoliciesResponse := &models.ListPoliciesResponse{
@@ -131,24 +123,21 @@ func removePolicy(ctx context.Context, client MinioAdmin, name string) error {
}
// getRemovePolicyResponse() performs removePolicy() and serializes it to the handler's output
func getRemovePolicyResponse(session *models.Principal, params admin_api.RemovePolicyParams) error {
func getRemovePolicyResponse(session *models.Principal, params admin_api.RemovePolicyParams) *models.Error {
ctx := context.Background()
if params.Name == "" {
log.Println("error policy name not in request")
return errors.New(500, "error policy name not in request")
return prepareError(errPolicyNameNotInRequest)
}
mAdmin, err := newMAdminClient(session)
if err != nil {
log.Println("error creating Madmin Client:", err)
return err
return prepareError(err)
}
// create a MinIO Admin Client interface implementation
// defining the client to be used
adminClient := adminClient{client: mAdmin}
if err := removePolicy(ctx, adminClient, params.Name); err != nil {
log.Println("error removing policy:", err)
return err
return prepareError(err)
}
return nil
}
@@ -173,25 +162,23 @@ func addPolicy(ctx context.Context, client MinioAdmin, name, policy string) (*mo
}
// getAddPolicyResponse performs addPolicy() and serializes it to the handler's output
func getAddPolicyResponse(session *models.Principal, params *models.AddPolicyRequest) (*models.Policy, error) {
func getAddPolicyResponse(session *models.Principal, params *models.AddPolicyRequest) (*models.Policy, *models.Error) {
ctx := context.Background()
if params == nil {
log.Println("error AddPolicy body not in request")
return nil, errors.New(500, "error AddPolicy body not in request")
return nil, prepareError(errPolicyBodyNotInRequest)
}
mAdmin, err := newMAdminClient(session)
if err != nil {
log.Println("error creating Madmin Client:", err)
return nil, err
return nil, prepareError(err)
}
// create a MinIO Admin Client interface implementation
// defining the client to be used
adminClient := adminClient{client: mAdmin}
policy, err := addPolicy(ctx, adminClient, *params.Name, *params.Policy)
if err != nil {
log.Println("error adding policy")
return nil, err
return nil, prepareError(err)
}
return policy, nil
}
@@ -213,20 +200,18 @@ func policyInfo(ctx context.Context, client MinioAdmin, name string) (*models.Po
}
// getPolicyInfoResponse performs policyInfo() and serializes it to the handler's output
func getPolicyInfoResponse(session *models.Principal, params admin_api.PolicyInfoParams) (*models.Policy, error) {
func getPolicyInfoResponse(session *models.Principal, params admin_api.PolicyInfoParams) (*models.Policy, *models.Error) {
ctx := context.Background()
mAdmin, err := newMAdminClient(session)
if err != nil {
log.Println("error creating Madmin Client:", err)
return nil, err
return nil, prepareError(err)
}
// create a MinIO Admin Client interface implementation
// defining the client to be used
adminClient := adminClient{client: mAdmin}
policy, err := policyInfo(ctx, adminClient, params.Name)
if err != nil {
log.Println("error getting group info:", err)
return nil, err
return nil, prepareError(err)
}
return policy, nil
}
@@ -244,24 +229,21 @@ func setPolicy(ctx context.Context, client MinioAdmin, name, entityName string,
}
// getSetPolicyResponse() performs setPolicy() and serializes it to the handler's output
func getSetPolicyResponse(session *models.Principal, name string, params *models.SetPolicyRequest) error {
func getSetPolicyResponse(session *models.Principal, name string, params *models.SetPolicyRequest) *models.Error {
ctx := context.Background()
if name == "" {
log.Println("error policy name not in request")
return errors.New(500, "error policy name not in request")
return prepareError(errPolicyNameNotInRequest)
}
mAdmin, err := newMAdminClient(session)
if err != nil {
log.Println("error creating Madmin Client:", err)
return err
return prepareError(err)
}
// create a MinIO Admin Client interface implementation
// defining the client to be used
adminClient := adminClient{client: mAdmin}
if err := setPolicy(ctx, adminClient, name, *params.EntityName, params.EntityType); err != nil {
log.Println("error setting policy:", err)
return err
return prepareError(err)
}
return nil
}

View File

@@ -22,10 +22,8 @@ import (
"log"
"net/http"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
"github.com/go-openapi/runtime/middleware"
"github.com/go-openapi/swag"
"github.com/minio/console/models"
"github.com/minio/console/restapi/operations"
"github.com/minio/console/restapi/operations/admin_api"
@@ -37,7 +35,7 @@ func registerProfilingHandler(api *operations.ConsoleAPI) {
api.AdminAPIProfilingStartHandler = admin_api.ProfilingStartHandlerFunc(func(params admin_api.ProfilingStartParams, session *models.Principal) middleware.Responder {
profilingStartResponse, err := getProfilingStartResponse(session, params.Body)
if err != nil {
return admin_api.NewProfilingStartDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return admin_api.NewProfilingStartDefault(int(err.Code)).WithPayload(err)
}
return admin_api.NewProfilingStartCreated().WithPayload(profilingStartResponse)
})
@@ -45,7 +43,7 @@ func registerProfilingHandler(api *operations.ConsoleAPI) {
api.AdminAPIProfilingStopHandler = admin_api.ProfilingStopHandlerFunc(func(params admin_api.ProfilingStopParams, session *models.Principal) middleware.Responder {
profilingStopResponse, err := getProfilingStopResponse(session)
if err != nil {
return admin_api.NewProfilingStopDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return admin_api.NewProfilingStopDefault(int(err.Code)).WithPayload(err)
}
// Custom response writer to set the content-disposition header to tell the
// HTTP client the name and extension of the file we are returning
@@ -90,24 +88,21 @@ func startProfiling(ctx context.Context, client MinioAdmin, profilerType models.
}
// getProfilingStartResponse performs startProfiling() and serializes it to the handler's output
func getProfilingStartResponse(session *models.Principal, params *models.ProfilingStartRequest) (*models.StartProfilingList, error) {
func getProfilingStartResponse(session *models.Principal, params *models.ProfilingStartRequest) (*models.StartProfilingList, *models.Error) {
ctx := context.Background()
if params == nil {
log.Println("error profiling type not in body request")
return nil, errors.New(500, "error AddPolicy body not in request")
return nil, prepareError(errPolicyBodyNotInRequest)
}
mAdmin, err := newMAdminClient(session)
if err != nil {
log.Println("error creating Madmin Client:", err)
return nil, err
return nil, prepareError(err)
}
// create a MinIO Admin Client interface implementation
// defining the client to be used
adminClient := adminClient{client: mAdmin}
profilingItems, err := startProfiling(ctx, adminClient, params.Type)
if err != nil {
log.Println("error starting profiling:", err)
return nil, err
return nil, prepareError(err)
}
profilingList := &models.StartProfilingList{
StartResults: profilingItems,
@@ -127,20 +122,18 @@ func stopProfiling(ctx context.Context, client MinioAdmin) (io.ReadCloser, error
}
// getProfilingStopResponse() performs setPolicy() and serializes it to the handler's output
func getProfilingStopResponse(session *models.Principal) (io.ReadCloser, error) {
func getProfilingStopResponse(session *models.Principal) (io.ReadCloser, *models.Error) {
ctx := context.Background()
mAdmin, err := newMAdminClient(session)
if err != nil {
log.Println("error creating Madmin Client:", err)
return nil, err
return nil, prepareError(err)
}
// create a MinIO Admin Client interface implementation
// defining the client to be used
adminClient := adminClient{client: mAdmin}
profilingData, err := stopProfiling(ctx, adminClient)
if err != nil {
log.Println("error stopping profiling:", err)
return nil, err
return nil, prepareError(err)
}
return profilingData, nil
}

View File

@@ -18,11 +18,9 @@ package restapi
import (
"context"
"log"
"time"
"github.com/go-openapi/runtime/middleware"
"github.com/go-openapi/swag"
"github.com/minio/console/models"
"github.com/minio/console/restapi/operations"
@@ -33,7 +31,7 @@ func registerServiceHandlers(api *operations.ConsoleAPI) {
// Restart Service
api.AdminAPIRestartServiceHandler = admin_api.RestartServiceHandlerFunc(func(params admin_api.RestartServiceParams, session *models.Principal) middleware.Responder {
if err := getRestartServiceResponse(session); err != nil {
return admin_api.NewRestartServiceDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return admin_api.NewRestartServiceDefault(int(err.Code)).WithPayload(err)
}
return admin_api.NewRestartServiceNoContent()
})
@@ -61,20 +59,18 @@ func serviceRestart(ctx context.Context, client MinioAdmin) error {
}
// getRestartServiceResponse performs serviceRestart()
func getRestartServiceResponse(session *models.Principal) error {
func getRestartServiceResponse(session *models.Principal) *models.Error {
ctx := context.Background()
mAdmin, err := newMAdminClient(session)
if err != nil {
log.Println("error creating Madmin Client:", err)
return err
return prepareError(err)
}
// create a MinIO Admin Client interface implementation
// defining the client to be used
adminClient := adminClient{client: mAdmin}
if err := serviceRestart(ctx, adminClient); err != nil {
log.Println("error restarting service:", err)
return err
return prepareError(err)
}
return nil
}

View File

@@ -64,8 +64,7 @@ func registerTenantHandlers(api *operations.ConsoleAPI) {
api.AdminAPICreateTenantHandler = admin_api.CreateTenantHandlerFunc(func(params admin_api.CreateTenantParams, session *models.Principal) middleware.Responder {
resp, err := getTenantCreatedResponse(session, params)
if err != nil {
log.Println(err)
return admin_api.NewCreateTenantDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return admin_api.NewCreateTenantDefault(int(err.Code)).WithPayload(err)
}
return admin_api.NewCreateTenantOK().WithPayload(resp)
})
@@ -73,8 +72,7 @@ func registerTenantHandlers(api *operations.ConsoleAPI) {
api.AdminAPIListAllTenantsHandler = admin_api.ListAllTenantsHandlerFunc(func(params admin_api.ListAllTenantsParams, session *models.Principal) middleware.Responder {
resp, err := getListAllTenantsResponse(session, params)
if err != nil {
log.Println(err)
return admin_api.NewListTenantsDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return admin_api.NewListTenantsDefault(int(err.Code)).WithPayload(err)
}
return admin_api.NewListTenantsOK().WithPayload(resp)
@@ -83,8 +81,7 @@ func registerTenantHandlers(api *operations.ConsoleAPI) {
api.AdminAPIListTenantsHandler = admin_api.ListTenantsHandlerFunc(func(params admin_api.ListTenantsParams, session *models.Principal) middleware.Responder {
resp, err := getListTenantsResponse(session, params)
if err != nil {
log.Println(err)
return admin_api.NewListTenantsDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return admin_api.NewListTenantsDefault(int(err.Code)).WithPayload(err)
}
return admin_api.NewListTenantsOK().WithPayload(resp)
@@ -93,8 +90,7 @@ func registerTenantHandlers(api *operations.ConsoleAPI) {
api.AdminAPITenantInfoHandler = admin_api.TenantInfoHandlerFunc(func(params admin_api.TenantInfoParams, session *models.Principal) middleware.Responder {
resp, err := getTenantInfoResponse(session, params)
if err != nil {
log.Println(err)
return admin_api.NewTenantInfoDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return admin_api.NewTenantInfoDefault(int(err.Code)).WithPayload(err)
}
return admin_api.NewTenantInfoOK().WithPayload(resp)
@@ -104,8 +100,7 @@ func registerTenantHandlers(api *operations.ConsoleAPI) {
api.AdminAPIDeleteTenantHandler = admin_api.DeleteTenantHandlerFunc(func(params admin_api.DeleteTenantParams, session *models.Principal) middleware.Responder {
err := getDeleteTenantResponse(session, params)
if err != nil {
log.Println(err)
return admin_api.NewTenantInfoDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return admin_api.NewTenantInfoDefault(int(err.Code)).WithPayload(err)
}
return admin_api.NewTenantInfoOK()
@@ -115,8 +110,7 @@ func registerTenantHandlers(api *operations.ConsoleAPI) {
api.AdminAPIUpdateTenantHandler = admin_api.UpdateTenantHandlerFunc(func(params admin_api.UpdateTenantParams, session *models.Principal) middleware.Responder {
err := getUpdateTenantResponse(session, params)
if err != nil {
log.Println(err)
return admin_api.NewUpdateTenantDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String("Unable to update tenant")})
return admin_api.NewUpdateTenantDefault(int(err.Code)).WithPayload(err)
}
return admin_api.NewUpdateTenantCreated()
})
@@ -125,8 +119,7 @@ func registerTenantHandlers(api *operations.ConsoleAPI) {
api.AdminAPITenantAddZoneHandler = admin_api.TenantAddZoneHandlerFunc(func(params admin_api.TenantAddZoneParams, session *models.Principal) middleware.Responder {
err := getTenantAddZoneResponse(session, params)
if err != nil {
log.Println(err)
return admin_api.NewTenantAddZoneDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String("Unable to add zone")})
return admin_api.NewTenantAddZoneDefault(int(err.Code)).WithPayload(err)
}
return admin_api.NewTenantAddZoneCreated()
})
@@ -135,8 +128,7 @@ func registerTenantHandlers(api *operations.ConsoleAPI) {
api.AdminAPIGetTenantUsageHandler = admin_api.GetTenantUsageHandlerFunc(func(params admin_api.GetTenantUsageParams, session *models.Principal) middleware.Responder {
payload, err := getTenantUsageResponse(session, params)
if err != nil {
log.Println(err)
return admin_api.NewGetTenantUsageDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String("Unable to get tenant usage")})
return admin_api.NewGetTenantUsageDefault(int(err.Code)).WithPayload(err)
}
return admin_api.NewGetTenantUsageOK().WithPayload(payload)
})
@@ -145,8 +137,7 @@ func registerTenantHandlers(api *operations.ConsoleAPI) {
api.AdminAPITenantUpdateZonesHandler = admin_api.TenantUpdateZonesHandlerFunc(func(params admin_api.TenantUpdateZonesParams, session *models.Principal) middleware.Responder {
resp, err := getTenantUpdateZoneResponse(session, params)
if err != nil {
log.Println(err)
return admin_api.NewTenantUpdateZonesDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return admin_api.NewTenantUpdateZonesDefault(int(err.Code)).WithPayload(err)
}
return admin_api.NewTenantUpdateZonesOK().WithPayload(resp)
})
@@ -155,8 +146,7 @@ func registerTenantHandlers(api *operations.ConsoleAPI) {
api.AdminAPITenantUpdateCertificateHandler = admin_api.TenantUpdateCertificateHandlerFunc(func(params admin_api.TenantUpdateCertificateParams, session *models.Principal) middleware.Responder {
err := getTenantUpdateCertificatesResponse(session, params)
if err != nil {
log.Println(err)
return admin_api.NewGetTenantUsageDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String("Unable to update tenant certificates")})
return admin_api.NewGetTenantUsageDefault(int(err.Code)).WithPayload(err)
}
return admin_api.NewTenantUpdateCertificateCreated()
})
@@ -165,23 +155,22 @@ func registerTenantHandlers(api *operations.ConsoleAPI) {
api.AdminAPITenantUpdateEncryptionHandler = admin_api.TenantUpdateEncryptionHandlerFunc(func(params admin_api.TenantUpdateEncryptionParams, session *models.Principal) middleware.Responder {
err := getTenantUpdateEncryptionResponse(session, params)
if err != nil {
log.Println(err)
return admin_api.NewGetTenantUsageDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String("Unable to update encryption configuration")})
return admin_api.NewGetTenantUsageDefault(int(err.Code)).WithPayload(err)
}
return admin_api.NewTenantUpdateCertificateCreated()
})
}
// getDeleteTenantResponse gets the output of deleting a minio instance
func getDeleteTenantResponse(session *models.Principal, params admin_api.DeleteTenantParams) error {
func getDeleteTenantResponse(session *models.Principal, params admin_api.DeleteTenantParams) *models.Error {
opClientClientSet, err := cluster.OperatorClient(session.SessionToken)
if err != nil {
return err
return prepareError(err)
}
// get Kubernetes Client
clientset, err := cluster.K8sClient(session.SessionToken)
if err != nil {
return err
return prepareError(err)
}
opClient := &operatorClient{
client: opClientClientSet,
@@ -190,7 +179,10 @@ func getDeleteTenantResponse(session *models.Principal, params admin_api.DeleteT
if params.Body != nil {
deleteTenantPVCs = params.Body.DeletePvcs
}
return deleteTenantAction(context.Background(), opClient, clientset.CoreV1(), params.Namespace, params.Tenant, deleteTenantPVCs)
if err = deleteTenantAction(context.Background(), opClient, clientset.CoreV1(), params.Namespace, params.Tenant, deleteTenantPVCs); err != nil {
return prepareError(err)
}
return nil
}
// deleteTenantAction performs the actions of deleting a tenant
@@ -265,35 +257,70 @@ func getTenant(ctx context.Context, operatorClient OperatorClientI, namespace, t
return minInst, nil
}
func isPrometheusEnabled(annotations map[string]string) bool {
if annotations == nil {
return false
}
// if one of the following prometheus annotations are not present
// we consider the tenant as not integrated with prometheus
if _, ok := annotations[prometheusPath]; !ok {
return false
}
if _, ok := annotations[prometheusPort]; !ok {
return false
}
if _, ok := annotations[prometheusScrape]; !ok {
return false
}
return true
}
func getTenantInfo(tenant *operator.Tenant) *models.Tenant {
var zones []*models.Zone
consoleImage := ""
var totalSize int64
for _, z := range tenant.Spec.Zones {
zones = append(zones, parseTenantZone(&z))
zoneSize := int64(z.Servers) * int64(z.VolumesPerServer) * z.VolumeClaimTemplate.Spec.Resources.Requests.Storage().Value()
totalSize = totalSize + zoneSize
}
var deletion string
if tenant.ObjectMeta.DeletionTimestamp != nil {
deletion = tenant.ObjectMeta.DeletionTimestamp.String()
}
if tenant.HasConsoleEnabled() {
consoleImage = tenant.Spec.Console.Image
}
if tenant.Spec.Metadata == nil {
tenant.Spec.Metadata = &metav1.ObjectMeta{
Annotations: map[string]string{},
}
}
return &models.Tenant{
CreationDate: tenant.ObjectMeta.CreationTimestamp.String(),
Name: tenant.Name,
TotalSize: totalSize,
CurrentState: tenant.Status.CurrentState,
Zones: zones,
Namespace: tenant.ObjectMeta.Namespace,
Image: tenant.Spec.Image,
CreationDate: tenant.ObjectMeta.CreationTimestamp.String(),
DeletionDate: deletion,
Name: tenant.Name,
TotalSize: totalSize,
CurrentState: tenant.Status.CurrentState,
Zones: zones,
Namespace: tenant.ObjectMeta.Namespace,
Image: tenant.Spec.Image,
ConsoleImage: consoleImage,
EnablePrometheus: isPrometheusEnabled(tenant.Spec.Metadata.Annotations),
}
}
func getTenantInfoResponse(session *models.Principal, params admin_api.TenantInfoParams) (*models.Tenant, error) {
func getTenantInfoResponse(session *models.Principal, params admin_api.TenantInfoParams) (*models.Tenant, *models.Error) {
// 5 seconds timeout
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
opClientClientSet, err := cluster.OperatorClient(session.SessionToken)
if err != nil {
return nil, err
return nil, prepareError(err)
}
opClient := &operatorClient{
@@ -302,8 +329,7 @@ func getTenantInfoResponse(session *models.Principal, params admin_api.TenantInf
minTenant, err := getTenant(ctx, opClient, params.Namespace, params.Tenant)
if err != nil {
log.Println("error getting minioTenant:", err)
return nil, err
return nil, prepareError(err)
}
info := getTenantInfo(minTenant)
@@ -339,8 +365,14 @@ func listTenants(ctx context.Context, operatorClient OperatorClientI, namespace
}
}
var deletion string
if tenant.ObjectMeta.DeletionTimestamp != nil {
deletion = tenant.ObjectMeta.DeletionTimestamp.String()
}
tenants = append(tenants, &models.TenantList{
CreationDate: tenant.ObjectMeta.CreationTimestamp.String(),
DeletionDate: deletion,
Name: tenant.ObjectMeta.Name,
ZoneCount: int64(len(tenant.Spec.Zones)),
InstanceCount: instanceCount,
@@ -357,44 +389,40 @@ func listTenants(ctx context.Context, operatorClient OperatorClientI, namespace
}, nil
}
func getListAllTenantsResponse(session *models.Principal, params admin_api.ListAllTenantsParams) (*models.ListTenantsResponse, error) {
func getListAllTenantsResponse(session *models.Principal, params admin_api.ListAllTenantsParams) (*models.ListTenantsResponse, *models.Error) {
ctx := context.Background()
opClientClientSet, err := cluster.OperatorClient(session.SessionToken)
if err != nil {
log.Println("error getting operator client:", err)
return nil, err
return nil, prepareError(err)
}
opClient := &operatorClient{
client: opClientClientSet,
}
listT, err := listTenants(ctx, opClient, "", params.Limit)
if err != nil {
log.Println("error listing tenants:", err)
return nil, err
return nil, prepareError(err)
}
return listT, nil
}
// getListTenantsResponse list tenants by namespace
func getListTenantsResponse(session *models.Principal, params admin_api.ListTenantsParams) (*models.ListTenantsResponse, error) {
func getListTenantsResponse(session *models.Principal, params admin_api.ListTenantsParams) (*models.ListTenantsResponse, *models.Error) {
ctx := context.Background()
opClientClientSet, err := cluster.OperatorClient(session.SessionToken)
if err != nil {
log.Println("error getting operator client:", err)
return nil, err
return nil, prepareError(err)
}
opClient := &operatorClient{
client: opClientClientSet,
}
listT, err := listTenants(ctx, opClient, params.Namespace, params.Limit)
if err != nil {
log.Println("error listing tenants:", err)
return nil, err
return nil, prepareError(err)
}
return listT, nil
}
func getTenantCreatedResponse(session *models.Principal, params admin_api.CreateTenantParams) (*models.CreateTenantResponse, error) {
func getTenantCreatedResponse(session *models.Principal, params admin_api.CreateTenantParams) (*models.CreateTenantResponse, *models.Error) {
tenantReq := params.Body
minioImage := tenantReq.Image
ctx := context.Background()
@@ -412,7 +440,7 @@ func getTenantCreatedResponse(session *models.Principal, params admin_api.Create
client: clientSet,
}
if err != nil {
return nil, err
return nil, prepareError(err)
}
ns := *tenantReq.Namespace
@@ -448,14 +476,14 @@ func getTenantCreatedResponse(session *models.Principal, params admin_api.Create
_, err = clientSet.CoreV1().Secrets(ns).Create(ctx, &instanceSecret, metav1.CreateOptions{})
if err != nil {
return nil, err
return nil, prepareError(err)
}
var envrionmentVariables []corev1.EnvVar
// Check the Erasure Coding Parity for validity and pass it to Tenant
if tenantReq.ErasureCodingParity > 0 {
if tenantReq.ErasureCodingParity < 2 && tenantReq.ErasureCodingParity > 8 {
return nil, errors.New("invalid Erasure Coding Value")
return nil, prepareError(errorInvalidErasureCodingValue)
}
envrionmentVariables = append(envrionmentVariables, corev1.EnvVar{
Name: "MINIO_STORAGE_CLASS_STANDARD",
@@ -545,7 +573,7 @@ func getTenantCreatedResponse(session *models.Principal, params admin_api.Create
externalCertSecretName := fmt.Sprintf("%s-instance-external-certificates", secretName)
externalCertSecret, err := createOrReplaceExternalCertSecret(ctx, &k8sClient, ns, tenantReq.TLS.Minio, externalCertSecretName, tenantName)
if err != nil {
return nil, err
return nil, prepareError(err)
}
minInst.Spec.ExternalCertSecret = externalCertSecret
}
@@ -561,13 +589,13 @@ func getTenantCreatedResponse(session *models.Principal, params admin_api.Create
tenantExternalClientCertSecretName := fmt.Sprintf("%s-tenant-external-client-cert", secretName)
minInst.Spec.ExternalClientCertSecret, err = createOrReplaceExternalCertSecret(ctx, &k8sClient, ns, tenantReq.Encryption.Client, tenantExternalClientCertSecretName, tenantName)
if err != nil {
return nil, err
return nil, prepareError(errorGeneric)
}
}
// KES configuration for Tenant instance
minInst.Spec.KES, err = getKESConfiguration(ctx, &k8sClient, ns, tenantReq.Encryption, secretName, tenantName, minInst.Spec.RequestAutoCert)
if err != nil {
return nil, err
return nil, prepareError(errorGeneric)
}
}
@@ -626,10 +654,10 @@ func getTenantCreatedResponse(session *models.Principal, params admin_api.Create
_, err = clientSet.CoreV1().Secrets(ns).Create(ctx, &instanceSecret, metav1.CreateOptions{})
if err != nil {
return nil, err
return nil, prepareError(errorGeneric)
}
const consoleVersion = "minio/console:v0.3.19"
const consoleVersion = "minio/console:v0.3.22"
minInst.Spec.Console = &operator.ConsoleConfiguration{
Replicas: 1,
Image: consoleVersion,
@@ -645,7 +673,7 @@ func getTenantCreatedResponse(session *models.Principal, params admin_api.Create
externalCertSecretName := fmt.Sprintf("%s-console-external-certificates", secretName)
externalCertSecret, err := createOrReplaceExternalCertSecret(ctx, &k8sClient, ns, tenantReq.TLS.Console, externalCertSecretName, tenantName)
if err != nil {
return nil, err
return nil, prepareError(errorGeneric)
}
minInst.Spec.Console.ExternalCertSecret = externalCertSecret
}
@@ -670,7 +698,7 @@ func getTenantCreatedResponse(session *models.Principal, params admin_api.Create
for _, zone := range tenantReq.Zones {
zone, err := parseTenantZoneRequest(zone, annotations)
if err != nil {
return nil, err
return nil, prepareError(err)
}
minInst.Spec.Zones = append(minInst.Spec.Zones, *zone)
}
@@ -686,8 +714,7 @@ func getTenantCreatedResponse(session *models.Principal, params admin_api.Create
if tenantReq.ImagePullSecret != "" {
imagePullSecret = tenantReq.ImagePullSecret
} else if imagePullSecret, err = setImageRegistry(ctx, tenantName, tenantReq.ImageRegistry, clientSet.CoreV1(), ns); err != nil {
log.Println("error setting image registry secret:", err)
return nil, err
return nil, prepareError(err)
}
// pass the image pull secret to the Tenant
if imagePullSecret != "" {
@@ -698,9 +725,9 @@ func getTenantCreatedResponse(session *models.Principal, params admin_api.Create
// prometheus annotations support
if tenantReq.EnablePrometheus != nil && *tenantReq.EnablePrometheus && minInst.Spec.Metadata != nil && minInst.Spec.Metadata.Annotations != nil {
minInst.Spec.Metadata.Annotations["prometheus.io/path"] = "/minio/prometheus/metrics"
minInst.Spec.Metadata.Annotations["prometheus.io/port"] = fmt.Sprint(operator.MinIOPort)
minInst.Spec.Metadata.Annotations["prometheus.io/scrape"] = "true"
minInst.Spec.Metadata.Annotations[prometheusPath] = "/minio/prometheus/metrics"
minInst.Spec.Metadata.Annotations[prometheusPort] = fmt.Sprint(operator.MinIOPort)
minInst.Spec.Metadata.Annotations[prometheusScrape] = "true"
}
// set console image if provided
@@ -710,19 +737,19 @@ func getTenantCreatedResponse(session *models.Principal, params admin_api.Create
opClient, err := cluster.OperatorClient(session.SessionToken)
if err != nil {
return nil, err
return nil, prepareError(err)
}
_, err = opClient.MinioV1().Tenants(ns).Create(context.Background(), &minInst, metav1.CreateOptions{})
if err != nil {
return nil, err
return nil, prepareError(err)
}
// Integratrions
if os.Getenv("GKE_INTEGRATION") != "" {
err := gkeIntegration(clientSet, tenantName, ns, session.SessionToken)
if err != nil {
return nil, err
return nil, prepareError(err)
}
}
response := &models.CreateTenantResponse{
@@ -765,33 +792,33 @@ func setImageRegistry(ctx context.Context, tenantName string, req *models.ImageR
}
pullSecretName := fmt.Sprintf("%s-regcred", tenantName)
instanceSecret := corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: pullSecretName,
Labels: map[string]string{
operator.TenantLabel: tenantName,
},
},
Data: map[string][]byte{
corev1.DockerConfigJsonKey: []byte(string(imRegistryJSON)),
},
Type: corev1.SecretTypeDockerConfigJson,
secretCredentials := map[string][]byte{
corev1.DockerConfigJsonKey: []byte(string(imRegistryJSON)),
}
// Get or Create secret if it doesn't exist
_, err = clientset.Secrets(namespace).Get(ctx, pullSecretName, metav1.GetOptions{})
currentSecret, err := clientset.Secrets(namespace).Get(ctx, pullSecretName, metav1.GetOptions{})
if err != nil {
if k8sErrors.IsNotFound(err) {
instanceSecret := corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: pullSecretName,
Labels: map[string]string{
operator.TenantLabel: tenantName,
},
},
Data: secretCredentials,
Type: corev1.SecretTypeDockerConfigJson,
}
_, err = clientset.Secrets(namespace).Create(ctx, &instanceSecret, metav1.CreateOptions{})
if err != nil {
return "", err
}
return "", nil
return pullSecretName, nil
}
return "", err
}
_, err = clientset.Secrets(namespace).Update(ctx, &instanceSecret, metav1.UpdateOptions{})
currentSecret.Data = secretCredentials
_, err = clientset.Secrets(namespace).Update(ctx, currentSecret, metav1.UpdateOptions{})
if err != nil {
return "", err
}
@@ -834,6 +861,40 @@ func updateTenantAction(ctx context.Context, operatorClient OperatorClientI, cli
}
}
// Prometheus Annotations
if minInst.Spec.Metadata == nil {
minInst.Spec.Metadata = &metav1.ObjectMeta{
Annotations: map[string]string{},
}
}
currentAnnotations := minInst.Spec.Metadata.Annotations
prometheusAnnotations := map[string]string{
prometheusPath: "/minio/prometheus/metrics",
prometheusPort: fmt.Sprint(operator.MinIOPort),
prometheusScrape: "true",
}
if params.Body.EnablePrometheus && minInst.Spec.Metadata != nil && currentAnnotations != nil {
// add prometheus annotations to the tenant
minInst.Spec.Metadata.Annotations = addAnnotations(currentAnnotations, prometheusAnnotations)
// add prometheus annotations to the each zone
if minInst.Spec.Zones != nil {
for _, zone := range minInst.Spec.Zones {
zoneAnnotations := zone.VolumeClaimTemplate.GetObjectMeta().GetAnnotations()
zone.VolumeClaimTemplate.GetObjectMeta().SetAnnotations(addAnnotations(zoneAnnotations, prometheusAnnotations))
}
}
} else {
// remove prometheus annotations to the tenant
minInst.Spec.Metadata.Annotations = removeAnnotations(currentAnnotations, prometheusAnnotations)
// add prometheus annotations from each zone
if minInst.Spec.Zones != nil {
for _, zone := range minInst.Spec.Zones {
zoneAnnotations := zone.VolumeClaimTemplate.GetObjectMeta().GetAnnotations()
zone.VolumeClaimTemplate.GetObjectMeta().SetAnnotations(removeAnnotations(zoneAnnotations, prometheusAnnotations))
}
}
}
payloadBytes, err := json.Marshal(minInst)
if err != nil {
return err
@@ -845,19 +906,39 @@ func updateTenantAction(ctx context.Context, operatorClient OperatorClientI, cli
return nil
}
func getUpdateTenantResponse(session *models.Principal, params admin_api.UpdateTenantParams) error {
// addAnnotations will merge two annotation maps
func addAnnotations(annotationsOne, annotationsTwo map[string]string) map[string]string {
if annotationsOne == nil {
annotationsOne = map[string]string{}
}
for key, value := range annotationsTwo {
annotationsOne[key] = value
}
return annotationsOne
}
// removeAnnotations will remove keys from the first annotations map based on the second one
func removeAnnotations(annotationsOne, annotationsTwo map[string]string) map[string]string {
if annotationsOne == nil {
annotationsOne = map[string]string{}
}
for key := range annotationsTwo {
delete(annotationsOne, key)
}
return annotationsOne
}
func getUpdateTenantResponse(session *models.Principal, params admin_api.UpdateTenantParams) *models.Error {
ctx := context.Background()
opClientClientSet, err := cluster.OperatorClient(session.SessionToken)
if err != nil {
log.Println("error getting operator client:", err)
return err
return prepareError(err)
}
// get Kubernetes Client
clientset, err := cluster.K8sClient(session.SessionToken)
clientSet, err := cluster.K8sClient(session.SessionToken)
if err != nil {
return err
return prepareError(err)
}
opClient := &operatorClient{
client: opClientClientSet,
}
@@ -866,10 +947,8 @@ func getUpdateTenantResponse(session *models.Principal, params admin_api.UpdateT
Timeout: 4 * time.Second,
},
}
if err := updateTenantAction(ctx, opClient, clientset.CoreV1(), httpC, params.Namespace, params); err != nil {
log.Println("error patching Tenant:", err)
return err
if err := updateTenantAction(ctx, opClient, clientSet.CoreV1(), httpC, params.Namespace, params); err != nil {
return prepareError(err, errors.New("unable to update tenant"))
}
return nil
}
@@ -899,51 +978,46 @@ func addTenantZone(ctx context.Context, operatorClient OperatorClientI, params a
return nil
}
func getTenantAddZoneResponse(session *models.Principal, params admin_api.TenantAddZoneParams) error {
func getTenantAddZoneResponse(session *models.Principal, params admin_api.TenantAddZoneParams) *models.Error {
ctx := context.Background()
opClientClientSet, err := cluster.OperatorClient(session.SessionToken)
if err != nil {
log.Println("error getting operator client:", err)
return err
return prepareError(err)
}
opClient := &operatorClient{
client: opClientClientSet,
}
if err := addTenantZone(ctx, opClient, params); err != nil {
log.Println("error patching Tenant:", err)
return err
return prepareError(err, errors.New("unable to add zone"))
}
return nil
}
// getTenantUsageResponse returns the usage of a tenant
func getTenantUsageResponse(session *models.Principal, params admin_api.GetTenantUsageParams) (*models.TenantUsage, error) {
func getTenantUsageResponse(session *models.Principal, params admin_api.GetTenantUsageParams) (*models.TenantUsage, *models.Error) {
// 5 seconds timeout
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
opClientClientSet, err := cluster.OperatorClient(session.SessionToken)
if err != nil {
log.Println("error operator client", err)
return nil, err
return nil, prepareError(err, errorUnableToGetTenantUsage)
}
clientset, err := cluster.K8sClient(session.SessionToken)
clientSet, err := cluster.K8sClient(session.SessionToken)
if err != nil {
log.Println("error getting k8sClient:", err)
return nil, err
return nil, prepareError(err, errorUnableToGetTenantUsage)
}
opClient := &operatorClient{
client: opClientClientSet,
}
k8sClient := &k8sClient{
client: clientset,
client: clientSet,
}
minTenant, err := getTenant(ctx, opClient, params.Namespace, params.Tenant)
if err != nil {
log.Println("error getting minioTenant:", err)
return nil, err
return nil, prepareError(err, errorUnableToGetTenantUsage)
}
minTenant.EnsureDefaults()
tenantScheme := getTenantScheme(minTenant)
@@ -959,8 +1033,7 @@ func getTenantUsageResponse(session *models.Principal, params admin_api.GetTenan
tenantScheme,
true)
if err != nil {
log.Println("error getting tenant's admin client:", err)
return nil, err
return nil, prepareError(err, errorUnableToGetTenantUsage)
}
// create a minioClient interface implementation
// defining the client to be used
@@ -968,8 +1041,7 @@ func getTenantUsageResponse(session *models.Principal, params admin_api.GetTenan
// serialize output
adminInfo, err := getAdminInfo(ctx, adminClient)
if err != nil {
log.Println("error getting admin info:", err)
return nil, err
return nil, prepareError(err, errorUnableToGetTenantUsage)
}
info := &models.TenantUsage{Used: adminInfo.Usage, DiskUsed: adminInfo.DisksUsage}
return info, nil
@@ -1390,12 +1462,11 @@ func parseNodeSelectorTerm(term *corev1.NodeSelectorTerm) *models.NodeSelectorTe
return &t
}
func getTenantUpdateZoneResponse(session *models.Principal, params admin_api.TenantUpdateZonesParams) (*models.Tenant, error) {
func getTenantUpdateZoneResponse(session *models.Principal, params admin_api.TenantUpdateZonesParams) (*models.Tenant, *models.Error) {
ctx := context.Background()
opClientClientSet, err := cluster.OperatorClient(session.SessionToken)
if err != nil {
log.Println("error getting operator client:", err)
return nil, err
return nil, prepareError(err)
}
opClient := &operatorClient{
@@ -1405,7 +1476,7 @@ func getTenantUpdateZoneResponse(session *models.Principal, params admin_api.Ten
t, err := updateTenantZones(ctx, opClient, params.Namespace, params.Tenant, params.Body.Zones)
if err != nil {
log.Println("error updating Tenant's zones:", err)
return nil, err
return nil, prepareError(err)
}
// parse it to models.Tenant

View File

@@ -81,25 +81,25 @@ func tenantUpdateCertificates(ctx context.Context, operatorClient OperatorClient
}
// getTenantUpdateCertificatesResponse wrapper of tenantUpdateCertificates
func getTenantUpdateCertificatesResponse(session *models.Principal, params admin_api.TenantUpdateCertificateParams) error {
func getTenantUpdateCertificatesResponse(session *models.Principal, params admin_api.TenantUpdateCertificateParams) *models.Error {
ctx := context.Background()
// get Kubernetes Client
clientSet, err := cluster.K8sClient(session.SessionToken)
if err != nil {
return err
return prepareError(err, errorUnableToUpdateTenantCertificates)
}
k8sClient := k8sClient{
client: clientSet,
}
opClientClientSet, err := cluster.OperatorClient(session.SessionToken)
if err != nil {
return err
return prepareError(err, errorUnableToUpdateTenantCertificates)
}
opClient := operatorClient{
client: opClientClientSet,
}
if err := tenantUpdateCertificates(ctx, &opClient, &k8sClient, params.Namespace, params); err != nil {
return err
return prepareError(err, errorUnableToUpdateTenantCertificates)
}
return nil
}
@@ -157,25 +157,25 @@ func tenantUpdateEncryption(ctx context.Context, operatorClient OperatorClientI,
}
// getTenantUpdateEncryptionResponse is a wrapper for tenantUpdateEncryption
func getTenantUpdateEncryptionResponse(session *models.Principal, params admin_api.TenantUpdateEncryptionParams) error {
func getTenantUpdateEncryptionResponse(session *models.Principal, params admin_api.TenantUpdateEncryptionParams) *models.Error {
ctx := context.Background()
// get Kubernetes Client
clientSet, err := cluster.K8sClient(session.SessionToken)
if err != nil {
return err
return prepareError(err, errorUpdatingEncryptionConfig)
}
k8sClient := k8sClient{
client: clientSet,
}
opClientClientSet, err := cluster.OperatorClient(session.SessionToken)
if err != nil {
return err
return prepareError(err, errorUpdatingEncryptionConfig)
}
opClient := operatorClient{
client: opClientClientSet,
}
if err := tenantUpdateEncryption(ctx, &opClient, &k8sClient, params.Namespace, params); err != nil {
return err
return prepareError(err, errorUpdatingEncryptionConfig)
}
return nil
}

View File

@@ -1,3 +1,19 @@
// This file is part of MinIO Console Server
// Copyright (c) 2020 MinIO, Inc.
//
// 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 restapi
import (

View File

@@ -871,7 +871,7 @@ func Test_UpdateTenantAction(t *testing.T) {
},
params: admin_api.UpdateTenantParams{
Body: &models.UpdateTenantRequest{
ConsoleImage: "minio/console:v0.3.19",
ConsoleImage: "minio/console:v0.3.22",
},
},
},

View File

@@ -19,7 +19,6 @@ package restapi
import (
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime/middleware"
"github.com/go-openapi/swag"
"github.com/minio/console/models"
"github.com/minio/console/restapi/operations"
"github.com/minio/console/restapi/operations/admin_api"
@@ -36,7 +35,7 @@ func registerUsersHandlers(api *operations.ConsoleAPI) {
api.AdminAPIListUsersHandler = admin_api.ListUsersHandlerFunc(func(params admin_api.ListUsersParams, session *models.Principal) middleware.Responder {
listUsersResponse, err := getListUsersResponse(session)
if err != nil {
return admin_api.NewListUsersDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return admin_api.NewListUsersDefault(int(err.Code)).WithPayload(err)
}
return admin_api.NewListUsersOK().WithPayload(listUsersResponse)
})
@@ -44,7 +43,7 @@ func registerUsersHandlers(api *operations.ConsoleAPI) {
api.AdminAPIAddUserHandler = admin_api.AddUserHandlerFunc(func(params admin_api.AddUserParams, session *models.Principal) middleware.Responder {
userResponse, err := getUserAddResponse(session, params)
if err != nil {
return admin_api.NewAddUserDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return admin_api.NewAddUserDefault(int(err.Code)).WithPayload(err)
}
return admin_api.NewAddUserCreated().WithPayload(userResponse)
})
@@ -52,7 +51,7 @@ func registerUsersHandlers(api *operations.ConsoleAPI) {
api.AdminAPIRemoveUserHandler = admin_api.RemoveUserHandlerFunc(func(params admin_api.RemoveUserParams, session *models.Principal) middleware.Responder {
err := getRemoveUserResponse(session, params)
if err != nil {
return admin_api.NewRemoveUserDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return admin_api.NewRemoveUserDefault(int(err.Code)).WithPayload(err)
}
return admin_api.NewRemoveUserNoContent()
})
@@ -60,7 +59,7 @@ func registerUsersHandlers(api *operations.ConsoleAPI) {
api.AdminAPIUpdateUserGroupsHandler = admin_api.UpdateUserGroupsHandlerFunc(func(params admin_api.UpdateUserGroupsParams, session *models.Principal) middleware.Responder {
userUpdateResponse, err := getUpdateUserGroupsResponse(session, params)
if err != nil {
return admin_api.NewUpdateUserGroupsDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return admin_api.NewUpdateUserGroupsDefault(int(err.Code)).WithPayload(err)
}
return admin_api.NewUpdateUserGroupsOK().WithPayload(userUpdateResponse)
@@ -69,7 +68,7 @@ func registerUsersHandlers(api *operations.ConsoleAPI) {
api.AdminAPIGetUserInfoHandler = admin_api.GetUserInfoHandlerFunc(func(params admin_api.GetUserInfoParams, session *models.Principal) middleware.Responder {
userInfoResponse, err := getUserInfoResponse(session, params)
if err != nil {
return admin_api.NewGetUserInfoDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return admin_api.NewGetUserInfoDefault(int(err.Code)).WithPayload(err)
}
return admin_api.NewGetUserInfoOK().WithPayload(userInfoResponse)
@@ -78,7 +77,7 @@ func registerUsersHandlers(api *operations.ConsoleAPI) {
api.AdminAPIUpdateUserInfoHandler = admin_api.UpdateUserInfoHandlerFunc(func(params admin_api.UpdateUserInfoParams, session *models.Principal) middleware.Responder {
userUpdateResponse, err := getUpdateUserResponse(session, params)
if err != nil {
return admin_api.NewUpdateUserInfoDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return admin_api.NewUpdateUserInfoDefault(int(err.Code)).WithPayload(err)
}
return admin_api.NewUpdateUserInfoOK().WithPayload(userUpdateResponse)
@@ -87,7 +86,7 @@ func registerUsersHandlers(api *operations.ConsoleAPI) {
api.AdminAPIBulkUpdateUsersGroupsHandler = admin_api.BulkUpdateUsersGroupsHandlerFunc(func(params admin_api.BulkUpdateUsersGroupsParams, session *models.Principal) middleware.Responder {
err := getAddUsersListToGroupsResponse(session, params)
if err != nil {
return admin_api.NewBulkUpdateUsersGroupsDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return admin_api.NewBulkUpdateUsersGroupsDefault(int(err.Code)).WithPayload(err)
}
return admin_api.NewBulkUpdateUsersGroupsOK()
@@ -119,12 +118,11 @@ func listUsers(ctx context.Context, client MinioAdmin) ([]*models.User, error) {
}
// getListUsersResponse performs listUsers() and serializes it to the handler's output
func getListUsersResponse(session *models.Principal) (*models.ListUsersResponse, error) {
func getListUsersResponse(session *models.Principal) (*models.ListUsersResponse, *models.Error) {
ctx := context.Background()
mAdmin, err := newMAdminClient(session)
if err != nil {
log.Println("error creating Madmin Client:", err)
return nil, err
return nil, prepareError(err)
}
// create a minioClient interface implementation
// defining the client to be used
@@ -132,8 +130,7 @@ func getListUsersResponse(session *models.Principal) (*models.ListUsersResponse,
users, err := listUsers(ctx, adminClient)
if err != nil {
log.Println("error listing users:", err)
return nil, err
return nil, prepareError(err)
}
// serialize output
listUsersResponse := &models.ListUsersResponse{
@@ -167,12 +164,11 @@ func addUser(ctx context.Context, client MinioAdmin, accessKey, secretKey *strin
return userRet, nil
}
func getUserAddResponse(session *models.Principal, params admin_api.AddUserParams) (*models.User, error) {
func getUserAddResponse(session *models.Principal, params admin_api.AddUserParams) (*models.User, *models.Error) {
ctx := context.Background()
mAdmin, err := newMAdminClient(session)
if err != nil {
log.Println("error creating Madmin Client:", err)
return nil, err
return nil, prepareError(err)
}
// create a minioClient interface implementation
// defining the client to be used
@@ -180,8 +176,7 @@ func getUserAddResponse(session *models.Principal, params admin_api.AddUserParam
user, err := addUser(ctx, adminClient, params.Body.AccessKey, params.Body.SecretKey, params.Body.Groups)
if err != nil {
log.Println("error adding user:", err)
return nil, err
return nil, prepareError(err)
}
return user, nil
}
@@ -194,13 +189,12 @@ func removeUser(ctx context.Context, client MinioAdmin, accessKey string) error
return nil
}
func getRemoveUserResponse(session *models.Principal, params admin_api.RemoveUserParams) error {
func getRemoveUserResponse(session *models.Principal, params admin_api.RemoveUserParams) *models.Error {
ctx := context.Background()
mAdmin, err := newMAdminClient(session)
if err != nil {
log.Println("error creating Madmin Client:", err)
return err
return prepareError(err)
}
// create a minioClient interface implementation
@@ -208,8 +202,7 @@ func getRemoveUserResponse(session *models.Principal, params admin_api.RemoveUse
adminClient := adminClient{client: mAdmin}
if err := removeUser(ctx, adminClient, params.Name); err != nil {
log.Println("error removing user:", err)
return err
return prepareError(err)
}
log.Println("User removed successfully:", params.Name)
@@ -226,13 +219,12 @@ func getUserInfo(ctx context.Context, client MinioAdmin, accessKey string) (*mad
return &userInfo, nil
}
func getUserInfoResponse(session *models.Principal, params admin_api.GetUserInfoParams) (*models.User, error) {
func getUserInfoResponse(session *models.Principal, params admin_api.GetUserInfoParams) (*models.User, *models.Error) {
ctx := context.Background()
mAdmin, err := newMAdminClient(session)
if err != nil {
log.Println("error creating Madmin Client:", err)
return nil, err
return nil, prepareError(err)
}
// create a minioClient interface implementation
@@ -241,8 +233,7 @@ func getUserInfoResponse(session *models.Principal, params admin_api.GetUserInfo
user, err := getUserInfo(ctx, adminClient, params.Name)
if err != nil {
log.Println("error getting user:", err)
return nil, err
return nil, prepareError(err)
}
userInformation := &models.User{
@@ -341,13 +332,12 @@ func updateUserGroups(ctx context.Context, client MinioAdmin, user string, group
return userReturn, nil
}
func getUpdateUserGroupsResponse(session *models.Principal, params admin_api.UpdateUserGroupsParams) (*models.User, error) {
func getUpdateUserGroupsResponse(session *models.Principal, params admin_api.UpdateUserGroupsParams) (*models.User, *models.Error) {
ctx := context.Background()
mAdmin, err := newMAdminClient(session)
if err != nil {
log.Println("error creating Madmin Client:", err)
return nil, err
return nil, prepareError(err)
}
// create a minioClient interface implementation
@@ -357,8 +347,7 @@ func getUpdateUserGroupsResponse(session *models.Principal, params admin_api.Upd
user, err := updateUserGroups(ctx, adminClient, params.Name, params.Body.Groups)
if err != nil {
log.Println("error updating users's groups:", params.Body.Groups)
return nil, err
return nil, prepareError(err)
}
return user, nil
@@ -382,13 +371,12 @@ func setUserStatus(ctx context.Context, client MinioAdmin, user string, status s
return nil
}
func getUpdateUserResponse(session *models.Principal, params admin_api.UpdateUserInfoParams) (*models.User, error) {
func getUpdateUserResponse(session *models.Principal, params admin_api.UpdateUserInfoParams) (*models.User, *models.Error) {
ctx := context.Background()
mAdmin, err := newMAdminClient(session)
if err != nil {
log.Println("error creating Madmin Client:", err)
return nil, err
return nil, prepareError(err)
}
// create a minioClient interface implementation
@@ -400,14 +388,13 @@ func getUpdateUserResponse(session *models.Principal, params admin_api.UpdateUse
groups := params.Body.Groups
if err := setUserStatus(ctx, adminClient, name, status); err != nil {
log.Println("error updating user status:", status)
return nil, err
return nil, prepareError(err)
}
userElem, errUG := updateUserGroups(ctx, adminClient, name, groups)
if errUG != nil {
return nil, errUG
return nil, prepareError(errUG)
}
return userElem, nil
}
@@ -455,13 +442,12 @@ func addUsersListToGroups(ctx context.Context, client MinioAdmin, usersToUpdate
return nil
}
func getAddUsersListToGroupsResponse(session *models.Principal, params admin_api.BulkUpdateUsersGroupsParams) error {
func getAddUsersListToGroupsResponse(session *models.Principal, params admin_api.BulkUpdateUsersGroupsParams) *models.Error {
ctx := context.Background()
mAdmin, err := newMAdminClient(session)
if err != nil {
log.Println("error creating Madmin Client:", err)
return err
return prepareError(err)
}
// create a minioClient interface implementation
@@ -472,8 +458,7 @@ func getAddUsersListToGroupsResponse(session *models.Principal, params admin_api
groupsList := params.Body.Groups
if err := addUsersListToGroups(ctx, adminClient, usersList, groupsList); err != nil {
log.Println("error updating groups bulk users:", err.Error())
return err
return prepareError(err)
}
return nil

View File

@@ -50,3 +50,11 @@ const (
ConsoleSecureFeaturePolicy = "CONSOLE_SECURE_FEATURE_POLICY"
ConsoleSecureExpectCTHeader = "CONSOLE_SECURE_EXPECT_CT_HEADER"
)
// prometheus annotations
const (
prometheusPath = "prometheus.io/path"
prometheusPort = "prometheus.io/port"
prometheusScrape = "prometheus.io/scrape"
)

View File

@@ -2320,7 +2320,7 @@ func init() {
"properties": {
"code": {
"type": "integer",
"format": "int64"
"format": "int32"
},
"message": {
"type": "string"
@@ -3150,12 +3150,21 @@ func init() {
"tenant": {
"type": "object",
"properties": {
"console_image": {
"type": "string"
},
"creation_date": {
"type": "string"
},
"currentState": {
"type": "string"
},
"deletion_date": {
"type": "string"
},
"enable_prometheus": {
"type": "boolean"
},
"image": {
"type": "string"
},
@@ -3186,6 +3195,9 @@ func init() {
"currentState": {
"type": "string"
},
"deletion_date": {
"type": "string"
},
"instance_count": {
"type": "integer"
},
@@ -3257,6 +3269,9 @@ func init() {
"type": "string",
"pattern": "^((.*?)/(.*?):(.+))$"
},
"enable_prometheus": {
"type": "boolean"
},
"image": {
"type": "string",
"pattern": "^((.*?)/(.*?):(.+))$"
@@ -6461,7 +6476,7 @@ func init() {
"properties": {
"code": {
"type": "integer",
"format": "int64"
"format": "int32"
},
"message": {
"type": "string"
@@ -7225,12 +7240,21 @@ func init() {
"tenant": {
"type": "object",
"properties": {
"console_image": {
"type": "string"
},
"creation_date": {
"type": "string"
},
"currentState": {
"type": "string"
},
"deletion_date": {
"type": "string"
},
"enable_prometheus": {
"type": "boolean"
},
"image": {
"type": "string"
},
@@ -7261,6 +7285,9 @@ func init() {
"currentState": {
"type": "string"
},
"deletion_date": {
"type": "string"
},
"instance_count": {
"type": "integer"
},
@@ -7332,6 +7359,9 @@ func init() {
"type": "string",
"pattern": "^((.*?)/(.*?):(.+))$"
},
"enable_prometheus": {
"type": "boolean"
},
"image": {
"type": "string",
"pattern": "^((.*?)/(.*?):(.+))$"

100
restapi/error.go Normal file
View File

@@ -0,0 +1,100 @@
package restapi
import (
"errors"
"log"
"github.com/go-openapi/swag"
"github.com/minio/console/models"
k8sErrors "k8s.io/apimachinery/pkg/api/errors"
)
var (
// Generic error messages
errorGeneric = errors.New("an error occurred, please try again")
errInvalidCredentials = errors.New("invalid Login")
errorGenericInvalidSession = errors.New("invalid session")
errorGenericUnauthorized = errors.New("unauthorized")
errorGenericForbidden = errors.New("forbidden")
errorGenericNotFound = errors.New("not found")
// Explicit error messages
errorInvalidErasureCodingValue = errors.New("invalid Erasure Coding Value")
errorUnableToGetTenantUsage = errors.New("unable to get tenant usage")
errorUnableToUpdateTenantCertificates = errors.New("unable to update tenant certificates")
errorUpdatingEncryptionConfig = errors.New("unable to update encryption configuration")
errBucketBodyNotInRequest = errors.New("error bucket body not in request")
errBucketNameNotInRequest = errors.New("error bucket name not in request")
errGroupBodyNotInRequest = errors.New("error group body not in request")
errGroupNameNotInRequest = errors.New("error group name not in request")
errPolicyNameNotInRequest = errors.New("error policy name not in request")
errPolicyBodyNotInRequest = errors.New("error policy body not in request")
)
// prepareError receives an error object and parse it against k8sErrors, returns the right error code paired with a generic error message
func prepareError(err ...error) *models.Error {
errorCode := int32(500)
errorMessage := errorGeneric.Error()
if len(err) > 0 {
log.Print("original error: ", err[0].Error())
if k8sErrors.IsUnauthorized(err[0]) {
errorCode = 401
errorMessage = errorGenericUnauthorized.Error()
}
if k8sErrors.IsForbidden(err[0]) {
errorCode = 403
errorMessage = errorGenericForbidden.Error()
}
if k8sErrors.IsNotFound(err[0]) {
errorCode = 404
errorMessage = errorGenericNotFound.Error()
}
if errors.Is(err[0], errInvalidCredentials) {
errorCode = 401
errorMessage = errInvalidCredentials.Error()
}
// console invalid erasure coding value
if errors.Is(err[0], errorInvalidErasureCodingValue) {
errorCode = 400
errorMessage = errorInvalidErasureCodingValue.Error()
}
if errors.Is(err[0], errBucketBodyNotInRequest) {
errorCode = 400
errorMessage = errBucketBodyNotInRequest.Error()
}
if errors.Is(err[0], errBucketNameNotInRequest) {
errorCode = 400
errorMessage = errBucketNameNotInRequest.Error()
}
if errors.Is(err[0], errGroupBodyNotInRequest) {
errorCode = 400
errorMessage = errGroupBodyNotInRequest.Error()
}
if errors.Is(err[0], errGroupNameNotInRequest) {
errorCode = 400
errorMessage = errGroupNameNotInRequest.Error()
}
if errors.Is(err[0], errPolicyNameNotInRequest) {
errorCode = 400
errorMessage = errPolicyNameNotInRequest.Error()
}
if errors.Is(err[0], errPolicyBodyNotInRequest) {
errorCode = 400
errorMessage = errPolicyBodyNotInRequest.Error()
}
// console invalid session error
if errors.Is(err[0], errorGenericInvalidSession) {
errorCode = 401
errorMessage = errorGenericInvalidSession.Error()
}
// if we received a second error take that as friendly message but dont override the code
if len(err) > 1 && err[1] != nil {
log.Print("friendly error: ", err[1].Error())
errorMessage = err[1].Error()
}
// if we receive third error we just print that as debugging
if len(err) > 2 && err[2] != nil {
log.Print("debugging error: ", err[2].Error())
}
}
return &models.Error{Code: errorCode, Message: swag.String(errorMessage)}
}

View File

@@ -18,12 +18,10 @@ package restapi
import (
"context"
"log"
"github.com/minio/console/cluster"
"github.com/go-openapi/runtime/middleware"
"github.com/go-openapi/swag"
"github.com/minio/console/models"
"github.com/minio/console/restapi/operations"
"github.com/minio/console/restapi/operations/admin_api"
@@ -35,7 +33,7 @@ func registerResourceQuotaHandlers(api *operations.ConsoleAPI) {
api.AdminAPIGetResourceQuotaHandler = admin_api.GetResourceQuotaHandlerFunc(func(params admin_api.GetResourceQuotaParams, session *models.Principal) middleware.Responder {
resp, err := getResourceQuotaResponse(session, params)
if err != nil {
return admin_api.NewGetResourceQuotaDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return admin_api.NewGetResourceQuotaDefault(int(err.Code)).WithPayload(err)
}
return admin_api.NewGetResourceQuotaOK().WithPayload(resp)
@@ -68,20 +66,18 @@ func getResourceQuota(ctx context.Context, client K8sClientI, namespace, resourc
return &rq, nil
}
func getResourceQuotaResponse(session *models.Principal, params admin_api.GetResourceQuotaParams) (*models.ResourceQuota, error) {
func getResourceQuotaResponse(session *models.Principal, params admin_api.GetResourceQuotaParams) (*models.ResourceQuota, *models.Error) {
ctx := context.Background()
client, err := cluster.K8sClient(session.SessionToken)
if err != nil {
log.Println("error getting k8sClient:", err)
return nil, err
return nil, prepareError(err)
}
k8sClient := &k8sClient{
client: client,
}
resourceQuota, err := getResourceQuota(ctx, k8sClient, params.Namespace, params.ResourceQuotaName)
if err != nil {
log.Println("error getting resource quota:", err)
return nil, err
return nil, prepareError(err)
}
return resourceQuota, nil

View File

@@ -20,11 +20,9 @@ import (
"context"
"encoding/json"
"fmt"
"log"
"strings"
"time"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime/middleware"
"github.com/go-openapi/swag"
"github.com/minio/console/models"
@@ -39,21 +37,21 @@ func registerBucketsHandlers(api *operations.ConsoleAPI) {
api.UserAPIListBucketsHandler = user_api.ListBucketsHandlerFunc(func(params user_api.ListBucketsParams, session *models.Principal) middleware.Responder {
listBucketsResponse, err := getListBucketsResponse(session)
if err != nil {
return user_api.NewListBucketsDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return user_api.NewListBucketsDefault(int(err.Code)).WithPayload(err)
}
return user_api.NewListBucketsOK().WithPayload(listBucketsResponse)
})
// make bucket
api.UserAPIMakeBucketHandler = user_api.MakeBucketHandlerFunc(func(params user_api.MakeBucketParams, session *models.Principal) middleware.Responder {
if err := getMakeBucketResponse(session, params.Body); err != nil {
return user_api.NewMakeBucketDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return user_api.NewMakeBucketDefault(int(err.Code)).WithPayload(err)
}
return user_api.NewMakeBucketCreated()
})
// delete bucket
api.UserAPIDeleteBucketHandler = user_api.DeleteBucketHandlerFunc(func(params user_api.DeleteBucketParams, session *models.Principal) middleware.Responder {
if err := getDeleteBucketResponse(session, params); err != nil {
return user_api.NewMakeBucketDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return user_api.NewMakeBucketDefault(int(err.Code)).WithPayload(err)
}
return user_api.NewDeleteBucketNoContent()
@@ -62,7 +60,7 @@ func registerBucketsHandlers(api *operations.ConsoleAPI) {
api.UserAPIBucketInfoHandler = user_api.BucketInfoHandlerFunc(func(params user_api.BucketInfoParams, session *models.Principal) middleware.Responder {
bucketInfoResp, err := getBucketInfoResponse(session, params)
if err != nil {
return user_api.NewBucketInfoDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return user_api.NewBucketInfoDefault(int(err.Code)).WithPayload(err)
}
return user_api.NewBucketInfoOK().WithPayload(bucketInfoResp)
@@ -71,7 +69,7 @@ func registerBucketsHandlers(api *operations.ConsoleAPI) {
api.UserAPIBucketSetPolicyHandler = user_api.BucketSetPolicyHandlerFunc(func(params user_api.BucketSetPolicyParams, session *models.Principal) middleware.Responder {
bucketSetPolicyResp, err := getBucketSetPolicyResponse(session, params.Name, params.Body)
if err != nil {
return user_api.NewBucketSetPolicyDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return user_api.NewBucketSetPolicyDefault(int(err.Code)).WithPayload(err)
}
return user_api.NewBucketSetPolicyOK().WithPayload(bucketSetPolicyResp)
})
@@ -92,22 +90,20 @@ func getaAcountUsageInfo(ctx context.Context, client MinioAdmin) ([]*models.Buck
}
// getListBucketsResponse performs listBuckets() and serializes it to the handler's output
func getListBucketsResponse(session *models.Principal) (*models.ListBucketsResponse, error) {
func getListBucketsResponse(session *models.Principal) (*models.ListBucketsResponse, *models.Error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*20)
defer cancel()
mAdmin, err := newMAdminClient(session)
if err != nil {
log.Println("error creating Madmin Client:", err)
return nil, err
return nil, prepareError(err)
}
// create a minioClient interface implementation
// defining the client to be used
adminClient := adminClient{client: mAdmin}
buckets, err := getaAcountUsageInfo(ctx, adminClient)
if err != nil {
log.Println("error accountingUsageInfo:", err)
return nil, err
return nil, prepareError(err)
}
// serialize output
@@ -128,26 +124,23 @@ func makeBucket(ctx context.Context, client MinioClient, bucketName string) erro
}
// getMakeBucketResponse performs makeBucket() to create a bucket with its access policy
func getMakeBucketResponse(session *models.Principal, br *models.MakeBucketRequest) error {
func getMakeBucketResponse(session *models.Principal, br *models.MakeBucketRequest) *models.Error {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*20)
defer cancel()
// bucket request needed to proceed
if br == nil {
log.Println("error bucket body not in request")
return errors.New(500, "error bucket body not in request")
return prepareError(errBucketBodyNotInRequest)
}
mClient, err := newMinioClient(session)
if err != nil {
log.Println("error creating MinIO Client:", err)
return err
return prepareError(err)
}
// create a minioClient interface implementation
// defining the client to be used
minioClient := minioClient{client: mClient}
if err := makeBucket(ctx, minioClient, *br.Name); err != nil {
log.Println("error making bucket:", err)
return err
return prepareError(err)
}
return nil
}
@@ -182,14 +175,13 @@ func setBucketAccessPolicy(ctx context.Context, client MinioClient, bucketName s
// getBucketSetPolicyResponse calls setBucketAccessPolicy() to set a access policy to a bucket
// and returns the serialized output.
func getBucketSetPolicyResponse(session *models.Principal, bucketName string, req *models.SetBucketPolicyRequest) (*models.Bucket, error) {
func getBucketSetPolicyResponse(session *models.Principal, bucketName string, req *models.SetBucketPolicyRequest) (*models.Bucket, *models.Error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*20)
defer cancel()
mClient, err := newMinioClient(session)
if err != nil {
log.Println("error creating MinIO Client:", err)
return nil, err
return nil, prepareError(err)
}
// create a minioClient interface implementation
// defining the client to be used
@@ -197,14 +189,12 @@ func getBucketSetPolicyResponse(session *models.Principal, bucketName string, re
// set bucket access policy
if err := setBucketAccessPolicy(ctx, minioClient, bucketName, req.Access); err != nil {
log.Println("error setting bucket access policy:", err)
return nil, err
return nil, prepareError(err)
}
// get updated bucket details and return it
bucket, err := getBucketInfo(minioClient, bucketName)
if err != nil {
log.Println("error getting bucket's info:", err)
return nil, err
return nil, prepareError(err)
}
return bucket, nil
}
@@ -215,23 +205,23 @@ func removeBucket(client MinioClient, bucketName string) error {
}
// getDeleteBucketResponse performs removeBucket() to delete a bucket
func getDeleteBucketResponse(session *models.Principal, params user_api.DeleteBucketParams) error {
func getDeleteBucketResponse(session *models.Principal, params user_api.DeleteBucketParams) *models.Error {
if params.Name == "" {
log.Println("error bucket name not in request")
return errors.New(500, "error bucket name not in request")
return prepareError(errBucketNameNotInRequest)
}
bucketName := params.Name
mClient, err := newMinioClient(session)
if err != nil {
log.Println("error creating MinIO Client:", err)
return err
return prepareError(err)
}
// create a minioClient interface implementation
// defining the client to be used
minioClient := minioClient{client: mClient}
return removeBucket(minioClient, bucketName)
if err := removeBucket(minioClient, bucketName); err != nil {
return prepareError(err)
}
return nil
}
// getBucketInfo return bucket information including name, policy access, size and creation date
@@ -264,11 +254,10 @@ func getBucketInfo(client MinioClient, bucketName string) (*models.Bucket, error
}
// getBucketInfoResponse calls getBucketInfo() to get the bucket's info
func getBucketInfoResponse(session *models.Principal, params user_api.BucketInfoParams) (*models.Bucket, error) {
func getBucketInfoResponse(session *models.Principal, params user_api.BucketInfoParams) (*models.Bucket, *models.Error) {
mClient, err := newMinioClient(session)
if err != nil {
log.Println("error creating MinIO Client:", err)
return nil, err
return nil, prepareError(err)
}
// create a minioClient interface implementation
// defining the client to be used
@@ -276,8 +265,7 @@ func getBucketInfoResponse(session *models.Principal, params user_api.BucketInfo
bucket, err := getBucketInfo(minioClient, params.Name)
if err != nil {
log.Println("error getting bucket's info:", err)
return nil, err
return nil, prepareError(err)
}
return bucket, nil

View File

@@ -18,7 +18,6 @@ package restapi
import (
"context"
"log"
"strings"
"github.com/go-openapi/runtime/middleware"
@@ -34,21 +33,21 @@ func registerBucketEventsHandlers(api *operations.ConsoleAPI) {
api.UserAPIListBucketEventsHandler = user_api.ListBucketEventsHandlerFunc(func(params user_api.ListBucketEventsParams, session *models.Principal) middleware.Responder {
listBucketEventsResponse, err := getListBucketEventsResponse(session, params)
if err != nil {
return user_api.NewListBucketEventsDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return user_api.NewListBucketEventsDefault(int(err.Code)).WithPayload(err)
}
return user_api.NewListBucketEventsOK().WithPayload(listBucketEventsResponse)
})
// create bucket event
api.UserAPICreateBucketEventHandler = user_api.CreateBucketEventHandlerFunc(func(params user_api.CreateBucketEventParams, session *models.Principal) middleware.Responder {
if err := getCreateBucketEventsResponse(session, params.BucketName, params.Body); err != nil {
return user_api.NewCreateBucketEventDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return user_api.NewCreateBucketEventDefault(int(err.Code)).WithPayload(err)
}
return user_api.NewCreateBucketEventCreated()
})
// delete bucket event
api.UserAPIDeleteBucketEventHandler = user_api.DeleteBucketEventHandlerFunc(func(params user_api.DeleteBucketEventParams, session *models.Principal) middleware.Responder {
if err := getDeleteBucketEventsResponse(session, params.BucketName, params.Arn, params.Body.Events, params.Body.Prefix, params.Body.Suffix); err != nil {
return user_api.NewDeleteBucketEventDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return user_api.NewDeleteBucketEventDefault(int(err.Code)).WithPayload(err)
}
return user_api.NewDeleteBucketEventNoContent()
})
@@ -125,11 +124,10 @@ func listBucketEvents(client MinioClient, bucketName string) ([]*models.Notifica
}
// getListBucketsResponse performs listBucketEvents() and serializes it to the handler's output
func getListBucketEventsResponse(session *models.Principal, params user_api.ListBucketEventsParams) (*models.ListBucketEventsResponse, error) {
func getListBucketEventsResponse(session *models.Principal, params user_api.ListBucketEventsParams) (*models.ListBucketEventsResponse, *models.Error) {
mClient, err := newMinioClient(session)
if err != nil {
log.Println("error creating MinIO Client:", err)
return nil, err
return nil, prepareError(err)
}
// create a minioClient interface implementation
// defining the client to be used
@@ -137,8 +135,7 @@ func getListBucketEventsResponse(session *models.Principal, params user_api.List
bucketEvents, err := listBucketEvents(minioClient, params.BucketName)
if err != nil {
log.Println("error listing bucket events:", err)
return nil, err
return nil, prepareError(err)
}
// serialize output
listBucketsResponse := &models.ListBucketEventsResponse{
@@ -178,20 +175,18 @@ func createBucketEvent(ctx context.Context, client MCClient, arn string, notific
}
// getCreateBucketEventsResponse calls createBucketEvent to add a bucket event notification
func getCreateBucketEventsResponse(session *models.Principal, bucketName string, eventReq *models.BucketEventRequest) error {
func getCreateBucketEventsResponse(session *models.Principal, bucketName string, eventReq *models.BucketEventRequest) *models.Error {
ctx := context.Background()
s3Client, err := newS3BucketClient(session, bucketName)
if err != nil {
log.Println("error creating S3Client:", err)
return err
return prepareError(err)
}
// create a mc S3Client interface implementation
// defining the client to be used
mcClient := mcClient{client: s3Client}
err = createBucketEvent(ctx, mcClient, *eventReq.Configuration.Arn, eventReq.Configuration.Events, eventReq.Configuration.Prefix, eventReq.Configuration.Suffix, eventReq.IgnoreExisting)
if err != nil {
log.Println("error creating bucket event:", err)
return err
return prepareError(err)
}
return nil
}
@@ -215,20 +210,18 @@ func joinNotificationEvents(events []models.NotificationEventType) string {
}
// getDeleteBucketEventsResponse calls deleteBucketEventNotification() to delete a bucket event notification
func getDeleteBucketEventsResponse(session *models.Principal, bucketName string, arn string, events []models.NotificationEventType, prefix, suffix *string) error {
func getDeleteBucketEventsResponse(session *models.Principal, bucketName string, arn string, events []models.NotificationEventType, prefix, suffix *string) *models.Error {
ctx := context.Background()
s3Client, err := newS3BucketClient(session, bucketName)
if err != nil {
log.Println("error creating S3Client:", err)
return err
return prepareError(err)
}
// create a mc S3Client interface implementation
// defining the client to be used
mcClient := mcClient{client: s3Client}
err = deleteBucketEventNotification(ctx, mcClient, arn, events, prefix, suffix)
if err != nil {
log.Println("error deleting bucket event:", err)
return err
return prepareError(err)
}
return nil
}

View File

@@ -18,11 +18,9 @@ package restapi
import (
"context"
"errors"
"log"
"github.com/go-openapi/runtime/middleware"
"github.com/go-openapi/swag"
"github.com/minio/console/models"
"github.com/minio/console/pkg/acl"
"github.com/minio/console/pkg/auth"
@@ -32,17 +30,12 @@ import (
"github.com/minio/console/restapi/operations/user_api"
)
var (
errorGeneric = errors.New("an error occurred, please try again")
errInvalidCredentials = errors.New("invalid Login")
)
func registerLoginHandlers(api *operations.ConsoleAPI) {
// get login strategy
api.UserAPILoginDetailHandler = user_api.LoginDetailHandlerFunc(func(params user_api.LoginDetailParams) middleware.Responder {
loginDetails, err := getLoginDetailsResponse()
if err != nil {
return user_api.NewLoginDetailDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return user_api.NewLoginDetailDefault(int(err.Code)).WithPayload(err)
}
return user_api.NewLoginDetailOK().WithPayload(loginDetails)
})
@@ -50,21 +43,21 @@ func registerLoginHandlers(api *operations.ConsoleAPI) {
api.UserAPILoginHandler = user_api.LoginHandlerFunc(func(params user_api.LoginParams) middleware.Responder {
loginResponse, err := getLoginResponse(params.Body)
if err != nil {
return user_api.NewLoginDefault(401).WithPayload(&models.Error{Code: 401, Message: swag.String(err.Error())})
return user_api.NewLoginDefault(int(err.Code)).WithPayload(err)
}
return user_api.NewLoginCreated().WithPayload(loginResponse)
})
api.UserAPILoginOauth2AuthHandler = user_api.LoginOauth2AuthHandlerFunc(func(params user_api.LoginOauth2AuthParams) middleware.Responder {
loginResponse, err := getLoginOauth2AuthResponse(params.Body)
if err != nil {
return user_api.NewLoginOauth2AuthDefault(401).WithPayload(&models.Error{Code: 401, Message: swag.String(err.Error())})
return user_api.NewLoginOauth2AuthDefault(int(err.Code)).WithPayload(err)
}
return user_api.NewLoginOauth2AuthCreated().WithPayload(loginResponse)
})
api.UserAPILoginOperatorHandler = user_api.LoginOperatorHandlerFunc(func(params user_api.LoginOperatorParams) middleware.Responder {
loginResponse, err := getLoginOperatorResponse(params.Body)
if err != nil {
return user_api.NewLoginOperatorDefault(401).WithPayload(&models.Error{Code: 401, Message: swag.String(err.Error())})
return user_api.NewLoginOperatorDefault(int(err.Code)).WithPayload(err)
}
return user_api.NewLoginOperatorCreated().WithPayload(loginResponse)
})
@@ -76,8 +69,7 @@ func login(credentials ConsoleCredentials, actions []string) (*string, error) {
// try to obtain consoleCredentials,
tokens, err := credentials.Get()
if err != nil {
log.Println("error authenticating user", err)
return nil, errInvalidCredentials
return nil, err
}
// if we made it here, the consoleCredentials work, generate a jwt with claims
jwt, err := auth.NewEncryptedTokenForClient(&tokens, actions)
@@ -103,32 +95,29 @@ func getConfiguredRegionForLogin(client MinioAdmin) (string, error) {
}
// getLoginResponse performs login() and serializes it to the handler's output
func getLoginResponse(lr *models.LoginRequest) (*models.LoginResponse, error) {
func getLoginResponse(lr *models.LoginRequest) (*models.LoginResponse, *models.Error) {
ctx := context.Background()
mAdmin, err := newSuperMAdminClient()
if err != nil {
log.Println("error creating Madmin Client:", err)
return nil, errorGeneric
return nil, prepareError(err)
}
adminClient := adminClient{client: mAdmin}
// obtain the configured MinIO region
// need it for user authentication
location, err := getConfiguredRegionForLogin(adminClient)
if err != nil {
return nil, err
return nil, prepareError(err)
}
creds, err := newConsoleCredentials(*lr.AccessKey, *lr.SecretKey, location)
if err != nil {
log.Println("error login:", err)
return nil, errInvalidCredentials
return nil, prepareError(err)
}
credentials := consoleCredentials{consoleCredentials: creds}
// obtain the current policy assigned to this user
// necessary for generating the list of allowed endpoints
userInfo, err := adminClient.getUserInfo(ctx, *lr.AccessKey)
if err != nil {
log.Println("error login:", err)
return nil, errInvalidCredentials
return nil, prepareError(err)
}
policy, _ := adminClient.getPolicy(ctx, userInfo.PolicyName)
// by default every user starts with an empty array of available actions
@@ -141,7 +130,7 @@ func getLoginResponse(lr *models.LoginRequest) (*models.LoginResponse, error) {
}
sessionID, err := login(credentials, actions)
if err != nil {
return nil, err
return nil, prepareError(errInvalidCredentials, nil, err)
}
// serialize output
loginResponse := &models.LoginResponse{
@@ -151,7 +140,7 @@ func getLoginResponse(lr *models.LoginRequest) (*models.LoginResponse, error) {
}
// getLoginDetailsResponse returns information regarding the Console authentication mechanism.
func getLoginDetailsResponse() (*models.LoginDetails, error) {
func getLoginDetailsResponse() (*models.LoginDetails, *models.Error) {
ctx := context.Background()
loginStrategy := models.LoginDetailsLoginStrategyForm
redirectURL := ""
@@ -162,8 +151,7 @@ func getLoginDetailsResponse() (*models.LoginDetails, error) {
// initialize new oauth2 client
oauth2Client, err := oauth2.NewOauth2ProviderClient(ctx, nil)
if err != nil {
log.Println("error getting new oauth2 provider client", err)
return nil, errorGeneric
return nil, prepareError(err)
}
// Validate user against IDP
identityProvider := &auth.IdentityProvider{Client: oauth2Client}
@@ -180,31 +168,29 @@ func loginOauth2Auth(ctx context.Context, provider *auth.IdentityProvider, code,
userIdentity, err := provider.VerifyIdentity(ctx, code, state)
if err != nil {
log.Println("error validating user identity against idp:", err)
return nil, errorGeneric
return nil, errInvalidCredentials
}
return userIdentity, nil
}
func getLoginOauth2AuthResponse(lr *models.LoginOauth2AuthRequest) (*models.LoginResponse, error) {
func getLoginOauth2AuthResponse(lr *models.LoginOauth2AuthRequest) (*models.LoginResponse, *models.Error) {
ctx := context.Background()
if oauth2.IsIdpEnabled() {
// initialize new oauth2 client
oauth2Client, err := oauth2.NewOauth2ProviderClient(ctx, nil)
if err != nil {
log.Println("error getting new oauth2 client:", err)
return nil, errorGeneric
return nil, prepareError(err)
}
// initialize new identity provider
identityProvider := &auth.IdentityProvider{Client: oauth2Client}
// Validate user against IDP
identity, err := loginOauth2Auth(ctx, identityProvider, *lr.Code, *lr.State)
if err != nil {
return nil, err
return nil, prepareError(errInvalidCredentials, nil, err)
}
mAdmin, err := newSuperMAdminClient()
if err != nil {
log.Println("error creating Madmin Client:", err)
return nil, errorGeneric
return nil, prepareError(err)
}
adminClient := adminClient{client: mAdmin}
accessKey := identity.Email
@@ -213,12 +199,11 @@ func getLoginOauth2AuthResponse(lr *models.LoginOauth2AuthRequest) (*models.Logi
// need it for user authentication
location, err := getConfiguredRegionForLogin(adminClient)
if err != nil {
return nil, err
return nil, prepareError(err)
}
// create user in MinIO
if _, err := addUser(ctx, adminClient, &accessKey, &secretKey, []string{}); err != nil {
log.Println("error adding user:", err)
return nil, errorGeneric
return nil, prepareError(err)
}
// rollback user if there's an error after this point
defer func() {
@@ -231,26 +216,23 @@ func getLoginOauth2AuthResponse(lr *models.LoginOauth2AuthRequest) (*models.Logi
// assign the "consoleAdmin" policy to this user
policyName := oauth2.GetIDPPolicyForUser()
if err := setPolicy(ctx, adminClient, policyName, accessKey, models.PolicyEntityUser); err != nil {
log.Println("error setting policy:", err)
return nil, errorGeneric
return nil, prepareError(err)
}
// obtain the current policy details, necessary for generating the list of allowed endpoints
policy, err := adminClient.getPolicy(ctx, policyName)
if err != nil {
log.Println("error reading policy:", err)
return nil, errorGeneric
return nil, prepareError(err)
}
actions := acl.GetActionsStringFromPolicy(policy)
// User was created correctly, create a new session/JWT
creds, err := newConsoleCredentials(accessKey, secretKey, location)
if err != nil {
log.Println("error login:", err)
return nil, errorGeneric
return nil, prepareError(err)
}
credentials := consoleCredentials{consoleCredentials: creds}
jwt, err := login(credentials, actions)
if err != nil {
return nil, err
return nil, prepareError(errInvalidCredentials, nil, err)
}
// serialize output
loginResponse := &models.LoginResponse{
@@ -258,21 +240,20 @@ func getLoginOauth2AuthResponse(lr *models.LoginOauth2AuthRequest) (*models.Logi
}
return loginResponse, nil
}
return nil, errorGeneric
return nil, prepareError(errorGeneric)
}
// getLoginOperatorResponse validate the provided service account token against k8s api
func getLoginOperatorResponse(lmr *models.LoginOperatorRequest) (*models.LoginResponse, error) {
func getLoginOperatorResponse(lmr *models.LoginOperatorRequest) (*models.LoginResponse, *models.Error) {
creds, err := newConsoleCredentials("", *lmr.Jwt, "")
if err != nil {
log.Println("error login:", err)
return nil, errInvalidCredentials
return nil, prepareError(err)
}
credentials := consoleCredentials{consoleCredentials: creds}
var actions []string
jwt, err := login(credentials, actions)
if err != nil {
return nil, err
return nil, prepareError(errInvalidCredentials, nil, err)
}
// serialize output
loginResponse := &models.LoginResponse{

View File

@@ -100,7 +100,7 @@ func TestLoginOauth2Auth(t *testing.T) {
return nil, errors.New("error")
}
if _, err := loginOauth2Auth(ctx, identityProvider, mockCode, mockState); funcAssert.Error(err) {
funcAssert.Equal("an error occurred, please try again", err.Error())
funcAssert.Equal(errInvalidCredentials.Error(), err.Error())
}
}

View File

@@ -19,12 +19,10 @@ package restapi
import (
"bytes"
"context"
"log"
"strings"
"time"
"github.com/go-openapi/runtime/middleware"
"github.com/go-openapi/swag"
"github.com/minio/console/models"
"github.com/minio/console/restapi/operations"
"github.com/minio/console/restapi/operations/user_api"
@@ -36,7 +34,7 @@ func registerServiceAccountsHandlers(api *operations.ConsoleAPI) {
api.UserAPICreateServiceAccountHandler = user_api.CreateServiceAccountHandlerFunc(func(params user_api.CreateServiceAccountParams, session *models.Principal) middleware.Responder {
creds, err := getCreateServiceAccountResponse(session, params.Body)
if err != nil {
return user_api.NewCreateServiceAccountDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return user_api.NewCreateServiceAccountDefault(int(err.Code)).WithPayload(err)
}
return user_api.NewCreateServiceAccountCreated().WithPayload(creds)
})
@@ -44,7 +42,7 @@ func registerServiceAccountsHandlers(api *operations.ConsoleAPI) {
api.UserAPIListUserServiceAccountsHandler = user_api.ListUserServiceAccountsHandlerFunc(func(params user_api.ListUserServiceAccountsParams, session *models.Principal) middleware.Responder {
serviceAccounts, err := getUserServiceAccountsResponse(session)
if err != nil {
return user_api.NewListUserServiceAccountsDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return user_api.NewListUserServiceAccountsDefault(int(err.Code)).WithPayload(err)
}
return user_api.NewListUserServiceAccountsOK().WithPayload(serviceAccounts)
})
@@ -52,7 +50,7 @@ func registerServiceAccountsHandlers(api *operations.ConsoleAPI) {
// Delete a User's service account
api.UserAPIDeleteServiceAccountHandler = user_api.DeleteServiceAccountHandlerFunc(func(params user_api.DeleteServiceAccountParams, session *models.Principal) middleware.Responder {
if err := getDeleteServiceAccountResponse(session, params.AccessKey); err != nil {
return user_api.NewDeleteServiceAccountDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
return user_api.NewDeleteServiceAccountDefault(int(err.Code)).WithPayload(err)
}
return user_api.NewDeleteServiceAccountNoContent()
})
@@ -79,14 +77,13 @@ func createServiceAccount(ctx context.Context, userClient MinioAdmin, policy str
// getCreateServiceAccountResponse creates a service account with the defined policy for the user that
// is requestingit ,it first gets the credentials of the user and creates a client which is going to
// make the call to create the Service Account
func getCreateServiceAccountResponse(session *models.Principal, serviceAccount *models.ServiceAccountRequest) (*models.ServiceAccountCreds, error) {
func getCreateServiceAccountResponse(session *models.Principal, serviceAccount *models.ServiceAccountRequest) (*models.ServiceAccountCreds, *models.Error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*20)
defer cancel()
userAdmin, err := newMAdminClient(session)
if err != nil {
log.Println("error creating user Client:", err)
return nil, err
return nil, prepareError(err)
}
// create a MinIO user Admin Client interface implementation
// defining the client to be used
@@ -94,8 +91,7 @@ func getCreateServiceAccountResponse(session *models.Principal, serviceAccount *
saCreds, err := createServiceAccount(ctx, userAdminClient, serviceAccount.Policy)
if err != nil {
log.Println("error creating service account:", err)
return nil, err
return nil, prepareError(err)
}
return saCreds, nil
}
@@ -115,14 +111,13 @@ func getUserServiceAccounts(ctx context.Context, userClient MinioAdmin) (models.
// getUserServiceAccountsResponse authenticates the user and calls
// getUserServiceAccounts to list the user's service accounts
func getUserServiceAccountsResponse(session *models.Principal) (models.ServiceAccounts, error) {
func getUserServiceAccountsResponse(session *models.Principal) (models.ServiceAccounts, *models.Error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*20)
defer cancel()
userAdmin, err := newMAdminClient(session)
if err != nil {
log.Println("error creating user Client:", err)
return nil, err
return nil, prepareError(err)
}
// create a MinIO user Admin Client interface implementation
// defining the client to be used
@@ -130,11 +125,9 @@ func getUserServiceAccountsResponse(session *models.Principal) (models.ServiceAc
serviceAccounts, err := getUserServiceAccounts(ctx, userAdminClient)
if err != nil {
log.Println("error listing user's service account:", err)
return nil, err
return nil, prepareError(err)
}
return serviceAccounts, nil
}
// deleteServiceAccount calls delete service account api
@@ -143,22 +136,20 @@ func deleteServiceAccount(ctx context.Context, userClient MinioAdmin, accessKey
}
// getDeleteServiceAccountResponse authenticates the user and calls deleteServiceAccount
func getDeleteServiceAccountResponse(session *models.Principal, accessKey string) error {
func getDeleteServiceAccountResponse(session *models.Principal, accessKey string) *models.Error {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*20)
defer cancel()
userAdmin, err := newMAdminClient(session)
if err != nil {
log.Println("error creating user Client:", err)
return err
return prepareError(err)
}
// create a MinIO user Admin Client interface implementation
// defining the client to be used
userAdminClient := adminClient{client: userAdmin}
if err := deleteServiceAccount(ctx, userAdminClient, accessKey); err != nil {
log.Println("error deleting user's service account:", err)
return err
return prepareError(err)
}
return nil
}

View File

@@ -17,36 +17,29 @@
package restapi
import (
"errors"
"github.com/go-openapi/runtime/middleware"
"github.com/go-openapi/swag"
"github.com/minio/console/models"
"github.com/minio/console/pkg/acl"
"github.com/minio/console/restapi/operations"
"github.com/minio/console/restapi/operations/user_api"
)
var (
errorGenericInvalidSession = errors.New("invalid session")
)
func registerSessionHandlers(api *operations.ConsoleAPI) {
// session check
api.UserAPISessionCheckHandler = user_api.SessionCheckHandlerFunc(func(params user_api.SessionCheckParams, session *models.Principal) middleware.Responder {
sessionResp, err := getSessionResponse(session)
if err != nil {
return user_api.NewSessionCheckDefault(401).WithPayload(&models.Error{Code: 401, Message: swag.String(err.Error())})
return user_api.NewSessionCheckDefault(int(err.Code)).WithPayload(err)
}
return user_api.NewSessionCheckOK().WithPayload(sessionResp)
})
}
// getSessionResponse parse the jwt of the current session and returns a list of allowed actions to render in the UI
func getSessionResponse(session *models.Principal) (*models.SessionResponse, error) {
func getSessionResponse(session *models.Principal) (*models.SessionResponse, *models.Error) {
// serialize output
if session == nil {
return nil, errorGenericInvalidSession
return nil, prepareError(errorGenericInvalidSession)
}
sessionResp := &models.SessionResponse{
Pages: acl.GetAuthorizedEndpoints(session.Actions),

View File

@@ -1355,7 +1355,7 @@ definitions:
properties:
code:
type: integer
format: int64
format: int32
message:
type: string
user:
@@ -1828,6 +1828,8 @@ definitions:
type: string
creation_date:
type: string
deletion_date:
type: string
currentState:
type: string
zones:
@@ -1836,11 +1838,15 @@ definitions:
$ref: "#/definitions/zone"
image:
type: string
console_image:
type: string
namespace:
type: string
total_size:
type: integer
format: int64
enable_prometheus:
type: boolean
tenantUsage:
type: object
@@ -1867,6 +1873,8 @@ definitions:
type: integer
creation_date:
type: string
deletion_date:
type: string
currentState:
type: string
namespace:
@@ -1898,6 +1906,8 @@ definitions:
$ref: "#/definitions/imageRegistry"
image_pull_secret:
type: string
enable_prometheus:
type: boolean
imageRegistry:
type: object