Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
af4bebb6eb | ||
|
|
8530eb5368 | ||
|
|
0ba1e76400 | ||
|
|
94096ee657 | ||
|
|
c59387c2b4 | ||
|
|
c5a3eff745 | ||
|
|
624891ae1f | ||
|
|
83435e1ab9 | ||
|
|
2b4606e773 | ||
|
|
30f5943f8a | ||
|
|
412ac0a603 | ||
|
|
b2aa1349f8 | ||
|
|
8b62aec7fb | ||
|
|
83fe33b499 | ||
|
|
54d0a1d342 | ||
|
|
c59737a71d | ||
|
|
7c2ba707eb | ||
|
|
545a890c45 |
4
go.mod
4
go.mod
@@ -19,14 +19,14 @@ require (
|
|||||||
github.com/minio/mc v0.0.0-20200808005614-7e52c104bee1
|
github.com/minio/mc v0.0.0-20200808005614-7e52c104bee1
|
||||||
github.com/minio/minio v0.0.0-20200808024306-2a9819aff876
|
github.com/minio/minio v0.0.0-20200808024306-2a9819aff876
|
||||||
github.com/minio/minio-go/v7 v7.0.5-0.20200807085956-d7db33ea7618
|
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/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect
|
||||||
github.com/secure-io/sio-go v0.3.1
|
github.com/secure-io/sio-go v0.3.1
|
||||||
github.com/stretchr/testify v1.6.1
|
github.com/stretchr/testify v1.6.1
|
||||||
github.com/unrolled/secure v1.0.7
|
github.com/unrolled/secure v1.0.7
|
||||||
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de
|
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de
|
||||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381
|
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
|
gopkg.in/yaml.v2 v2.3.0
|
||||||
k8s.io/api v0.18.6
|
k8s.io/api v0.18.6
|
||||||
k8s.io/apimachinery v0.18.6
|
k8s.io/apimachinery v0.18.6
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ spec:
|
|||||||
serviceAccountName: console-sa
|
serviceAccountName: console-sa
|
||||||
containers:
|
containers:
|
||||||
- name: console
|
- name: console
|
||||||
image: minio/console:v0.3.14
|
image: minio/console:v0.3.20
|
||||||
imagePullPolicy: "IfNotPresent"
|
imagePullPolicy: "IfNotPresent"
|
||||||
args:
|
args:
|
||||||
- server
|
- server
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ rules:
|
|||||||
- list
|
- list
|
||||||
- patch
|
- patch
|
||||||
- update
|
- update
|
||||||
|
- deletecollection
|
||||||
- apiGroups:
|
- apiGroups:
|
||||||
- ""
|
- ""
|
||||||
resources:
|
resources:
|
||||||
@@ -22,6 +23,7 @@ rules:
|
|||||||
- services
|
- services
|
||||||
- events
|
- events
|
||||||
- resourcequotas
|
- resourcequotas
|
||||||
|
- nodes
|
||||||
verbs:
|
verbs:
|
||||||
- get
|
- get
|
||||||
- watch
|
- watch
|
||||||
@@ -34,6 +36,8 @@ rules:
|
|||||||
- persistentvolumeclaims
|
- persistentvolumeclaims
|
||||||
verbs:
|
verbs:
|
||||||
- deletecollection
|
- deletecollection
|
||||||
|
- list
|
||||||
|
- get
|
||||||
- apiGroups:
|
- apiGroups:
|
||||||
- "storage.k8s.io"
|
- "storage.k8s.io"
|
||||||
resources:
|
resources:
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ spec:
|
|||||||
serviceAccountName: console-sa
|
serviceAccountName: console-sa
|
||||||
containers:
|
containers:
|
||||||
- name: console
|
- name: console
|
||||||
image: minio/console:v0.3.14
|
image: minio/console:v0.3.20
|
||||||
imagePullPolicy: "IfNotPresent"
|
imagePullPolicy: "IfNotPresent"
|
||||||
env:
|
env:
|
||||||
- name: CONSOLE_OPERATOR_MODE
|
- name: CONSOLE_OPERATOR_MODE
|
||||||
|
|||||||
@@ -48,6 +48,9 @@ type CreateTenantRequest struct {
|
|||||||
// enable console
|
// enable console
|
||||||
EnableConsole *bool `json:"enable_console,omitempty"`
|
EnableConsole *bool `json:"enable_console,omitempty"`
|
||||||
|
|
||||||
|
// enable prometheus
|
||||||
|
EnablePrometheus *bool `json:"enable_prometheus,omitempty"`
|
||||||
|
|
||||||
// enable tls
|
// enable tls
|
||||||
EnableTLS *bool `json:"enable_tls,omitempty"`
|
EnableTLS *bool `json:"enable_tls,omitempty"`
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ import (
|
|||||||
type Error struct {
|
type Error struct {
|
||||||
|
|
||||||
// code
|
// code
|
||||||
Code int64 `json:"code,omitempty"`
|
Code int32 `json:"code,omitempty"`
|
||||||
|
|
||||||
// message
|
// message
|
||||||
// Required: true
|
// Required: true
|
||||||
|
|||||||
60
models/max_allocatable_mem_response.go
Normal file
60
models/max_allocatable_mem_response.go
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
// 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/strfmt"
|
||||||
|
"github.com/go-openapi/swag"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MaxAllocatableMemResponse max allocatable mem response
|
||||||
|
//
|
||||||
|
// swagger:model maxAllocatableMemResponse
|
||||||
|
type MaxAllocatableMemResponse struct {
|
||||||
|
|
||||||
|
// max memory
|
||||||
|
MaxMemory int64 `json:"max_memory,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate validates this max allocatable mem response
|
||||||
|
func (m *MaxAllocatableMemResponse) Validate(formats strfmt.Registry) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalBinary interface implementation
|
||||||
|
func (m *MaxAllocatableMemResponse) MarshalBinary() ([]byte, error) {
|
||||||
|
if m == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
return swag.WriteJSON(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalBinary interface implementation
|
||||||
|
func (m *MaxAllocatableMemResponse) UnmarshalBinary(b []byte) error {
|
||||||
|
var res MaxAllocatableMemResponse
|
||||||
|
if err := swag.ReadJSON(b, &res); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*m = res
|
||||||
|
return nil
|
||||||
|
}
|
||||||
113
models/update_certificates_request.go
Normal file
113
models/update_certificates_request.go
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
// 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
|
||||||
|
}
|
||||||
@@ -207,6 +207,9 @@ func (m *Zone) UnmarshalBinary(b []byte) error {
|
|||||||
// swagger:model ZoneVolumeConfiguration
|
// swagger:model ZoneVolumeConfiguration
|
||||||
type ZoneVolumeConfiguration struct {
|
type ZoneVolumeConfiguration struct {
|
||||||
|
|
||||||
|
// labels
|
||||||
|
Labels map[string]string `json:"labels,omitempty"`
|
||||||
|
|
||||||
// size
|
// size
|
||||||
// Required: true
|
// Required: true
|
||||||
Size *int64 `json:"size"`
|
Size *int64 `json:"size"`
|
||||||
|
|||||||
99
models/zone_update_request.go
Normal file
99
models/zone_update_request.go
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
// 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 (
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/go-openapi/errors"
|
||||||
|
"github.com/go-openapi/strfmt"
|
||||||
|
"github.com/go-openapi/swag"
|
||||||
|
"github.com/go-openapi/validate"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ZoneUpdateRequest zone update request
|
||||||
|
//
|
||||||
|
// swagger:model zoneUpdateRequest
|
||||||
|
type ZoneUpdateRequest struct {
|
||||||
|
|
||||||
|
// zones
|
||||||
|
// Required: true
|
||||||
|
Zones []*Zone `json:"zones"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate validates this zone update request
|
||||||
|
func (m *ZoneUpdateRequest) Validate(formats strfmt.Registry) error {
|
||||||
|
var res []error
|
||||||
|
|
||||||
|
if err := m.validateZones(formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(res) > 0 {
|
||||||
|
return errors.CompositeValidationError(res...)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *ZoneUpdateRequest) validateZones(formats strfmt.Registry) error {
|
||||||
|
|
||||||
|
if err := validate.Required("zones", "body", m.Zones); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < len(m.Zones); i++ {
|
||||||
|
if swag.IsZero(m.Zones[i]) { // not required
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if m.Zones[i] != nil {
|
||||||
|
if err := m.Zones[i].Validate(formats); err != nil {
|
||||||
|
if ve, ok := err.(*errors.Validation); ok {
|
||||||
|
return ve.ValidateName("zones" + "." + strconv.Itoa(i))
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalBinary interface implementation
|
||||||
|
func (m *ZoneUpdateRequest) MarshalBinary() ([]byte, error) {
|
||||||
|
if m == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
return swag.WriteJSON(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalBinary interface implementation
|
||||||
|
func (m *ZoneUpdateRequest) UnmarshalBinary(b []byte) error {
|
||||||
|
var res ZoneUpdateRequest
|
||||||
|
if err := swag.ReadJSON(b, &res); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*m = res
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -18,11 +18,9 @@ package restapi
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"log"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-openapi/runtime/middleware"
|
"github.com/go-openapi/runtime/middleware"
|
||||||
"github.com/go-openapi/swag"
|
|
||||||
"github.com/minio/console/models"
|
"github.com/minio/console/models"
|
||||||
"github.com/minio/console/restapi/operations"
|
"github.com/minio/console/restapi/operations"
|
||||||
"github.com/minio/console/restapi/operations/admin_api"
|
"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 {
|
api.AdminAPIArnListHandler = admin_api.ArnListHandlerFunc(func(params admin_api.ArnListParams, session *models.Principal) middleware.Responder {
|
||||||
arnsResp, err := getArnsResponse(session)
|
arnsResp, err := getArnsResponse(session)
|
||||||
if err != nil {
|
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)
|
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
|
// 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)
|
mAdmin, err := newMAdminClient(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating Madmin Client:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
// create a minioClient interface implementation
|
// create a minioClient interface implementation
|
||||||
// defining the client to be used
|
// defining the client to be used
|
||||||
@@ -68,8 +65,7 @@ func getArnsResponse(session *models.Principal) (*models.ArnsResponse, error) {
|
|||||||
// serialize output
|
// serialize output
|
||||||
arnsList, err := getArns(ctx, adminClient)
|
arnsList, err := getArns(ctx, adminClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error getting arn list:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
return arnsList, nil
|
return arnsList, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ package restapi
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/go-openapi/runtime/middleware"
|
"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 {
|
api.AdminAPIListConfigHandler = admin_api.ListConfigHandlerFunc(func(params admin_api.ListConfigParams, session *models.Principal) middleware.Responder {
|
||||||
configListResp, err := getListConfigResponse(session)
|
configListResp, err := getListConfigResponse(session)
|
||||||
if err != nil {
|
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)
|
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 {
|
api.AdminAPIConfigInfoHandler = admin_api.ConfigInfoHandlerFunc(func(params admin_api.ConfigInfoParams, session *models.Principal) middleware.Responder {
|
||||||
config, err := getConfigResponse(session, params)
|
config, err := getConfigResponse(session, params)
|
||||||
if err != nil {
|
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)
|
return admin_api.NewConfigInfoOK().WithPayload(config)
|
||||||
})
|
})
|
||||||
// Set Configuration
|
// Set Configuration
|
||||||
api.AdminAPISetConfigHandler = admin_api.SetConfigHandlerFunc(func(params admin_api.SetConfigParams, session *models.Principal) middleware.Responder {
|
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 {
|
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()
|
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
|
// 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)
|
mAdmin, err := newMAdminClient(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating Madmin Client:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
// create a MinIO Admin Client interface implementation
|
// create a MinIO Admin Client interface implementation
|
||||||
// defining the client to be used
|
// defining the client to be used
|
||||||
@@ -88,8 +86,7 @@ func getListConfigResponse(session *models.Principal) (*models.ListConfigRespons
|
|||||||
|
|
||||||
configDescs, err := listConfig(adminClient)
|
configDescs, err := listConfig(adminClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error listing configurations:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
listGroupsResponse := &models.ListConfigResponse{
|
listGroupsResponse := &models.ListConfigResponse{
|
||||||
Configurations: configDescs,
|
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
|
// 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)
|
mAdmin, err := newMAdminClient(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating Madmin Client:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
// create a MinIO Admin Client interface implementation
|
// create a MinIO Admin Client interface implementation
|
||||||
// defining the client to be used
|
// 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)
|
configkv, err := getConfig(adminClient, params.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error getting configuration:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
configurationObj := &models.Configuration{
|
configurationObj := &models.Configuration{
|
||||||
Name: params.Name,
|
Name: params.Name,
|
||||||
@@ -180,11 +175,10 @@ func buildConfig(configName *string, kvs []*models.ConfigurationKV) *string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// setConfigResponse implements setConfig() to be used by handler
|
// 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)
|
mAdmin, err := newMAdminClient(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating Madmin Client:", err)
|
return prepareError(err)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
// create a MinIO Admin Client interface implementation
|
// create a MinIO Admin Client interface implementation
|
||||||
// defining the client to be used
|
// defining the client to be used
|
||||||
@@ -194,8 +188,7 @@ func setConfigResponse(session *models.Principal, name string, configRequest *mo
|
|||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
if err := setConfigWithARNAccountID(ctx, adminClient, &configName, configRequest.KeyValues, configRequest.ArnResourceID); err != nil {
|
if err := setConfigWithARNAccountID(ctx, adminClient, &configName, configRequest.KeyValues, configRequest.ArnResourceID); err != nil {
|
||||||
log.Println("error listing configurations:", err)
|
return prepareError(err)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import (
|
|||||||
|
|
||||||
"github.com/go-openapi/errors"
|
"github.com/go-openapi/errors"
|
||||||
"github.com/go-openapi/runtime/middleware"
|
"github.com/go-openapi/runtime/middleware"
|
||||||
"github.com/go-openapi/swag"
|
|
||||||
"github.com/minio/console/restapi/operations"
|
"github.com/minio/console/restapi/operations"
|
||||||
"github.com/minio/minio/pkg/madmin"
|
"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 {
|
api.AdminAPIListGroupsHandler = admin_api.ListGroupsHandlerFunc(func(params admin_api.ListGroupsParams, session *models.Principal) middleware.Responder {
|
||||||
listGroupsResponse, err := getListGroupsResponse(session)
|
listGroupsResponse, err := getListGroupsResponse(session)
|
||||||
if err != nil {
|
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)
|
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 {
|
api.AdminAPIGroupInfoHandler = admin_api.GroupInfoHandlerFunc(func(params admin_api.GroupInfoParams, session *models.Principal) middleware.Responder {
|
||||||
groupInfo, err := getGroupInfoResponse(session, params)
|
groupInfo, err := getGroupInfoResponse(session, params)
|
||||||
if err != nil {
|
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)
|
return admin_api.NewGroupInfoOK().WithPayload(groupInfo)
|
||||||
})
|
})
|
||||||
// Add Group
|
// Add Group
|
||||||
api.AdminAPIAddGroupHandler = admin_api.AddGroupHandlerFunc(func(params admin_api.AddGroupParams, session *models.Principal) middleware.Responder {
|
api.AdminAPIAddGroupHandler = admin_api.AddGroupHandlerFunc(func(params admin_api.AddGroupParams, session *models.Principal) middleware.Responder {
|
||||||
if err := getAddGroupResponse(session, params.Body); err != nil {
|
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()
|
return admin_api.NewAddGroupCreated()
|
||||||
})
|
})
|
||||||
// Remove Group
|
// Remove Group
|
||||||
api.AdminAPIRemoveGroupHandler = admin_api.RemoveGroupHandlerFunc(func(params admin_api.RemoveGroupParams, session *models.Principal) middleware.Responder {
|
api.AdminAPIRemoveGroupHandler = admin_api.RemoveGroupHandlerFunc(func(params admin_api.RemoveGroupParams, session *models.Principal) middleware.Responder {
|
||||||
if err := getRemoveGroupResponse(session, params); err != nil {
|
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()
|
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 {
|
api.AdminAPIUpdateGroupHandler = admin_api.UpdateGroupHandlerFunc(func(params admin_api.UpdateGroupParams, session *models.Principal) middleware.Responder {
|
||||||
groupUpdateResp, err := getUpdateGroupResponse(session, params)
|
groupUpdateResp, err := getUpdateGroupResponse(session, params)
|
||||||
if err != nil {
|
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)
|
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
|
// 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()
|
ctx := context.Background()
|
||||||
mAdmin, err := newMAdminClient(session)
|
mAdmin, err := newMAdminClient(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating Madmin Client:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
// create a MinIO Admin Client interface implementation
|
// create a MinIO Admin Client interface implementation
|
||||||
// defining the client to be used
|
// defining the client to be used
|
||||||
@@ -95,8 +93,7 @@ func getListGroupsResponse(session *models.Principal) (*models.ListGroupsRespons
|
|||||||
|
|
||||||
groups, err := listGroups(ctx, adminClient)
|
groups, err := listGroups(ctx, adminClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error listing groups:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
// serialize output
|
// serialize output
|
||||||
listGroupsResponse := &models.ListGroupsResponse{
|
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
|
// 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()
|
ctx := context.Background()
|
||||||
mAdmin, err := newMAdminClient(session)
|
mAdmin, err := newMAdminClient(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating Madmin Client:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
// create a MinIO Admin Client interface implementation
|
// create a MinIO Admin Client interface implementation
|
||||||
// defining the client to be used
|
// 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)
|
groupDesc, err := groupInfo(ctx, adminClient, params.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error getting group info:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
groupResponse := &models.Group{
|
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
|
// 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()
|
ctx := context.Background()
|
||||||
// AddGroup request needed to proceed
|
// AddGroup request needed to proceed
|
||||||
if params == nil {
|
if params == nil {
|
||||||
log.Println("error AddGroup body not in request")
|
return prepareError(errGroupBodyNotInRequest)
|
||||||
return errors.New(500, "error AddGroup body not in request")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mAdmin, err := newMAdminClient(session)
|
mAdmin, err := newMAdminClient(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating Madmin Client:", err)
|
return prepareError(err)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
// create a MinIO Admin Client interface implementation
|
// create a MinIO Admin Client interface implementation
|
||||||
// defining the client to be used
|
// defining the client to be used
|
||||||
adminClient := adminClient{client: mAdmin}
|
adminClient := adminClient{client: mAdmin}
|
||||||
|
|
||||||
if err := addGroup(ctx, adminClient, *params.Group, params.Members); err != nil {
|
if err := addGroup(ctx, adminClient, *params.Group, params.Members); err != nil {
|
||||||
log.Println("error adding group:", err)
|
return prepareError(err)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
return nil
|
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
|
// 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()
|
ctx := context.Background()
|
||||||
|
|
||||||
if params.Name == "" {
|
if params.Name == "" {
|
||||||
log.Println("error group name not in request")
|
return prepareError(errGroupNameNotInRequest)
|
||||||
return errors.New(500, "error group name not in request")
|
|
||||||
}
|
}
|
||||||
mAdmin, err := newMAdminClient(session)
|
mAdmin, err := newMAdminClient(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating Madmin Client:", err)
|
return prepareError(err)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
// create a MinIO Admin Client interface implementation
|
// create a MinIO Admin Client interface implementation
|
||||||
// defining the client to be used
|
// defining the client to be used
|
||||||
adminClient := adminClient{client: mAdmin}
|
adminClient := adminClient{client: mAdmin}
|
||||||
|
|
||||||
if err := removeGroup(ctx, adminClient, params.Name); err != nil {
|
if err := removeGroup(ctx, adminClient, params.Name); err != nil {
|
||||||
log.Println("error removing group:", err)
|
return prepareError(err)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
return nil
|
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,
|
// 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.
|
// 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.
|
// 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()
|
ctx := context.Background()
|
||||||
if params.Name == "" {
|
if params.Name == "" {
|
||||||
log.Println("error group name not in request")
|
return nil, prepareError(errGroupNameNotInRequest)
|
||||||
return nil, errors.New(500, "error group name not in request")
|
|
||||||
}
|
}
|
||||||
if params.Body == nil {
|
if params.Body == nil {
|
||||||
log.Println("error body not in request")
|
return nil, prepareError(errGroupBodyNotInRequest)
|
||||||
return nil, errors.New(500, "error body not in request")
|
|
||||||
}
|
}
|
||||||
expectedGroupUpdate := params.Body
|
expectedGroupUpdate := params.Body
|
||||||
groupName := params.Name
|
groupName := params.Name
|
||||||
|
|
||||||
mAdmin, err := newMAdminClient(session)
|
mAdmin, err := newMAdminClient(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating Madmin Client:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
// create a MinIO Admin Client interface implementation
|
// create a MinIO Admin Client interface implementation
|
||||||
// defining the client to be used
|
// 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)
|
groupUpdated, err := groupUpdate(ctx, adminClient, groupName, expectedGroupUpdate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error updating group:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
groupResponse := &models.Group{
|
groupResponse := &models.Group{
|
||||||
Name: groupUpdated.Name,
|
Name: groupUpdated.Name,
|
||||||
|
|||||||
@@ -18,11 +18,9 @@ package restapi
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"log"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-openapi/runtime/middleware"
|
"github.com/go-openapi/runtime/middleware"
|
||||||
"github.com/go-openapi/swag"
|
|
||||||
"github.com/minio/console/models"
|
"github.com/minio/console/models"
|
||||||
"github.com/minio/console/restapi/operations"
|
"github.com/minio/console/restapi/operations"
|
||||||
"github.com/minio/console/restapi/operations/admin_api"
|
"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 {
|
api.AdminAPIAdminInfoHandler = admin_api.AdminInfoHandlerFunc(func(params admin_api.AdminInfoParams, session *models.Principal) middleware.Responder {
|
||||||
infoResp, err := getAdminInfoResponse(session)
|
infoResp, err := getAdminInfoResponse(session)
|
||||||
if err != nil {
|
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)
|
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.
|
// 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)
|
mAdmin, err := newMAdminClient(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating Madmin Client:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
// create a minioClient interface implementation
|
// create a minioClient interface implementation
|
||||||
// defining the client to be used
|
// defining the client to be used
|
||||||
@@ -87,8 +84,7 @@ func getAdminInfoResponse(session *models.Principal) (*models.AdminInfoResponse,
|
|||||||
// serialize output
|
// serialize output
|
||||||
usage, err := getAdminInfo(ctx, adminClient)
|
usage, err := getAdminInfo(ctx, adminClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error getting information:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
sessionResp := &models.AdminInfoResponse{
|
sessionResp := &models.AdminInfoResponse{
|
||||||
Buckets: usage.Buckets,
|
Buckets: usage.Buckets,
|
||||||
|
|||||||
136
restapi/admin_nodes.go
Normal file
136
restapi/admin_nodes.go
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
// 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 (
|
||||||
|
"context"
|
||||||
|
"sort"
|
||||||
|
|
||||||
|
"github.com/minio/console/cluster"
|
||||||
|
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"github.com/go-openapi/runtime/middleware"
|
||||||
|
"github.com/minio/console/models"
|
||||||
|
"github.com/minio/console/restapi/operations"
|
||||||
|
"github.com/minio/console/restapi/operations/admin_api"
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
v1 "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
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(int(err.Code)).WithPayload(err)
|
||||||
|
}
|
||||||
|
return admin_api.NewGetMaxAllocatableMemOK().WithPayload(resp)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// getMaxAllocatableMemory get max allocatable memory given a desired number of nodes
|
||||||
|
func getMaxAllocatableMemory(ctx context.Context, clientset v1.CoreV1Interface, numNodes int32) (*models.MaxAllocatableMemResponse, error) {
|
||||||
|
if numNodes == 0 {
|
||||||
|
return nil, errors.New("error NumNodes must be greated than 0")
|
||||||
|
}
|
||||||
|
|
||||||
|
// get all nodes from cluster
|
||||||
|
nodes, err := clientset.Nodes().List(ctx, metav1.ListOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
availableMemSizes := []int64{}
|
||||||
|
OUTER:
|
||||||
|
for _, n := range nodes.Items {
|
||||||
|
// Don't consider node if it has a NoSchedule or NoExecute Taint
|
||||||
|
for _, t := range n.Spec.Taints {
|
||||||
|
switch t.Effect {
|
||||||
|
case corev1.TaintEffectNoSchedule:
|
||||||
|
continue OUTER
|
||||||
|
case corev1.TaintEffectNoExecute:
|
||||||
|
continue OUTER
|
||||||
|
default:
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if quantity, ok := n.Status.Allocatable[corev1.ResourceMemory]; ok {
|
||||||
|
availableMemSizes = append(availableMemSizes, quantity.Value())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
maxAllocatableMemory := getMaxClusterMemory(numNodes, availableMemSizes)
|
||||||
|
|
||||||
|
res := &models.MaxAllocatableMemResponse{
|
||||||
|
MaxMemory: maxAllocatableMemory,
|
||||||
|
}
|
||||||
|
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// getMaxClusterMemory returns the maximum memory size that can be used
|
||||||
|
// across numNodes (number of nodes)
|
||||||
|
func getMaxClusterMemory(numNodes int32, nodesMemorySizes []int64) int64 {
|
||||||
|
if int32(len(nodesMemorySizes)) < numNodes || numNodes == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// sort nodesMemorySizes int64 array
|
||||||
|
sort.Slice(nodesMemorySizes, func(i, j int) bool { return nodesMemorySizes[i] < nodesMemorySizes[j] })
|
||||||
|
maxIndex := 0
|
||||||
|
maxAllocatableMemory := nodesMemorySizes[maxIndex]
|
||||||
|
|
||||||
|
for i, size := range nodesMemorySizes {
|
||||||
|
// maxAllocatableMemory is the minimum value of nodesMemorySizes array
|
||||||
|
// only within the size of numNodes, if more nodes are available
|
||||||
|
// then the maxAllocatableMemory is equal to the next minimum value
|
||||||
|
// on the sorted nodesMemorySizes array.
|
||||||
|
// e.g. with numNodes = 4;
|
||||||
|
// maxAllocatableMemory of [2,4,8,8] => 2
|
||||||
|
// maxAllocatableMemory of [2,4,8,8,16] => 4
|
||||||
|
if int32(i) < numNodes {
|
||||||
|
maxAllocatableMemory = min(maxAllocatableMemory, size)
|
||||||
|
} else {
|
||||||
|
maxIndex++
|
||||||
|
maxAllocatableMemory = nodesMemorySizes[maxIndex]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return maxAllocatableMemory
|
||||||
|
}
|
||||||
|
|
||||||
|
// min returns the smaller of x or y.
|
||||||
|
func min(x, y int64) int64 {
|
||||||
|
if x > y {
|
||||||
|
return y
|
||||||
|
}
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
|
||||||
|
func getMaxAllocatableMemoryResponse(session *models.Principal, numNodes int32) (*models.MaxAllocatableMemResponse, *models.Error) {
|
||||||
|
ctx := context.Background()
|
||||||
|
client, err := cluster.K8sClient(session.SessionToken)
|
||||||
|
if err != nil {
|
||||||
|
return nil, prepareError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
clusterResources, err := getMaxAllocatableMemory(ctx, client.CoreV1(), numNodes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, prepareError(err)
|
||||||
|
}
|
||||||
|
return clusterResources, nil
|
||||||
|
}
|
||||||
366
restapi/admin_nodes_test.go
Normal file
366
restapi/admin_nodes_test.go
Normal file
@@ -0,0 +1,366 @@
|
|||||||
|
// 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 (
|
||||||
|
"context"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/minio/console/models"
|
||||||
|
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/api/resource"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"k8s.io/client-go/kubernetes/fake"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_MaxAllocatableMemory(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
ctx context.Context
|
||||||
|
numNodes int32
|
||||||
|
objs []runtime.Object
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
expected *models.MaxAllocatableMemResponse
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Get Max Ram No Taints",
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
numNodes: 2,
|
||||||
|
objs: []runtime.Object{
|
||||||
|
&corev1.Node{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "node1",
|
||||||
|
},
|
||||||
|
Status: corev1.NodeStatus{
|
||||||
|
Allocatable: corev1.ResourceList{
|
||||||
|
corev1.ResourceMemory: resource.MustParse("2Ki"),
|
||||||
|
corev1.ResourceCPU: resource.MustParse("4Ki"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&corev1.Node{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "node2",
|
||||||
|
},
|
||||||
|
Status: corev1.NodeStatus{
|
||||||
|
Allocatable: corev1.ResourceList{
|
||||||
|
corev1.ResourceMemory: resource.MustParse("512"),
|
||||||
|
corev1.ResourceCPU: resource.MustParse("1Ki"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: &models.MaxAllocatableMemResponse{
|
||||||
|
MaxMemory: int64(512),
|
||||||
|
},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Description: if there are more nodes than the amount
|
||||||
|
// of nodes we want to use, but one has taints of NoSchedule
|
||||||
|
// node should not be considered for max memory
|
||||||
|
name: "Get Max Ram on nodes with NoSchedule",
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
numNodes: 2,
|
||||||
|
objs: []runtime.Object{
|
||||||
|
&corev1.Node{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "node1",
|
||||||
|
},
|
||||||
|
Status: corev1.NodeStatus{
|
||||||
|
Allocatable: corev1.ResourceList{
|
||||||
|
corev1.ResourceMemory: resource.MustParse("2Ki"),
|
||||||
|
corev1.ResourceCPU: resource.MustParse("4Ki"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&corev1.Node{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "node2",
|
||||||
|
},
|
||||||
|
Spec: corev1.NodeSpec{
|
||||||
|
Taints: []corev1.Taint{
|
||||||
|
corev1.Taint{
|
||||||
|
Key: "node.kubernetes.io/unreachable",
|
||||||
|
Effect: corev1.TaintEffectNoSchedule,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Status: corev1.NodeStatus{
|
||||||
|
Allocatable: corev1.ResourceList{
|
||||||
|
corev1.ResourceMemory: resource.MustParse("6Ki"),
|
||||||
|
corev1.ResourceCPU: resource.MustParse("1Ki"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&corev1.Node{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "node3",
|
||||||
|
},
|
||||||
|
Status: corev1.NodeStatus{
|
||||||
|
Allocatable: corev1.ResourceList{
|
||||||
|
corev1.ResourceMemory: resource.MustParse("4Ki"),
|
||||||
|
corev1.ResourceCPU: resource.MustParse("1Ki"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: &models.MaxAllocatableMemResponse{
|
||||||
|
MaxMemory: int64(2048),
|
||||||
|
},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Description: if there are more nodes than the amount
|
||||||
|
// of nodes we want to use, but one has taints of NoExecute
|
||||||
|
// node should not be considered for max memory
|
||||||
|
// if one node has PreferNoSchedule that should be considered.
|
||||||
|
name: "Get Max Ram on nodes with NoExecute",
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
numNodes: 2,
|
||||||
|
objs: []runtime.Object{
|
||||||
|
&corev1.Node{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "node1",
|
||||||
|
},
|
||||||
|
Status: corev1.NodeStatus{
|
||||||
|
Allocatable: corev1.ResourceList{
|
||||||
|
corev1.ResourceMemory: resource.MustParse("2Ki"),
|
||||||
|
corev1.ResourceCPU: resource.MustParse("4Ki"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&corev1.Node{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "node2",
|
||||||
|
},
|
||||||
|
Spec: corev1.NodeSpec{
|
||||||
|
Taints: []corev1.Taint{
|
||||||
|
corev1.Taint{
|
||||||
|
Key: "node.kubernetes.io/unreachable",
|
||||||
|
Effect: corev1.TaintEffectNoExecute,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Status: corev1.NodeStatus{
|
||||||
|
Allocatable: corev1.ResourceList{
|
||||||
|
corev1.ResourceMemory: resource.MustParse("6Ki"),
|
||||||
|
corev1.ResourceCPU: resource.MustParse("1Ki"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&corev1.Node{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "node3",
|
||||||
|
},
|
||||||
|
Spec: corev1.NodeSpec{
|
||||||
|
Taints: []corev1.Taint{
|
||||||
|
corev1.Taint{
|
||||||
|
Key: "node.kubernetes.io/unreachable",
|
||||||
|
Effect: corev1.TaintEffectPreferNoSchedule,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Status: corev1.NodeStatus{
|
||||||
|
Allocatable: corev1.ResourceList{
|
||||||
|
corev1.ResourceMemory: resource.MustParse("4Ki"),
|
||||||
|
corev1.ResourceCPU: resource.MustParse("1Ki"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: &models.MaxAllocatableMemResponse{
|
||||||
|
MaxMemory: int64(2048),
|
||||||
|
},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Description: if there are more nodes than the amount
|
||||||
|
// of nodes we want to use, max allocatable memory should
|
||||||
|
// be the minimum ram on the n nodes requested
|
||||||
|
name: "Get Max Ram, several nodes available",
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
numNodes: 2,
|
||||||
|
objs: []runtime.Object{
|
||||||
|
&corev1.Node{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "node1",
|
||||||
|
},
|
||||||
|
Status: corev1.NodeStatus{
|
||||||
|
Allocatable: corev1.ResourceList{
|
||||||
|
corev1.ResourceMemory: resource.MustParse("2Ki"),
|
||||||
|
corev1.ResourceCPU: resource.MustParse("4Ki"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&corev1.Node{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "node2",
|
||||||
|
},
|
||||||
|
Status: corev1.NodeStatus{
|
||||||
|
Allocatable: corev1.ResourceList{
|
||||||
|
corev1.ResourceMemory: resource.MustParse("6Ki"),
|
||||||
|
corev1.ResourceCPU: resource.MustParse("1Ki"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&corev1.Node{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "node3",
|
||||||
|
},
|
||||||
|
Status: corev1.NodeStatus{
|
||||||
|
Allocatable: corev1.ResourceList{
|
||||||
|
corev1.ResourceMemory: resource.MustParse("4Ki"),
|
||||||
|
corev1.ResourceCPU: resource.MustParse("1Ki"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: &models.MaxAllocatableMemResponse{
|
||||||
|
MaxMemory: int64(4096),
|
||||||
|
},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Description: if request has nil as request, expect error
|
||||||
|
name: "Nil nodes should be greater than 0",
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
numNodes: 0,
|
||||||
|
},
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
kubeClient := fake.NewSimpleClientset(tt.args.objs...)
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got, err := getMaxAllocatableMemory(tt.args.ctx, kubeClient.CoreV1(), tt.args.numNodes)
|
||||||
|
if (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("getMaxAllocatableMemory() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(got, tt.expected) {
|
||||||
|
t.Errorf("\ngot: %d \nwant: %d", got, tt.expected)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_MaxMemoryFunc(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
numNodes int32
|
||||||
|
nodesMemorySizes []int64
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
expected int64
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Get Max memory",
|
||||||
|
args: args{
|
||||||
|
numNodes: int32(4),
|
||||||
|
nodesMemorySizes: []int64{4294967296, 8589934592, 8589934592, 17179869184, 17179869184, 17179869184, 25769803776, 25769803776, 68719476736},
|
||||||
|
},
|
||||||
|
expected: int64(17179869184),
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Description, if not enough nodes return 0
|
||||||
|
name: "Get Max memory Not enough nodes",
|
||||||
|
args: args{
|
||||||
|
numNodes: int32(4),
|
||||||
|
nodesMemorySizes: []int64{4294967296, 8589934592, 68719476736},
|
||||||
|
},
|
||||||
|
expected: int64(0),
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Description, if not enough nodes return 0
|
||||||
|
name: "Get Max memory no nodes",
|
||||||
|
args: args{
|
||||||
|
numNodes: int32(4),
|
||||||
|
nodesMemorySizes: []int64{},
|
||||||
|
},
|
||||||
|
expected: int64(0),
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Description, if not enough nodes return 0
|
||||||
|
name: "Get Max memory no nodes, no request",
|
||||||
|
args: args{
|
||||||
|
numNodes: int32(0),
|
||||||
|
nodesMemorySizes: []int64{},
|
||||||
|
},
|
||||||
|
expected: int64(0),
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Description, if there are multiple nodes
|
||||||
|
// and required nodes is only 1, max should be equal to max memory
|
||||||
|
name: "Get Max memory one node",
|
||||||
|
args: args{
|
||||||
|
numNodes: int32(1),
|
||||||
|
nodesMemorySizes: []int64{4294967296, 8589934592, 68719476736},
|
||||||
|
},
|
||||||
|
expected: int64(68719476736),
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Description: if more nodes max memory should be the minimum
|
||||||
|
// value across pairs of numNodes
|
||||||
|
name: "Get Max memory two nodes",
|
||||||
|
args: args{
|
||||||
|
numNodes: int32(2),
|
||||||
|
nodesMemorySizes: []int64{8589934592, 68719476736, 4294967296},
|
||||||
|
},
|
||||||
|
expected: int64(8589934592),
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Get Max Multiple Memory Sizes",
|
||||||
|
args: args{
|
||||||
|
numNodes: int32(4),
|
||||||
|
nodesMemorySizes: []int64{0, 0, 0, 0, 4294967296, 8589934592, 8589934592, 17179869184, 17179869184, 17179869184, 25769803776, 25769803776, 68719476736, 34359738368, 34359738368, 34359738368, 34359738368},
|
||||||
|
},
|
||||||
|
expected: int64(34359738368),
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got := getMaxClusterMemory(tt.args.numNodes, tt.args.nodesMemorySizes)
|
||||||
|
if !reflect.DeepEqual(got, tt.expected) {
|
||||||
|
t.Errorf("\ngot: %d \nwant: %d", got, tt.expected)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,11 +19,9 @@ package restapi
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"log"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-openapi/runtime/middleware"
|
"github.com/go-openapi/runtime/middleware"
|
||||||
"github.com/go-openapi/swag"
|
|
||||||
"github.com/minio/console/models"
|
"github.com/minio/console/models"
|
||||||
"github.com/minio/console/restapi/operations"
|
"github.com/minio/console/restapi/operations"
|
||||||
"github.com/minio/console/restapi/operations/admin_api"
|
"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 {
|
api.AdminAPINotificationEndpointListHandler = admin_api.NotificationEndpointListHandlerFunc(func(params admin_api.NotificationEndpointListParams, session *models.Principal) middleware.Responder {
|
||||||
notifEndpoints, err := getNotificationEndpointsResponse(session)
|
notifEndpoints, err := getNotificationEndpointsResponse(session)
|
||||||
if err != nil {
|
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)
|
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 {
|
api.AdminAPIAddNotificationEndpointHandler = admin_api.AddNotificationEndpointHandlerFunc(func(params admin_api.AddNotificationEndpointParams, session *models.Principal) middleware.Responder {
|
||||||
notifEndpoints, err := getAddNotificationEndpointResponse(session, ¶ms)
|
notifEndpoints, err := getAddNotificationEndpointResponse(session, ¶ms)
|
||||||
if err != nil {
|
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)
|
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
|
// 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)
|
mAdmin, err := newMAdminClient(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating Madmin Client:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
// create a minioClient interface implementation
|
// create a minioClient interface implementation
|
||||||
// defining the client to be used
|
// defining the client to be used
|
||||||
@@ -93,8 +90,7 @@ func getNotificationEndpointsResponse(session *models.Principal) (*models.NotifE
|
|||||||
// serialize output
|
// serialize output
|
||||||
notfEndpointResp, err := getNotificationEndpoints(ctx, adminClient)
|
notfEndpointResp, err := getNotificationEndpoints(ctx, adminClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error getting notification endpoint list:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
return notfEndpointResp, nil
|
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
|
// 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)
|
mAdmin, err := newMAdminClient(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating Madmin Client:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
// create a minioClient interface implementation
|
// create a minioClient interface implementation
|
||||||
// defining the client to be used
|
// defining the client to be used
|
||||||
@@ -165,8 +160,7 @@ func getAddNotificationEndpointResponse(session *models.Principal, params *admin
|
|||||||
// serialize output
|
// serialize output
|
||||||
notfEndpointResp, err := addNotificationEndpoint(ctx, adminClient, params)
|
notfEndpointResp, err := addNotificationEndpoint(ctx, adminClient, params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error getting notification endpoint list:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
return notfEndpointResp, nil
|
return notfEndpointResp, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,10 +22,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/go-openapi/errors"
|
|
||||||
|
|
||||||
"github.com/go-openapi/runtime/middleware"
|
"github.com/go-openapi/runtime/middleware"
|
||||||
"github.com/go-openapi/swag"
|
|
||||||
"github.com/minio/console/models"
|
"github.com/minio/console/models"
|
||||||
"github.com/minio/console/restapi/operations"
|
"github.com/minio/console/restapi/operations"
|
||||||
"github.com/minio/console/restapi/operations/admin_api"
|
"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 {
|
api.AdminAPIListPoliciesHandler = admin_api.ListPoliciesHandlerFunc(func(params admin_api.ListPoliciesParams, session *models.Principal) middleware.Responder {
|
||||||
listPoliciesResponse, err := getListPoliciesResponse(session)
|
listPoliciesResponse, err := getListPoliciesResponse(session)
|
||||||
if err != nil {
|
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)
|
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 {
|
api.AdminAPIPolicyInfoHandler = admin_api.PolicyInfoHandlerFunc(func(params admin_api.PolicyInfoParams, session *models.Principal) middleware.Responder {
|
||||||
policyInfo, err := getPolicyInfoResponse(session, params)
|
policyInfo, err := getPolicyInfoResponse(session, params)
|
||||||
if err != nil {
|
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)
|
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 {
|
api.AdminAPIAddPolicyHandler = admin_api.AddPolicyHandlerFunc(func(params admin_api.AddPolicyParams, session *models.Principal) middleware.Responder {
|
||||||
policyResponse, err := getAddPolicyResponse(session, params.Body)
|
policyResponse, err := getAddPolicyResponse(session, params.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return admin_api.NewAddPolicyDefault(500).WithPayload(&models.Error{
|
return admin_api.NewAddPolicyDefault(int(err.Code)).WithPayload(err)
|
||||||
Code: 500,
|
|
||||||
Message: swag.String(err.Error()),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
return admin_api.NewAddPolicyCreated().WithPayload(policyResponse)
|
return admin_api.NewAddPolicyCreated().WithPayload(policyResponse)
|
||||||
})
|
})
|
||||||
// Remove Policy
|
// Remove Policy
|
||||||
api.AdminAPIRemovePolicyHandler = admin_api.RemovePolicyHandlerFunc(func(params admin_api.RemovePolicyParams, session *models.Principal) middleware.Responder {
|
api.AdminAPIRemovePolicyHandler = admin_api.RemovePolicyHandlerFunc(func(params admin_api.RemovePolicyParams, session *models.Principal) middleware.Responder {
|
||||||
if err := getRemovePolicyResponse(session, params); err != nil {
|
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()
|
return admin_api.NewRemovePolicyNoContent()
|
||||||
})
|
})
|
||||||
// Set Policy
|
// Set Policy
|
||||||
api.AdminAPISetPolicyHandler = admin_api.SetPolicyHandlerFunc(func(params admin_api.SetPolicyParams, session *models.Principal) middleware.Responder {
|
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 {
|
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()
|
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
|
// 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()
|
ctx := context.Background()
|
||||||
mAdmin, err := newMAdminClient(session)
|
mAdmin, err := newMAdminClient(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating Madmin Client:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
// create a MinIO Admin Client interface implementation
|
// create a MinIO Admin Client interface implementation
|
||||||
// defining the client to be used
|
// defining the client to be used
|
||||||
@@ -110,8 +103,7 @@ func getListPoliciesResponse(session *models.Principal) (*models.ListPoliciesRes
|
|||||||
|
|
||||||
policies, err := listPolicies(ctx, adminClient)
|
policies, err := listPolicies(ctx, adminClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error listing policies:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
// serialize output
|
// serialize output
|
||||||
listPoliciesResponse := &models.ListPoliciesResponse{
|
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
|
// 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()
|
ctx := context.Background()
|
||||||
if params.Name == "" {
|
if params.Name == "" {
|
||||||
log.Println("error policy name not in request")
|
return prepareError(errPolicyNameNotInRequest)
|
||||||
return errors.New(500, "error policy name not in request")
|
|
||||||
}
|
}
|
||||||
mAdmin, err := newMAdminClient(session)
|
mAdmin, err := newMAdminClient(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating Madmin Client:", err)
|
return prepareError(err)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
// create a MinIO Admin Client interface implementation
|
// create a MinIO Admin Client interface implementation
|
||||||
// defining the client to be used
|
// defining the client to be used
|
||||||
adminClient := adminClient{client: mAdmin}
|
adminClient := adminClient{client: mAdmin}
|
||||||
|
|
||||||
if err := removePolicy(ctx, adminClient, params.Name); err != nil {
|
if err := removePolicy(ctx, adminClient, params.Name); err != nil {
|
||||||
log.Println("error removing policy:", err)
|
return prepareError(err)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
return nil
|
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
|
// 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()
|
ctx := context.Background()
|
||||||
if params == nil {
|
if params == nil {
|
||||||
log.Println("error AddPolicy body not in request")
|
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)
|
mAdmin, err := newMAdminClient(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating Madmin Client:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
// create a MinIO Admin Client interface implementation
|
// create a MinIO Admin Client interface implementation
|
||||||
// defining the client to be used
|
// defining the client to be used
|
||||||
adminClient := adminClient{client: mAdmin}
|
adminClient := adminClient{client: mAdmin}
|
||||||
policy, err := addPolicy(ctx, adminClient, *params.Name, *params.Policy)
|
policy, err := addPolicy(ctx, adminClient, *params.Name, *params.Policy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error adding policy")
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
return policy, nil
|
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
|
// 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()
|
ctx := context.Background()
|
||||||
mAdmin, err := newMAdminClient(session)
|
mAdmin, err := newMAdminClient(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating Madmin Client:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
// create a MinIO Admin Client interface implementation
|
// create a MinIO Admin Client interface implementation
|
||||||
// defining the client to be used
|
// defining the client to be used
|
||||||
adminClient := adminClient{client: mAdmin}
|
adminClient := adminClient{client: mAdmin}
|
||||||
policy, err := policyInfo(ctx, adminClient, params.Name)
|
policy, err := policyInfo(ctx, adminClient, params.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error getting group info:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
return policy, nil
|
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
|
// 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()
|
ctx := context.Background()
|
||||||
if name == "" {
|
if name == "" {
|
||||||
log.Println("error policy name not in request")
|
return prepareError(errPolicyNameNotInRequest)
|
||||||
return errors.New(500, "error policy name not in request")
|
|
||||||
}
|
}
|
||||||
mAdmin, err := newMAdminClient(session)
|
mAdmin, err := newMAdminClient(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating Madmin Client:", err)
|
return prepareError(err)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
// create a MinIO Admin Client interface implementation
|
// create a MinIO Admin Client interface implementation
|
||||||
// defining the client to be used
|
// defining the client to be used
|
||||||
adminClient := adminClient{client: mAdmin}
|
adminClient := adminClient{client: mAdmin}
|
||||||
|
|
||||||
if err := setPolicy(ctx, adminClient, name, *params.EntityName, params.EntityType); err != nil {
|
if err := setPolicy(ctx, adminClient, name, *params.EntityName, params.EntityType); err != nil {
|
||||||
log.Println("error setting policy:", err)
|
return prepareError(err)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,10 +22,8 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/go-openapi/errors"
|
|
||||||
"github.com/go-openapi/runtime"
|
"github.com/go-openapi/runtime"
|
||||||
"github.com/go-openapi/runtime/middleware"
|
"github.com/go-openapi/runtime/middleware"
|
||||||
"github.com/go-openapi/swag"
|
|
||||||
"github.com/minio/console/models"
|
"github.com/minio/console/models"
|
||||||
"github.com/minio/console/restapi/operations"
|
"github.com/minio/console/restapi/operations"
|
||||||
"github.com/minio/console/restapi/operations/admin_api"
|
"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 {
|
api.AdminAPIProfilingStartHandler = admin_api.ProfilingStartHandlerFunc(func(params admin_api.ProfilingStartParams, session *models.Principal) middleware.Responder {
|
||||||
profilingStartResponse, err := getProfilingStartResponse(session, params.Body)
|
profilingStartResponse, err := getProfilingStartResponse(session, params.Body)
|
||||||
if err != nil {
|
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)
|
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 {
|
api.AdminAPIProfilingStopHandler = admin_api.ProfilingStopHandlerFunc(func(params admin_api.ProfilingStopParams, session *models.Principal) middleware.Responder {
|
||||||
profilingStopResponse, err := getProfilingStopResponse(session)
|
profilingStopResponse, err := getProfilingStopResponse(session)
|
||||||
if err != nil {
|
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
|
// Custom response writer to set the content-disposition header to tell the
|
||||||
// HTTP client the name and extension of the file we are returning
|
// 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
|
// 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()
|
ctx := context.Background()
|
||||||
if params == nil {
|
if params == nil {
|
||||||
log.Println("error profiling type not in body request")
|
return nil, prepareError(errPolicyBodyNotInRequest)
|
||||||
return nil, errors.New(500, "error AddPolicy body not in request")
|
|
||||||
}
|
}
|
||||||
mAdmin, err := newMAdminClient(session)
|
mAdmin, err := newMAdminClient(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating Madmin Client:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
// create a MinIO Admin Client interface implementation
|
// create a MinIO Admin Client interface implementation
|
||||||
// defining the client to be used
|
// defining the client to be used
|
||||||
adminClient := adminClient{client: mAdmin}
|
adminClient := adminClient{client: mAdmin}
|
||||||
profilingItems, err := startProfiling(ctx, adminClient, params.Type)
|
profilingItems, err := startProfiling(ctx, adminClient, params.Type)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error starting profiling:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
profilingList := &models.StartProfilingList{
|
profilingList := &models.StartProfilingList{
|
||||||
StartResults: profilingItems,
|
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
|
// 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()
|
ctx := context.Background()
|
||||||
mAdmin, err := newMAdminClient(session)
|
mAdmin, err := newMAdminClient(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating Madmin Client:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
// create a MinIO Admin Client interface implementation
|
// create a MinIO Admin Client interface implementation
|
||||||
// defining the client to be used
|
// defining the client to be used
|
||||||
adminClient := adminClient{client: mAdmin}
|
adminClient := adminClient{client: mAdmin}
|
||||||
profilingData, err := stopProfiling(ctx, adminClient)
|
profilingData, err := stopProfiling(ctx, adminClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error stopping profiling:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
return profilingData, nil
|
return profilingData, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,11 +18,9 @@ package restapi
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"log"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-openapi/runtime/middleware"
|
"github.com/go-openapi/runtime/middleware"
|
||||||
"github.com/go-openapi/swag"
|
|
||||||
"github.com/minio/console/models"
|
"github.com/minio/console/models"
|
||||||
"github.com/minio/console/restapi/operations"
|
"github.com/minio/console/restapi/operations"
|
||||||
|
|
||||||
@@ -33,7 +31,7 @@ func registerServiceHandlers(api *operations.ConsoleAPI) {
|
|||||||
// Restart Service
|
// Restart Service
|
||||||
api.AdminAPIRestartServiceHandler = admin_api.RestartServiceHandlerFunc(func(params admin_api.RestartServiceParams, session *models.Principal) middleware.Responder {
|
api.AdminAPIRestartServiceHandler = admin_api.RestartServiceHandlerFunc(func(params admin_api.RestartServiceParams, session *models.Principal) middleware.Responder {
|
||||||
if err := getRestartServiceResponse(session); err != nil {
|
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()
|
return admin_api.NewRestartServiceNoContent()
|
||||||
})
|
})
|
||||||
@@ -61,20 +59,18 @@ func serviceRestart(ctx context.Context, client MinioAdmin) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// getRestartServiceResponse performs serviceRestart()
|
// getRestartServiceResponse performs serviceRestart()
|
||||||
func getRestartServiceResponse(session *models.Principal) error {
|
func getRestartServiceResponse(session *models.Principal) *models.Error {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
mAdmin, err := newMAdminClient(session)
|
mAdmin, err := newMAdminClient(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating Madmin Client:", err)
|
return prepareError(err)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
// create a MinIO Admin Client interface implementation
|
// create a MinIO Admin Client interface implementation
|
||||||
// defining the client to be used
|
// defining the client to be used
|
||||||
adminClient := adminClient{client: mAdmin}
|
adminClient := adminClient{client: mAdmin}
|
||||||
|
|
||||||
if err := serviceRestart(ctx, adminClient); err != nil {
|
if err := serviceRestart(ctx, adminClient); err != nil {
|
||||||
log.Println("error restarting service:", err)
|
return prepareError(err)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
516
restapi/admin_tenants_helper.go
Normal file
516
restapi/admin_tenants_helper.go
Normal file
@@ -0,0 +1,516 @@
|
|||||||
|
// This file is part of MinIO Kubernetes Cloud
|
||||||
|
// 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 (
|
||||||
|
"context"
|
||||||
|
"crypto"
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/hex"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"github.com/minio/console/cluster"
|
||||||
|
"github.com/minio/console/models"
|
||||||
|
"github.com/minio/console/pkg/kes"
|
||||||
|
"github.com/minio/console/restapi/operations/admin_api"
|
||||||
|
operator "github.com/minio/operator/pkg/apis/minio.min.io/v1"
|
||||||
|
"gopkg.in/yaml.v2"
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
// tenantUpdateCertificates receives the keyPair certificates (public and private keys) for Minio and Console and will try
|
||||||
|
// to replace the existing kubernetes secrets with the new values, then will restart the affected pods so the new volumes can be mounted
|
||||||
|
func tenantUpdateCertificates(ctx context.Context, operatorClient OperatorClientI, clientSet K8sClientI, namespace string, params admin_api.TenantUpdateCertificateParams) error {
|
||||||
|
tenantName := params.Tenant
|
||||||
|
tenant, err := operatorClient.TenantGet(ctx, namespace, tenantName, metav1.GetOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
secretName := fmt.Sprintf("%s-secret", tenantName)
|
||||||
|
body := params.Body
|
||||||
|
// check if MinIO is deployed with external certs and user provided new MinIO keypair
|
||||||
|
if tenant.ExternalCert() && body.Minio != nil {
|
||||||
|
minioCertSecretName := fmt.Sprintf("%s-instance-external-certificates", secretName)
|
||||||
|
// update certificates
|
||||||
|
if _, err := createOrReplaceExternalCertSecret(ctx, clientSet, namespace, body.Minio, minioCertSecretName, tenantName); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// restart MinIO pods
|
||||||
|
err := clientSet.deletePodCollection(ctx, namespace, metav1.DeleteOptions{}, metav1.ListOptions{
|
||||||
|
LabelSelector: fmt.Sprintf("%s=%s", operator.TenantLabel, tenantName),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// check if Console is deployed with external certs and user provided new Console keypair
|
||||||
|
if tenant.ConsoleExternalCert() && tenant.HasConsoleEnabled() && body.Console != nil {
|
||||||
|
consoleCertSecretName := fmt.Sprintf("%s-console-external-certificates", secretName)
|
||||||
|
// update certificates
|
||||||
|
if _, err := createOrReplaceExternalCertSecret(ctx, clientSet, namespace, body.Console, consoleCertSecretName, tenantName); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// restart Console pods
|
||||||
|
err := clientSet.deletePodCollection(ctx, namespace, metav1.DeleteOptions{}, metav1.ListOptions{
|
||||||
|
LabelSelector: fmt.Sprintf("%s=%s", operator.ConsoleTenantLabel, fmt.Sprintf("%s-console", tenantName)),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// getTenantUpdateCertificatesResponse wrapper of tenantUpdateCertificates
|
||||||
|
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 prepareError(err, errorUnableToUpdateTenantCertificates)
|
||||||
|
}
|
||||||
|
k8sClient := k8sClient{
|
||||||
|
client: clientSet,
|
||||||
|
}
|
||||||
|
opClientClientSet, err := cluster.OperatorClient(session.SessionToken)
|
||||||
|
if err != nil {
|
||||||
|
return prepareError(err, errorUnableToUpdateTenantCertificates)
|
||||||
|
}
|
||||||
|
opClient := operatorClient{
|
||||||
|
client: opClientClientSet,
|
||||||
|
}
|
||||||
|
if err := tenantUpdateCertificates(ctx, &opClient, &k8sClient, params.Namespace, params); err != nil {
|
||||||
|
return prepareError(err, errorUnableToUpdateTenantCertificates)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// tenantUpdateEncryption allow user to update KES server certificates, KES client certificates (used by MinIO for mTLS) and KES configuration (KMS configuration, credentials, etc)
|
||||||
|
func tenantUpdateEncryption(ctx context.Context, operatorClient OperatorClientI, clientSet K8sClientI, namespace string, params admin_api.TenantUpdateEncryptionParams) error {
|
||||||
|
tenantName := params.Tenant
|
||||||
|
secretName := fmt.Sprintf("%s-secret", tenantName)
|
||||||
|
tenant, err := operatorClient.TenantGet(ctx, namespace, tenantName, metav1.GetOptions{})
|
||||||
|
body := params.Body
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Check if encryption is enabled for MinIO via KES
|
||||||
|
if tenant.HasKESEnabled() {
|
||||||
|
// check if KES is deployed with external certificates and user provided new server keypair
|
||||||
|
if tenant.KESExternalCert() && body.Server != nil {
|
||||||
|
kesExternalCertSecretName := fmt.Sprintf("%s-kes-external-cert", secretName)
|
||||||
|
// update certificates
|
||||||
|
if _, err := createOrReplaceExternalCertSecret(ctx, clientSet, namespace, body.Server, kesExternalCertSecretName, tenantName); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// check if Tenant is deployed with external client certificates and user provided new client keypaiir
|
||||||
|
if tenant.ExternalClientCert() && body.Client != nil {
|
||||||
|
tenantExternalClientCertSecretName := fmt.Sprintf("%s-tenant-external-client-cert", secretName)
|
||||||
|
// Update certificates
|
||||||
|
if _, err := createOrReplaceExternalCertSecret(ctx, clientSet, namespace, body.Client, tenantExternalClientCertSecretName, tenantName); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Restart MinIO pods to mount the new client secrets
|
||||||
|
err := clientSet.deletePodCollection(ctx, namespace, metav1.DeleteOptions{}, metav1.ListOptions{
|
||||||
|
LabelSelector: fmt.Sprintf("%s=%s", operator.TenantLabel, tenantName),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// update KES identities in kes-configuration.yaml secret
|
||||||
|
kesConfigurationSecretName := fmt.Sprintf("%s-kes-configuration", secretName)
|
||||||
|
kesClientCertSecretName := fmt.Sprintf("%s-kes-client-cert", secretName)
|
||||||
|
_, _, err := createOrReplaceKesConfigurationSecrets(ctx, clientSet, namespace, body, kesConfigurationSecretName, kesClientCertSecretName, tenantName)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Restart KES pods to mount the new configuration
|
||||||
|
err = clientSet.deletePodCollection(ctx, namespace, metav1.DeleteOptions{}, metav1.ListOptions{
|
||||||
|
LabelSelector: fmt.Sprintf("%s=%s", operator.KESInstanceLabel, fmt.Sprintf("%s-kes", tenantName)),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// getTenantUpdateEncryptionResponse is a wrapper for tenantUpdateEncryption
|
||||||
|
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 prepareError(err, errorUpdatingEncryptionConfig)
|
||||||
|
}
|
||||||
|
k8sClient := k8sClient{
|
||||||
|
client: clientSet,
|
||||||
|
}
|
||||||
|
opClientClientSet, err := cluster.OperatorClient(session.SessionToken)
|
||||||
|
if err != nil {
|
||||||
|
return prepareError(err, errorUpdatingEncryptionConfig)
|
||||||
|
}
|
||||||
|
opClient := operatorClient{
|
||||||
|
client: opClientClientSet,
|
||||||
|
}
|
||||||
|
if err := tenantUpdateEncryption(ctx, &opClient, &k8sClient, params.Namespace, params); err != nil {
|
||||||
|
return prepareError(err, errorUpdatingEncryptionConfig)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// getKESConfiguration will generate the KES server certificate secrets, the tenant client secrets for mTLS authentication between MinIO and KES and the
|
||||||
|
// kes-configuration.yaml file used by the KES service (how to connect to the external KMS, eg: Vault, AWS, Gemalto, etc)
|
||||||
|
func getKESConfiguration(ctx context.Context, clientSet K8sClientI, ns string, encryptionCfg *models.EncryptionConfiguration, secretName, tenantName string, autoCert bool) (kesConfiguration *operator.KESConfig, err error) {
|
||||||
|
// Secrets used by the MiniO tenant service
|
||||||
|
//
|
||||||
|
// tenantExternalClientCertSecretName is the name of the secret that will store the certificates for mTLS between MinIO and the KES, eg: app.key and app.crt
|
||||||
|
tenantExternalClientCertSecretName := fmt.Sprintf("%s-tenant-external-client-cert", secretName)
|
||||||
|
// Secrets used by the KES service
|
||||||
|
//
|
||||||
|
// kesExternalCertSecretName is the name of the secret that will store the certificates for TLS in the KES server, eg: server.key and server.crt
|
||||||
|
kesExternalCertSecretName := fmt.Sprintf("%s-kes-external-cert", secretName)
|
||||||
|
// kesClientCertSecretName is the name of the secret that will store the certificates for mTLS between KES and the KMS, eg: mTLS with Vault or Gemalto KMS
|
||||||
|
kesClientCertSecretName := fmt.Sprintf("%s-kes-client-cert", secretName)
|
||||||
|
// kesConfigurationSecretName is the name of the secret that will store the configuration file, eg: kes-configuration.yaml
|
||||||
|
kesConfigurationSecretName := fmt.Sprintf("%s-kes-configuration", secretName)
|
||||||
|
// if there's an error during this process we delete all KES configuration secrets
|
||||||
|
defer func() {
|
||||||
|
if err != nil {
|
||||||
|
errDelete := clientSet.deleteSecret(ctx, ns, tenantExternalClientCertSecretName, metav1.DeleteOptions{})
|
||||||
|
if errDelete != nil {
|
||||||
|
log.Print(errDelete)
|
||||||
|
}
|
||||||
|
errDelete = clientSet.deleteSecret(ctx, ns, kesExternalCertSecretName, metav1.DeleteOptions{})
|
||||||
|
if errDelete != nil {
|
||||||
|
log.Print(errDelete)
|
||||||
|
}
|
||||||
|
errDelete = clientSet.deleteSecret(ctx, ns, kesClientCertSecretName, metav1.DeleteOptions{})
|
||||||
|
if errDelete != nil {
|
||||||
|
log.Print(errDelete)
|
||||||
|
}
|
||||||
|
errDelete = clientSet.deleteSecret(ctx, ns, kesConfigurationSecretName, metav1.DeleteOptions{})
|
||||||
|
if errDelete != nil {
|
||||||
|
log.Print(errDelete)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
kesConfiguration = &operator.KESConfig{
|
||||||
|
Image: "minio/kes:v0.11.0",
|
||||||
|
Replicas: 1,
|
||||||
|
Metadata: nil,
|
||||||
|
}
|
||||||
|
// Using custom image for KES
|
||||||
|
if encryptionCfg.Image != "" {
|
||||||
|
kesConfiguration.Image = encryptionCfg.Image
|
||||||
|
}
|
||||||
|
// Generate server certificates for KES only if autoCert is disabled
|
||||||
|
if !autoCert {
|
||||||
|
kesExternalCertSecret, err := createOrReplaceExternalCertSecret(ctx, clientSet, ns, encryptionCfg.Server, kesExternalCertSecretName, tenantName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// External TLS certificates used by KES
|
||||||
|
kesConfiguration.ExternalCertSecret = kesExternalCertSecret
|
||||||
|
}
|
||||||
|
// Prepare kesConfiguration for KES
|
||||||
|
serverConfigSecret, clientCertSecret, err := createOrReplaceKesConfigurationSecrets(ctx, clientSet, ns, encryptionCfg, kesConfigurationSecretName, kesClientCertSecretName, tenantName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// Configuration used by KES
|
||||||
|
kesConfiguration.Configuration = serverConfigSecret
|
||||||
|
kesConfiguration.ClientCertSecret = clientCertSecret
|
||||||
|
|
||||||
|
return kesConfiguration, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// createOrReplaceExternalCertSecret receives a keypair, public and private key, encoded in base64, decode it and generate a new kubernetes secret
|
||||||
|
// to be used by the operator for TLS encryption
|
||||||
|
func createOrReplaceExternalCertSecret(ctx context.Context, clientSet K8sClientI, ns string, keyPair *models.KeyPairConfiguration, secretName, tenantName string) (*operator.LocalCertificateReference, error) {
|
||||||
|
if keyPair == nil || keyPair.Crt == nil || keyPair.Key == nil || *keyPair.Crt == "" || *keyPair.Key == "" {
|
||||||
|
return nil, errors.New("certificate files must not be empty")
|
||||||
|
}
|
||||||
|
// delete secret with same name if exists
|
||||||
|
err := clientSet.deleteSecret(ctx, ns, secretName, metav1.DeleteOptions{})
|
||||||
|
if err != nil {
|
||||||
|
// log the error if any and continue
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
imm := true
|
||||||
|
tlsCrt, err := base64.StdEncoding.DecodeString(*keyPair.Crt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
tlsKey, err := base64.StdEncoding.DecodeString(*keyPair.Key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
externalTLSCertificateSecret := &corev1.Secret{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: secretName,
|
||||||
|
Labels: map[string]string{
|
||||||
|
operator.TenantLabel: tenantName,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Type: corev1.SecretTypeTLS,
|
||||||
|
Immutable: &imm,
|
||||||
|
Data: map[string][]byte{
|
||||||
|
"tls.crt": tlsCrt,
|
||||||
|
"tls.key": tlsKey,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
_, err = clientSet.createSecret(ctx, ns, externalTLSCertificateSecret, metav1.CreateOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// Certificates used by the minio instance
|
||||||
|
return &operator.LocalCertificateReference{
|
||||||
|
Name: secretName,
|
||||||
|
Type: "kubernetes.io/tls",
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func createOrReplaceKesConfigurationSecrets(ctx context.Context, clientSet K8sClientI, ns string, encryptionCfg *models.EncryptionConfiguration, kesConfigurationSecretName, kesClientCertSecretName, tenantName string) (*corev1.LocalObjectReference, *operator.LocalCertificateReference, error) {
|
||||||
|
// delete KES configuration secret if exists
|
||||||
|
if err := clientSet.deleteSecret(ctx, ns, kesConfigurationSecretName, metav1.DeleteOptions{}); err != nil {
|
||||||
|
// log the error if any and continue
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
// delete KES client cert secret if exists
|
||||||
|
if err := clientSet.deleteSecret(ctx, ns, kesClientCertSecretName, metav1.DeleteOptions{}); err != nil {
|
||||||
|
// log the error if any and continue
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
// if autoCert is enabled then Operator will generate the client certificates, calculate the client cert identity
|
||||||
|
// and pass it to KES via the $MINIO_KES_IDENTITY variable
|
||||||
|
clientCrtIdentity := "$MINIO_KES_IDENTITY"
|
||||||
|
// If a client certificate is provided proceed to calculate the identity
|
||||||
|
if encryptionCfg.Client != nil {
|
||||||
|
// Client certificate for KES used by Minio to mTLS
|
||||||
|
clientTLSCrt, err := base64.StdEncoding.DecodeString(*encryptionCfg.Client.Crt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
// Calculate the client cert identity based on the clientTLSCrt
|
||||||
|
h := crypto.SHA256.New()
|
||||||
|
certificate, err := kes.ParseCertificate(clientTLSCrt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
h.Write(certificate.RawSubjectPublicKeyInfo)
|
||||||
|
clientCrtIdentity = hex.EncodeToString(h.Sum(nil))
|
||||||
|
}
|
||||||
|
// Default kesConfiguration for KES
|
||||||
|
kesConfig := &kes.ServerConfig{
|
||||||
|
Addr: "0.0.0.0:7373",
|
||||||
|
Root: "disabled",
|
||||||
|
TLS: kes.TLS{
|
||||||
|
KeyPath: "/tmp/kes/server.key",
|
||||||
|
CertPath: "/tmp/kes/server.crt",
|
||||||
|
},
|
||||||
|
Policies: map[string]kes.Policy{
|
||||||
|
"default-policy": {
|
||||||
|
Paths: []string{
|
||||||
|
"/v1/key/create/my-minio-key",
|
||||||
|
"/v1/key/generate/my-minio-key",
|
||||||
|
"/v1/key/decrypt/my-minio-key",
|
||||||
|
},
|
||||||
|
Identities: []kes.Identity{
|
||||||
|
kes.Identity(clientCrtIdentity),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Cache: kes.Cache{
|
||||||
|
Expiry: &kes.Expiry{
|
||||||
|
Any: 5 * time.Minute,
|
||||||
|
Unused: 20 * time.Second,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Log: kes.Log{
|
||||||
|
Error: "on",
|
||||||
|
Audit: "off",
|
||||||
|
},
|
||||||
|
Keys: kes.Keys{},
|
||||||
|
}
|
||||||
|
// operator will mount the mTLSCertificates in the following paths
|
||||||
|
// therefore we set these values in the KES yaml kesConfiguration
|
||||||
|
var mTLSClientCrtPath = "/tmp/kes/client.crt"
|
||||||
|
var mTLSClientKeyPath = "/tmp/kes/client.key"
|
||||||
|
var mTLSClientCaPath = "/tmp/kes/ca.crt"
|
||||||
|
// map to hold mTLSCertificates for KES mTLS against Vault
|
||||||
|
mTLSCertificates := map[string][]byte{}
|
||||||
|
// if encryption is enabled and encryption is configured to use Vault
|
||||||
|
if encryptionCfg.Vault != nil {
|
||||||
|
// Initialize Vault Config
|
||||||
|
kesConfig.Keys.Vault = &kes.Vault{
|
||||||
|
Endpoint: *encryptionCfg.Vault.Endpoint,
|
||||||
|
EnginePath: encryptionCfg.Vault.Engine,
|
||||||
|
Namespace: encryptionCfg.Vault.Namespace,
|
||||||
|
Prefix: encryptionCfg.Vault.Prefix,
|
||||||
|
Status: &kes.VaultStatus{
|
||||||
|
Ping: 10 * time.Second,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
// Vault AppRole credentials
|
||||||
|
if encryptionCfg.Vault.Approle != nil {
|
||||||
|
kesConfig.Keys.Vault.AppRole = &kes.AppRole{
|
||||||
|
EnginePath: encryptionCfg.Vault.Approle.Engine,
|
||||||
|
ID: *encryptionCfg.Vault.Approle.ID,
|
||||||
|
Secret: *encryptionCfg.Vault.Approle.Secret,
|
||||||
|
Retry: 15 * time.Second,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return nil, nil, errors.New("approle credentials missing for kes")
|
||||||
|
}
|
||||||
|
// Vault mTLS kesConfiguration
|
||||||
|
if encryptionCfg.Vault.TLS != nil {
|
||||||
|
vaultTLSConfig := encryptionCfg.Vault.TLS
|
||||||
|
kesConfig.Keys.Vault.TLS = &kes.VaultTLS{}
|
||||||
|
if vaultTLSConfig.Crt != "" {
|
||||||
|
clientCrt, err := base64.StdEncoding.DecodeString(vaultTLSConfig.Crt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
mTLSCertificates["client.crt"] = clientCrt
|
||||||
|
kesConfig.Keys.Vault.TLS.CertPath = mTLSClientCrtPath
|
||||||
|
}
|
||||||
|
if vaultTLSConfig.Key != "" {
|
||||||
|
clientKey, err := base64.StdEncoding.DecodeString(vaultTLSConfig.Key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
mTLSCertificates["client.key"] = clientKey
|
||||||
|
kesConfig.Keys.Vault.TLS.KeyPath = mTLSClientKeyPath
|
||||||
|
}
|
||||||
|
if vaultTLSConfig.Ca != "" {
|
||||||
|
caCrt, err := base64.StdEncoding.DecodeString(vaultTLSConfig.Ca)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
mTLSCertificates["ca.crt"] = caCrt
|
||||||
|
kesConfig.Keys.Vault.TLS.CAPath = mTLSClientCaPath
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if encryptionCfg.Aws != nil {
|
||||||
|
// Initialize AWS
|
||||||
|
kesConfig.Keys.Aws = &kes.Aws{
|
||||||
|
SecretsManager: &kes.AwsSecretManager{},
|
||||||
|
}
|
||||||
|
// AWS basic kesConfiguration
|
||||||
|
if encryptionCfg.Aws.Secretsmanager != nil {
|
||||||
|
kesConfig.Keys.Aws.SecretsManager.Endpoint = *encryptionCfg.Aws.Secretsmanager.Endpoint
|
||||||
|
kesConfig.Keys.Aws.SecretsManager.Region = *encryptionCfg.Aws.Secretsmanager.Region
|
||||||
|
kesConfig.Keys.Aws.SecretsManager.KmsKey = encryptionCfg.Aws.Secretsmanager.Kmskey
|
||||||
|
// AWS credentials
|
||||||
|
if encryptionCfg.Aws.Secretsmanager.Credentials != nil {
|
||||||
|
kesConfig.Keys.Aws.SecretsManager.Login = &kes.AwsSecretManagerLogin{
|
||||||
|
AccessKey: *encryptionCfg.Aws.Secretsmanager.Credentials.Accesskey,
|
||||||
|
SecretKey: *encryptionCfg.Aws.Secretsmanager.Credentials.Secretkey,
|
||||||
|
SessionToken: encryptionCfg.Aws.Secretsmanager.Credentials.Token,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if encryptionCfg.Gemalto != nil {
|
||||||
|
// Initialize Gemalto
|
||||||
|
kesConfig.Keys.Gemalto = &kes.Gemalto{
|
||||||
|
KeySecure: &kes.GemaltoKeySecure{},
|
||||||
|
}
|
||||||
|
// Gemalto Configuration
|
||||||
|
if encryptionCfg.Gemalto.Keysecure != nil {
|
||||||
|
kesConfig.Keys.Gemalto.KeySecure.Endpoint = *encryptionCfg.Gemalto.Keysecure.Endpoint
|
||||||
|
// Gemalto TLS kesConfiguration
|
||||||
|
if encryptionCfg.Gemalto.Keysecure.TLS != nil {
|
||||||
|
if encryptionCfg.Gemalto.Keysecure.TLS.Ca != nil {
|
||||||
|
caCrt, err := base64.StdEncoding.DecodeString(*encryptionCfg.Gemalto.Keysecure.TLS.Ca)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
mTLSCertificates["ca.crt"] = caCrt
|
||||||
|
kesConfig.Keys.Gemalto.KeySecure.TLS = &kes.GemaltoTLS{
|
||||||
|
CAPath: mTLSClientCaPath,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Gemalto Login
|
||||||
|
if encryptionCfg.Gemalto.Keysecure.Credentials != nil {
|
||||||
|
kesConfig.Keys.Gemalto.KeySecure.Credentials = &kes.GemaltoCredentials{
|
||||||
|
Token: *encryptionCfg.Gemalto.Keysecure.Credentials.Token,
|
||||||
|
Domain: *encryptionCfg.Gemalto.Keysecure.Credentials.Domain,
|
||||||
|
Retry: 15 * time.Second,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
imm := true
|
||||||
|
// if mTLSCertificates contains elements we create the kubernetes secret
|
||||||
|
var clientCertSecretReference *operator.LocalCertificateReference
|
||||||
|
if len(mTLSCertificates) > 0 {
|
||||||
|
// Secret to store KES mTLS kesConfiguration to authenticate against a KMS
|
||||||
|
kesClientCertSecret := corev1.Secret{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: kesClientCertSecretName,
|
||||||
|
Labels: map[string]string{
|
||||||
|
operator.TenantLabel: tenantName,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Immutable: &imm,
|
||||||
|
Data: mTLSCertificates,
|
||||||
|
}
|
||||||
|
_, err := clientSet.createSecret(ctx, ns, &kesClientCertSecret, metav1.CreateOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
// kubernetes generic secret
|
||||||
|
clientCertSecretReference = &operator.LocalCertificateReference{
|
||||||
|
Name: kesClientCertSecretName,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Generate Yaml kesConfiguration for KES
|
||||||
|
serverConfigYaml, err := yaml.Marshal(kesConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
// Secret to store KES server kesConfiguration
|
||||||
|
kesConfigurationSecret := corev1.Secret{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: kesConfigurationSecretName,
|
||||||
|
Labels: map[string]string{
|
||||||
|
operator.TenantLabel: tenantName,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Immutable: &imm,
|
||||||
|
Data: map[string][]byte{
|
||||||
|
"server-config.yaml": serverConfigYaml,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
_, err = clientSet.createSecret(ctx, ns, &kesConfigurationSecret, metav1.CreateOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
return &corev1.LocalObjectReference{
|
||||||
|
Name: kesConfigurationSecretName,
|
||||||
|
}, clientCertSecretReference, nil
|
||||||
|
}
|
||||||
472
restapi/admin_tenants_helper_test.go
Normal file
472
restapi/admin_tenants_helper_test.go
Normal file
@@ -0,0 +1,472 @@
|
|||||||
|
// 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 (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/minio/console/models"
|
||||||
|
"github.com/minio/console/restapi/operations/admin_api"
|
||||||
|
operator "github.com/minio/operator/pkg/apis/minio.min.io/v1"
|
||||||
|
v1 "k8s.io/api/core/v1"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
var DeletePodCollectionMock func(ctx context.Context, namespace string, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error
|
||||||
|
var DeleteSecretMock func(ctx context.Context, namespace string, name string, opts metav1.DeleteOptions) error
|
||||||
|
var CreateSecretMock func(ctx context.Context, namespace string, secret *v1.Secret, opts metav1.CreateOptions) (*v1.Secret, error)
|
||||||
|
|
||||||
|
func (c k8sClientMock) deletePodCollection(ctx context.Context, namespace string, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error {
|
||||||
|
return DeletePodCollectionMock(ctx, namespace, opts, listOpts)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c k8sClientMock) deleteSecret(ctx context.Context, namespace string, name string, opts metav1.DeleteOptions) error {
|
||||||
|
return DeleteSecretMock(ctx, namespace, name, opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c k8sClientMock) createSecret(ctx context.Context, namespace string, secret *v1.Secret, opts metav1.CreateOptions) (*v1.Secret, error) {
|
||||||
|
return CreateSecretMock(ctx, namespace, secret, opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_tenantUpdateCertificates(t *testing.T) {
|
||||||
|
k8sClient := k8sClientMock{}
|
||||||
|
opClient := opClientMock{}
|
||||||
|
crt := "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUUzRENDQTBTZ0F3SUJBZ0lRS0pDalNyK0xaMnJrYVo5ODAvZnV5akFOQmdrcWhraUc5dzBCQVFzRkFEQ0IKdFRFZU1Cd0dBMVVFQ2hNVmJXdGpaWEowSUdSbGRtVnNiM0J0Wlc1MElFTkJNVVV3UXdZRFZRUUxERHhoYkdWMgpjMnRBVEdWdWFXNXpMVTFoWTBKdmIyc3RVSEp2TG14dlkyRnNJQ2hNWlc1cGJpQkJiR1YyYzJ0cElFaDFaWEowCllTQkJjbWxoY3lreFREQktCZ05WQkFNTVEyMXJZMlZ5ZENCaGJHVjJjMnRBVEdWdWFXNXpMVTFoWTBKdmIyc3QKVUhKdkxteHZZMkZzSUNoTVpXNXBiaUJCYkdWMmMydHBJRWgxWlhKMFlTQkJjbWxoY3lrd0hoY05NVGt3TmpBeApNREF3TURBd1doY05NekF3T0RBeU1ERTFNekEzV2pCaU1TY3dKUVlEVlFRS0V4NXRhMk5sY25RZ1pHVjJaV3h2CmNHMWxiblFnWTJWeWRHbG1hV05oZEdVeE56QTFCZ05WQkFzTUxtRnNaWFp6YTBCMGFXWmhMbXh2WTJGc0lDaE0KWlc1cGJpQkJiR1YyYzJ0cElFaDFaWEowWVNCQmNtbGhjeWt3Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQgpEd0F3Z2dFS0FvSUJBUUM2dlhLVyswWmhJQUNycmpxTU9QZ3VSdGpSemk1L0VxK2JvZTJkQ1BpT3djdXo0WFlhCm1rVlcxSkhBS3VTc0I1UHE0QnFSRXFueUhYT0ZROWQ1bEFjRGNDYmhlTFRVb2h2ZkhOWW9SdWRrYkZ3RzAyOFQKdVMxTFNtcHU5VjhFU2Q0Q3BiOGRvUkcvUW8vRTF4RGk5STFhNVhoeUdHTTNsUFlYQU1HU1ZkWUNNNzh0M2ZLTwp0NFVlcEt6d2dFQ2NKRVg4MVFoem1ZT25ELysyazNxSVppZU9nOGFkbDNFUWV2eFBISXlXQ1JkaDJZTkZsRi9rCmEwTzQyRVl2NVNUT1N0dzI2TzMwTVRrcEg0dzRRZm9VV3BnZU93MDZyYTluRHdzV3VhMUZIaHlKZmxOanR1USsKU0NlaDdqTVlVUThYV1JkbXVHbzFRT0g5cjdDKy82L1JhMlZIQWdNQkFBR2pnYmt3Z2JZd0RnWURWUjBQQVFILwpCQVFEQWdXZ01CTUdBMVVkSlFRTU1Bb0dDQ3NHQVFVRkJ3TUJNQXdHQTFVZEV3RUIvd1FDTUFBd0h3WURWUjBqCkJCZ3dGb0FVNHg4NUIyeGVlQzg0UEdvM1dZVWwxRGVvZlFNd1lBWURWUjBSQkZrd1Y0SWpLaTV0YVc1cGJ5MWgKYkdWMmMyc3Ribk11YzNaakxtTnNkWE4wWlhJdWJHOWpZV3lDTUNvdWFHOXVaWGwzWld4c0xXaHNMbTFwYm1sdgpMV0ZzWlhaemF5MXVjeTV6ZG1NdVkyeDFjM1JsY2k1c2IyTmhiREFOQmdrcWhraUc5dzBCQVFzRkFBT0NBWUVBCnZnMFlIVGtzd3Z4NEE5ZXl0b1V3eTBOSFVjQXpuNy9BVCt3WEt6d3Fqa0RiS3hVYlFTMFNQVVI4SkVDMkpuUUgKU3pTNGFCNXRURVRYZUcrbHJZVU02b0RNcXlIalpUN1NJaW83OUNxOFloWWxORU9qMkhvaXdxalczZm10UU9kVApoVG1tS01lRnZleHo2cnRxbHp0cVdKa3kvOGd1MkMrMWw5UDFFUmhFNDZZY0puVmJ5REFTSGNvV2tiZVhFUGErCjNpNFd4bU1yMDlNZXFTNkFUb2NKanFBeEtYcURYWmlFZjRUVEp1ZTRBQ2s4WmhqaEtUUEV6RnQ3WllVaHY3dVoKdlZCOXhla2FqRzdMRU5kSHZncXVMRUxUV3czWkpBaXpSTU5KUUpzZU11LzdQN1NIeXRKTVJYdlVwd2R2dWhDOApKNm54aGRmUS91QVlQY1lHdlU5NUZPZ1NjWVZqNW1WQktXM0ZHbkl2YzZuamQ1OFhBSTE3dlk0K0ZZTnY4M2UxCm9mOGlxRFdWNTFyT1FlbG9FZFdmdHkvZTI2bXVWUUQzQlVjY2Z5SWpGYy9SeGNHdm5maUEwUm1uRDNkWFcyZ0oKUHFTd01ZZ3hxQndqMm1Qck5jdkFWY3BOeWRjTWJKOTFIOHRWY0ttRHMrY1NiV0tnblpmKzUvZm5yaTdmU3FLUQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg=="
|
||||||
|
key := "LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2Z0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktnd2dnU2tBZ0VBQW9JQkFRQzZ2WEtXKzBaaElBQ3IKcmpxTU9QZ3VSdGpSemk1L0VxK2JvZTJkQ1BpT3djdXo0WFlhbWtWVzFKSEFLdVNzQjVQcTRCcVJFcW55SFhPRgpROWQ1bEFjRGNDYmhlTFRVb2h2ZkhOWW9SdWRrYkZ3RzAyOFR1UzFMU21wdTlWOEVTZDRDcGI4ZG9SRy9Rby9FCjF4RGk5STFhNVhoeUdHTTNsUFlYQU1HU1ZkWUNNNzh0M2ZLT3Q0VWVwS3p3Z0VDY0pFWDgxUWh6bVlPbkQvKzIKazNxSVppZU9nOGFkbDNFUWV2eFBISXlXQ1JkaDJZTkZsRi9rYTBPNDJFWXY1U1RPU3R3MjZPMzBNVGtwSDR3NApRZm9VV3BnZU93MDZyYTluRHdzV3VhMUZIaHlKZmxOanR1UStTQ2VoN2pNWVVROFhXUmRtdUdvMVFPSDlyN0MrCi82L1JhMlZIQWdNQkFBRUNnZ0VCQUlyTlVFUnJSM2ZmK3IraGhJRS93ekZhbGNUMUZWaDh3aXpUWXJQcnZCMFkKYlZvcVJzZ2xUVTdxTjkvM3dmc2dzdEROZk5IQ1pySEJOR0drK0orMDZMV2tnakhycjdXeFBUaE16ZDRvUGN4RwpRdTBMOGE5ZVlBMXJwY3NOOVc5Um5JU3BRSEk4aTkxM0V6Z0RoOWk2WCt0bFQyNjNNK0JYaDhlM1Z5cDNSTmhpCjZZUTQwcWJsNlQ0TUlyLzRSMGJmcFExZWVMNVNnbHB6Z1d6ZGs4WGtmc0E5YnRiU1RoMjZKRlBPUU1tMm5adkcKbjBlZm85TDZtaktwRW9rRWpTY1hWYTRZNHJaREZFYTVIbkpUSDBHblByQzU1cDhBb3BFN1c1M2RDT3lxd29CcQo4SWtZb2grcm1qTUZrOGc5VlRVYlcwVE9YVTFSY1E1Z0gxWS9jam5uVTRrQ2dZRUE4amw5ZEQyN2JaQ2ZaTW9jCjJYRThiYkJTaFVXTjRvaklKc1lHY2xyTjJDUEtUNmExaVhvS3BrTXdGNUdsODEzQURGR1pTbWtUSUFVQXRXQU8KNzZCcEpGUlVCZ1hmUXhSU0gyS1RaRldxbE5yekZPQjNsT3h2bFJ1amw5eE9ueStyWUhJWC9BOWNqQlp3a2orSAo3MDZRTExvS1ZFL2lMYy9DMlI5VzRLRVI3R3NDZ1lFQXhWd3FyM1JnUXhHUmpueG1zbDZtUW5DQ3k2MXFoUzUxCkJicDJzWldraFNTV0w0YzFDY0NDMnZ2ektPSmJkZ2NZQU43L05sTHgzWjlCZUFjTVZMUEVoc2NPalB6YUlneEMKczJ2UkdwQUFtYnRjWi9MVlpKaERWTjIrSHowRHhnRUtCa1JzQU5XTG51cGRoUWJBdlZuTkVsY29YVlo1cC9qcwp3U1BCelFoSklaVUNnWUJqTUlHY0dTOW9SWUhRRHlmVEx4aVV2bEI4ZktnR2JRYXhRZ1FmemVsZktnRE5yekhGCnN6RXJOblk2SUkxNVpCbWhzY1I1QVNBd3kzdW55a2N6ZjFldTVjMW1qZjhJQkFsQkN1ZmFmVzRWK0xiMEJKdFQKWTZLcHg2Q3RMaTBQNk1CZ0JUaW5JazgrbW0zTXBiRnZvSmRQaVh0elhTYjhwWWhmeXdLVGg4SEVNd0tCZ1FDUwpvR0VPTFpYKy9pUjRDYkI2d0pzaExWbmZYSjJSQ096a0xwNVVYV3IzaURFVWFvMWJDMjJzcUJjRnZ2WllmL2l6ClhQbWJNSkNGS1BhSTZDT2ZJbGZXRWptYlFaZ0dSN21lZDNISkhFZDE3NTg5azBvN0RHeXB0bnl6MUs3akFvNmkKRFY5NFZ5NytCLzBuQWRkY1ZrVm5aTjJXU3RMam1xcTY2NGZtZmt0bTZRS0JnQzBsMk5OVlFWK2N0OFFRRFpINQpBRFIrSGM3Qk0wNDhURGhNTmhoR3JHc2tWNngwMCtMZTdISGdpT3h2NXJudkNlTlY2M001YUZHdFVWbllTN1VoCkE1NndaNVlZeFFnQ0xzNi9PRmZhK3NiTngrSjdnSjRjNXdMZVlJMXVPMTlzZHBHa2VHZ25vK3dXVmxDSzFCbW0KRGM0TXA2STRiUTVtdy93YVpLQnpjRTJLCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K"
|
||||||
|
badCrt := "ASD"
|
||||||
|
badKey := "ASD"
|
||||||
|
type args struct {
|
||||||
|
ctx context.Context
|
||||||
|
opClient OperatorClientI
|
||||||
|
clientSet K8sClientI
|
||||||
|
namespace string
|
||||||
|
params admin_api.TenantUpdateCertificateParams
|
||||||
|
mockTenantGet func(ctx context.Context, namespace string, tenantName string, options metav1.GetOptions) (*operator.Tenant, error)
|
||||||
|
mockDeleteSecret func(ctx context.Context, namespace string, name string, opts metav1.DeleteOptions) error
|
||||||
|
mockCreateSecret func(ctx context.Context, namespace string, secret *v1.Secret, opts metav1.CreateOptions) (*v1.Secret, error)
|
||||||
|
mockDeletePodCollection func(ctx context.Context, namespace string, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "error getting tenant information",
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
opClient: opClient,
|
||||||
|
clientSet: k8sClient,
|
||||||
|
namespace: "",
|
||||||
|
params: admin_api.TenantUpdateCertificateParams{},
|
||||||
|
mockTenantGet: func(ctx context.Context, namespace string, tenantName string, options metav1.GetOptions) (*operator.Tenant, error) {
|
||||||
|
return nil, errors.New("invalid tenant")
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "error replacing external certs for tenant because of missing keypair",
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
opClient: opClient,
|
||||||
|
clientSet: k8sClient,
|
||||||
|
namespace: "",
|
||||||
|
params: admin_api.TenantUpdateCertificateParams{
|
||||||
|
Body: &models.TLSConfiguration{
|
||||||
|
Minio: &models.KeyPairConfiguration{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mockTenantGet: func(ctx context.Context, namespace string, tenantName string, options metav1.GetOptions) (*operator.Tenant, error) {
|
||||||
|
return &operator.Tenant{
|
||||||
|
Spec: operator.TenantSpec{
|
||||||
|
ExternalCertSecret: &operator.LocalCertificateReference{
|
||||||
|
Name: "secret",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "error replacing external certs for tenant because of malformed encoded certs",
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
opClient: opClient,
|
||||||
|
clientSet: k8sClient,
|
||||||
|
namespace: "",
|
||||||
|
params: admin_api.TenantUpdateCertificateParams{
|
||||||
|
Body: &models.TLSConfiguration{
|
||||||
|
Minio: &models.KeyPairConfiguration{
|
||||||
|
Crt: &badCrt,
|
||||||
|
Key: &badKey,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mockTenantGet: func(ctx context.Context, namespace string, tenantName string, options metav1.GetOptions) (*operator.Tenant, error) {
|
||||||
|
return &operator.Tenant{
|
||||||
|
Spec: operator.TenantSpec{
|
||||||
|
ExternalCertSecret: &operator.LocalCertificateReference{
|
||||||
|
Name: "secret",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
},
|
||||||
|
mockDeleteSecret: func(ctx context.Context, namespace string, name string, opts metav1.DeleteOptions) error {
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "error replacing external certs for tenant because of error during secret creation",
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
opClient: opClient,
|
||||||
|
clientSet: k8sClient,
|
||||||
|
namespace: "",
|
||||||
|
params: admin_api.TenantUpdateCertificateParams{
|
||||||
|
Body: &models.TLSConfiguration{
|
||||||
|
Minio: &models.KeyPairConfiguration{
|
||||||
|
Crt: &crt,
|
||||||
|
Key: &key,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mockTenantGet: func(ctx context.Context, namespace string, tenantName string, options metav1.GetOptions) (*operator.Tenant, error) {
|
||||||
|
return &operator.Tenant{
|
||||||
|
Spec: operator.TenantSpec{
|
||||||
|
ExternalCertSecret: &operator.LocalCertificateReference{
|
||||||
|
Name: "secret",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
},
|
||||||
|
mockDeleteSecret: func(ctx context.Context, namespace string, name string, opts metav1.DeleteOptions) error {
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
mockCreateSecret: func(ctx context.Context, namespace string, secret *v1.Secret, opts metav1.CreateOptions) (*v1.Secret, error) {
|
||||||
|
return nil, errors.New("error creating secret")
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "certificates replaced but error during deleting existing tenant pods",
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
opClient: opClient,
|
||||||
|
clientSet: k8sClient,
|
||||||
|
namespace: "",
|
||||||
|
params: admin_api.TenantUpdateCertificateParams{
|
||||||
|
Body: &models.TLSConfiguration{
|
||||||
|
Minio: &models.KeyPairConfiguration{
|
||||||
|
Crt: &crt,
|
||||||
|
Key: &key,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mockTenantGet: func(ctx context.Context, namespace string, tenantName string, options metav1.GetOptions) (*operator.Tenant, error) {
|
||||||
|
return &operator.Tenant{
|
||||||
|
Spec: operator.TenantSpec{
|
||||||
|
ExternalCertSecret: &operator.LocalCertificateReference{
|
||||||
|
Name: "secret",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
},
|
||||||
|
mockDeleteSecret: func(ctx context.Context, namespace string, name string, opts metav1.DeleteOptions) error {
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
mockCreateSecret: func(ctx context.Context, namespace string, secret *v1.Secret, opts metav1.CreateOptions) (*v1.Secret, error) {
|
||||||
|
return &v1.Secret{}, nil
|
||||||
|
},
|
||||||
|
mockDeletePodCollection: func(ctx context.Context, namespace string, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error {
|
||||||
|
return errors.New("error deleting minio pods")
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "error replacing external certs for console because of missing keypair",
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
opClient: opClient,
|
||||||
|
clientSet: k8sClient,
|
||||||
|
namespace: "",
|
||||||
|
params: admin_api.TenantUpdateCertificateParams{
|
||||||
|
Body: &models.TLSConfiguration{
|
||||||
|
Console: &models.KeyPairConfiguration{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mockTenantGet: func(ctx context.Context, namespace string, tenantName string, options metav1.GetOptions) (*operator.Tenant, error) {
|
||||||
|
return &operator.Tenant{
|
||||||
|
Spec: operator.TenantSpec{
|
||||||
|
Console: &operator.ConsoleConfiguration{
|
||||||
|
ExternalCertSecret: &operator.LocalCertificateReference{
|
||||||
|
Name: "secret",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "certificates replaced but error during deleting existing tenant pods",
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
opClient: opClient,
|
||||||
|
clientSet: k8sClient,
|
||||||
|
namespace: "",
|
||||||
|
params: admin_api.TenantUpdateCertificateParams{
|
||||||
|
Body: &models.TLSConfiguration{
|
||||||
|
Console: &models.KeyPairConfiguration{
|
||||||
|
Crt: &crt,
|
||||||
|
Key: &key,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mockTenantGet: func(ctx context.Context, namespace string, tenantName string, options metav1.GetOptions) (*operator.Tenant, error) {
|
||||||
|
return &operator.Tenant{
|
||||||
|
Spec: operator.TenantSpec{
|
||||||
|
Console: &operator.ConsoleConfiguration{
|
||||||
|
ExternalCertSecret: &operator.LocalCertificateReference{
|
||||||
|
Name: "secret",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
},
|
||||||
|
mockDeleteSecret: func(ctx context.Context, namespace string, name string, opts metav1.DeleteOptions) error {
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
mockCreateSecret: func(ctx context.Context, namespace string, secret *v1.Secret, opts metav1.CreateOptions) (*v1.Secret, error) {
|
||||||
|
return &v1.Secret{}, nil
|
||||||
|
},
|
||||||
|
mockDeletePodCollection: func(ctx context.Context, namespace string, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error {
|
||||||
|
return errors.New("error deleting console pods")
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
opClientTenantGetMock = tt.args.mockTenantGet
|
||||||
|
DeleteSecretMock = tt.args.mockDeleteSecret
|
||||||
|
CreateSecretMock = tt.args.mockCreateSecret
|
||||||
|
DeletePodCollectionMock = tt.args.mockDeletePodCollection
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if err := tenantUpdateCertificates(tt.args.ctx, tt.args.opClient, tt.args.clientSet, tt.args.namespace, tt.args.params); (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("tenantUpdateCertificates() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_tenantUpdateEncryption(t *testing.T) {
|
||||||
|
k8sClient := k8sClientMock{}
|
||||||
|
opClient := opClientMock{}
|
||||||
|
type args struct {
|
||||||
|
ctx context.Context
|
||||||
|
opClient OperatorClientI
|
||||||
|
clientSet K8sClientI
|
||||||
|
namespace string
|
||||||
|
params admin_api.TenantUpdateEncryptionParams
|
||||||
|
mockTenantGet func(ctx context.Context, namespace string, tenantName string, options metav1.GetOptions) (*operator.Tenant, error)
|
||||||
|
mockDeleteSecret func(ctx context.Context, namespace string, name string, opts metav1.DeleteOptions) error
|
||||||
|
mockCreateSecret func(ctx context.Context, namespace string, secret *v1.Secret, opts metav1.CreateOptions) (*v1.Secret, error)
|
||||||
|
mockDeletePodCollection func(ctx context.Context, namespace string, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "error updating encryption configuration because of error getting tenant",
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
opClient: opClient,
|
||||||
|
clientSet: k8sClient,
|
||||||
|
namespace: "",
|
||||||
|
params: admin_api.TenantUpdateEncryptionParams{},
|
||||||
|
mockTenantGet: func(ctx context.Context, namespace string, tenantName string, options metav1.GetOptions) (*operator.Tenant, error) {
|
||||||
|
return nil, errors.New("invalid tenant")
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
opClientTenantGetMock = tt.args.mockTenantGet
|
||||||
|
DeleteSecretMock = tt.args.mockDeleteSecret
|
||||||
|
CreateSecretMock = tt.args.mockCreateSecret
|
||||||
|
DeletePodCollectionMock = tt.args.mockDeletePodCollection
|
||||||
|
if err := tenantUpdateEncryption(tt.args.ctx, tt.args.opClient, tt.args.clientSet, tt.args.namespace, tt.args.params); (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("tenantUpdateEncryption() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_createOrReplaceKesConfigurationSecrets(t *testing.T) {
|
||||||
|
k8sClient := k8sClientMock{}
|
||||||
|
crt := "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUUzRENDQTBTZ0F3SUJBZ0lRS0pDalNyK0xaMnJrYVo5ODAvZnV5akFOQmdrcWhraUc5dzBCQVFzRkFEQ0IKdFRFZU1Cd0dBMVVFQ2hNVmJXdGpaWEowSUdSbGRtVnNiM0J0Wlc1MElFTkJNVVV3UXdZRFZRUUxERHhoYkdWMgpjMnRBVEdWdWFXNXpMVTFoWTBKdmIyc3RVSEp2TG14dlkyRnNJQ2hNWlc1cGJpQkJiR1YyYzJ0cElFaDFaWEowCllTQkJjbWxoY3lreFREQktCZ05WQkFNTVEyMXJZMlZ5ZENCaGJHVjJjMnRBVEdWdWFXNXpMVTFoWTBKdmIyc3QKVUhKdkxteHZZMkZzSUNoTVpXNXBiaUJCYkdWMmMydHBJRWgxWlhKMFlTQkJjbWxoY3lrd0hoY05NVGt3TmpBeApNREF3TURBd1doY05NekF3T0RBeU1ERTFNekEzV2pCaU1TY3dKUVlEVlFRS0V4NXRhMk5sY25RZ1pHVjJaV3h2CmNHMWxiblFnWTJWeWRHbG1hV05oZEdVeE56QTFCZ05WQkFzTUxtRnNaWFp6YTBCMGFXWmhMbXh2WTJGc0lDaE0KWlc1cGJpQkJiR1YyYzJ0cElFaDFaWEowWVNCQmNtbGhjeWt3Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQgpEd0F3Z2dFS0FvSUJBUUM2dlhLVyswWmhJQUNycmpxTU9QZ3VSdGpSemk1L0VxK2JvZTJkQ1BpT3djdXo0WFlhCm1rVlcxSkhBS3VTc0I1UHE0QnFSRXFueUhYT0ZROWQ1bEFjRGNDYmhlTFRVb2h2ZkhOWW9SdWRrYkZ3RzAyOFQKdVMxTFNtcHU5VjhFU2Q0Q3BiOGRvUkcvUW8vRTF4RGk5STFhNVhoeUdHTTNsUFlYQU1HU1ZkWUNNNzh0M2ZLTwp0NFVlcEt6d2dFQ2NKRVg4MVFoem1ZT25ELysyazNxSVppZU9nOGFkbDNFUWV2eFBISXlXQ1JkaDJZTkZsRi9rCmEwTzQyRVl2NVNUT1N0dzI2TzMwTVRrcEg0dzRRZm9VV3BnZU93MDZyYTluRHdzV3VhMUZIaHlKZmxOanR1USsKU0NlaDdqTVlVUThYV1JkbXVHbzFRT0g5cjdDKy82L1JhMlZIQWdNQkFBR2pnYmt3Z2JZd0RnWURWUjBQQVFILwpCQVFEQWdXZ01CTUdBMVVkSlFRTU1Bb0dDQ3NHQVFVRkJ3TUJNQXdHQTFVZEV3RUIvd1FDTUFBd0h3WURWUjBqCkJCZ3dGb0FVNHg4NUIyeGVlQzg0UEdvM1dZVWwxRGVvZlFNd1lBWURWUjBSQkZrd1Y0SWpLaTV0YVc1cGJ5MWgKYkdWMmMyc3Ribk11YzNaakxtTnNkWE4wWlhJdWJHOWpZV3lDTUNvdWFHOXVaWGwzWld4c0xXaHNMbTFwYm1sdgpMV0ZzWlhaemF5MXVjeTV6ZG1NdVkyeDFjM1JsY2k1c2IyTmhiREFOQmdrcWhraUc5dzBCQVFzRkFBT0NBWUVBCnZnMFlIVGtzd3Z4NEE5ZXl0b1V3eTBOSFVjQXpuNy9BVCt3WEt6d3Fqa0RiS3hVYlFTMFNQVVI4SkVDMkpuUUgKU3pTNGFCNXRURVRYZUcrbHJZVU02b0RNcXlIalpUN1NJaW83OUNxOFloWWxORU9qMkhvaXdxalczZm10UU9kVApoVG1tS01lRnZleHo2cnRxbHp0cVdKa3kvOGd1MkMrMWw5UDFFUmhFNDZZY0puVmJ5REFTSGNvV2tiZVhFUGErCjNpNFd4bU1yMDlNZXFTNkFUb2NKanFBeEtYcURYWmlFZjRUVEp1ZTRBQ2s4WmhqaEtUUEV6RnQ3WllVaHY3dVoKdlZCOXhla2FqRzdMRU5kSHZncXVMRUxUV3czWkpBaXpSTU5KUUpzZU11LzdQN1NIeXRKTVJYdlVwd2R2dWhDOApKNm54aGRmUS91QVlQY1lHdlU5NUZPZ1NjWVZqNW1WQktXM0ZHbkl2YzZuamQ1OFhBSTE3dlk0K0ZZTnY4M2UxCm9mOGlxRFdWNTFyT1FlbG9FZFdmdHkvZTI2bXVWUUQzQlVjY2Z5SWpGYy9SeGNHdm5maUEwUm1uRDNkWFcyZ0oKUHFTd01ZZ3hxQndqMm1Qck5jdkFWY3BOeWRjTWJKOTFIOHRWY0ttRHMrY1NiV0tnblpmKzUvZm5yaTdmU3FLUQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg=="
|
||||||
|
key := "LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2Z0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktnd2dnU2tBZ0VBQW9JQkFRQzZ2WEtXKzBaaElBQ3IKcmpxTU9QZ3VSdGpSemk1L0VxK2JvZTJkQ1BpT3djdXo0WFlhbWtWVzFKSEFLdVNzQjVQcTRCcVJFcW55SFhPRgpROWQ1bEFjRGNDYmhlTFRVb2h2ZkhOWW9SdWRrYkZ3RzAyOFR1UzFMU21wdTlWOEVTZDRDcGI4ZG9SRy9Rby9FCjF4RGk5STFhNVhoeUdHTTNsUFlYQU1HU1ZkWUNNNzh0M2ZLT3Q0VWVwS3p3Z0VDY0pFWDgxUWh6bVlPbkQvKzIKazNxSVppZU9nOGFkbDNFUWV2eFBISXlXQ1JkaDJZTkZsRi9rYTBPNDJFWXY1U1RPU3R3MjZPMzBNVGtwSDR3NApRZm9VV3BnZU93MDZyYTluRHdzV3VhMUZIaHlKZmxOanR1UStTQ2VoN2pNWVVROFhXUmRtdUdvMVFPSDlyN0MrCi82L1JhMlZIQWdNQkFBRUNnZ0VCQUlyTlVFUnJSM2ZmK3IraGhJRS93ekZhbGNUMUZWaDh3aXpUWXJQcnZCMFkKYlZvcVJzZ2xUVTdxTjkvM3dmc2dzdEROZk5IQ1pySEJOR0drK0orMDZMV2tnakhycjdXeFBUaE16ZDRvUGN4RwpRdTBMOGE5ZVlBMXJwY3NOOVc5Um5JU3BRSEk4aTkxM0V6Z0RoOWk2WCt0bFQyNjNNK0JYaDhlM1Z5cDNSTmhpCjZZUTQwcWJsNlQ0TUlyLzRSMGJmcFExZWVMNVNnbHB6Z1d6ZGs4WGtmc0E5YnRiU1RoMjZKRlBPUU1tMm5adkcKbjBlZm85TDZtaktwRW9rRWpTY1hWYTRZNHJaREZFYTVIbkpUSDBHblByQzU1cDhBb3BFN1c1M2RDT3lxd29CcQo4SWtZb2grcm1qTUZrOGc5VlRVYlcwVE9YVTFSY1E1Z0gxWS9jam5uVTRrQ2dZRUE4amw5ZEQyN2JaQ2ZaTW9jCjJYRThiYkJTaFVXTjRvaklKc1lHY2xyTjJDUEtUNmExaVhvS3BrTXdGNUdsODEzQURGR1pTbWtUSUFVQXRXQU8KNzZCcEpGUlVCZ1hmUXhSU0gyS1RaRldxbE5yekZPQjNsT3h2bFJ1amw5eE9ueStyWUhJWC9BOWNqQlp3a2orSAo3MDZRTExvS1ZFL2lMYy9DMlI5VzRLRVI3R3NDZ1lFQXhWd3FyM1JnUXhHUmpueG1zbDZtUW5DQ3k2MXFoUzUxCkJicDJzWldraFNTV0w0YzFDY0NDMnZ2ektPSmJkZ2NZQU43L05sTHgzWjlCZUFjTVZMUEVoc2NPalB6YUlneEMKczJ2UkdwQUFtYnRjWi9MVlpKaERWTjIrSHowRHhnRUtCa1JzQU5XTG51cGRoUWJBdlZuTkVsY29YVlo1cC9qcwp3U1BCelFoSklaVUNnWUJqTUlHY0dTOW9SWUhRRHlmVEx4aVV2bEI4ZktnR2JRYXhRZ1FmemVsZktnRE5yekhGCnN6RXJOblk2SUkxNVpCbWhzY1I1QVNBd3kzdW55a2N6ZjFldTVjMW1qZjhJQkFsQkN1ZmFmVzRWK0xiMEJKdFQKWTZLcHg2Q3RMaTBQNk1CZ0JUaW5JazgrbW0zTXBiRnZvSmRQaVh0elhTYjhwWWhmeXdLVGg4SEVNd0tCZ1FDUwpvR0VPTFpYKy9pUjRDYkI2d0pzaExWbmZYSjJSQ096a0xwNVVYV3IzaURFVWFvMWJDMjJzcUJjRnZ2WllmL2l6ClhQbWJNSkNGS1BhSTZDT2ZJbGZXRWptYlFaZ0dSN21lZDNISkhFZDE3NTg5azBvN0RHeXB0bnl6MUs3akFvNmkKRFY5NFZ5NytCLzBuQWRkY1ZrVm5aTjJXU3RMam1xcTY2NGZtZmt0bTZRS0JnQzBsMk5OVlFWK2N0OFFRRFpINQpBRFIrSGM3Qk0wNDhURGhNTmhoR3JHc2tWNngwMCtMZTdISGdpT3h2NXJudkNlTlY2M001YUZHdFVWbllTN1VoCkE1NndaNVlZeFFnQ0xzNi9PRmZhK3NiTngrSjdnSjRjNXdMZVlJMXVPMTlzZHBHa2VHZ25vK3dXVmxDSzFCbW0KRGM0TXA2STRiUTVtdy93YVpLQnpjRTJLCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K"
|
||||||
|
badCrt := "ASD"
|
||||||
|
badKey := "ASD"
|
||||||
|
appRole := "ASD"
|
||||||
|
appSecret := "ASD"
|
||||||
|
endpoint := "ASD"
|
||||||
|
type args struct {
|
||||||
|
ctx context.Context
|
||||||
|
clientSet K8sClientI
|
||||||
|
ns string
|
||||||
|
encryptionCfg *models.EncryptionConfiguration
|
||||||
|
kesConfigurationSecretName string
|
||||||
|
kesClientCertSecretName string
|
||||||
|
tenantName string
|
||||||
|
mockDeleteSecret func(ctx context.Context, namespace string, name string, opts metav1.DeleteOptions) error
|
||||||
|
mockCreateSecret func(ctx context.Context, namespace string, secret *v1.Secret, opts metav1.CreateOptions) (*v1.Secret, error)
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want *v1.LocalObjectReference
|
||||||
|
want1 *operator.LocalCertificateReference
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "error decoding the client certificate",
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
clientSet: k8sClient,
|
||||||
|
encryptionCfg: &models.EncryptionConfiguration{
|
||||||
|
Client: &models.KeyPairConfiguration{
|
||||||
|
Crt: &badCrt,
|
||||||
|
Key: &badKey,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ns: "default",
|
||||||
|
kesConfigurationSecretName: "test-secret",
|
||||||
|
kesClientCertSecretName: "test-client-secret",
|
||||||
|
tenantName: "test",
|
||||||
|
mockDeleteSecret: func(ctx context.Context, namespace string, name string, opts metav1.DeleteOptions) error {
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: nil,
|
||||||
|
want1: nil,
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "error because of malformed decoded certificate",
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
clientSet: k8sClient,
|
||||||
|
encryptionCfg: &models.EncryptionConfiguration{
|
||||||
|
Client: &models.KeyPairConfiguration{
|
||||||
|
Crt: &key, // will cause an error because we are passing a private key as the public key
|
||||||
|
Key: &key,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ns: "default",
|
||||||
|
kesConfigurationSecretName: "test-secret",
|
||||||
|
kesClientCertSecretName: "test-client-secret",
|
||||||
|
tenantName: "test",
|
||||||
|
mockDeleteSecret: func(ctx context.Context, namespace string, name string, opts metav1.DeleteOptions) error {
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: nil,
|
||||||
|
want1: nil,
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "error because of malformed decoded certificate",
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
clientSet: k8sClient,
|
||||||
|
encryptionCfg: &models.EncryptionConfiguration{
|
||||||
|
Client: &models.KeyPairConfiguration{
|
||||||
|
Crt: &crt,
|
||||||
|
Key: &key,
|
||||||
|
},
|
||||||
|
Vault: &models.VaultConfiguration{
|
||||||
|
Approle: &models.VaultConfigurationApprole{
|
||||||
|
Engine: "",
|
||||||
|
ID: &appRole,
|
||||||
|
Retry: 0,
|
||||||
|
Secret: &appSecret,
|
||||||
|
},
|
||||||
|
Endpoint: &endpoint,
|
||||||
|
Engine: "",
|
||||||
|
Namespace: "",
|
||||||
|
Prefix: "",
|
||||||
|
Status: nil,
|
||||||
|
TLS: &models.VaultConfigurationTLS{
|
||||||
|
Ca: crt,
|
||||||
|
Crt: crt,
|
||||||
|
Key: key,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ns: "default",
|
||||||
|
kesConfigurationSecretName: "test-secret",
|
||||||
|
kesClientCertSecretName: "test-client-secret",
|
||||||
|
tenantName: "test",
|
||||||
|
mockDeleteSecret: func(ctx context.Context, namespace string, name string, opts metav1.DeleteOptions) error {
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
mockCreateSecret: func(ctx context.Context, namespace string, secret *v1.Secret, opts metav1.CreateOptions) (*v1.Secret, error) {
|
||||||
|
return &v1.Secret{}, nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: &v1.LocalObjectReference{
|
||||||
|
Name: "test-secret",
|
||||||
|
},
|
||||||
|
want1: &operator.LocalCertificateReference{
|
||||||
|
Name: "test-client-secret",
|
||||||
|
},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
DeleteSecretMock = tt.args.mockDeleteSecret
|
||||||
|
CreateSecretMock = tt.args.mockCreateSecret
|
||||||
|
got, got1, err := createOrReplaceKesConfigurationSecrets(tt.args.ctx, tt.args.clientSet, tt.args.ns, tt.args.encryptionCfg, tt.args.kesConfigurationSecretName, tt.args.kesClientCertSecretName, tt.args.tenantName)
|
||||||
|
if (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("createOrReplaceKesConfigurationSecrets() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(got, tt.want) {
|
||||||
|
t.Errorf("createOrReplaceKesConfigurationSecrets() got = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(got1, tt.want1) {
|
||||||
|
t.Errorf("createOrReplaceKesConfigurationSecrets() got1 = %v, want %v", got1, tt.want1)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -88,7 +88,7 @@ func Test_TenantInfoTenantAdminClient(t *testing.T) {
|
|||||||
kClient := k8sClientMock{}
|
kClient := k8sClientMock{}
|
||||||
type args struct {
|
type args struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
client K8sClient
|
client K8sClientI
|
||||||
namespace string
|
namespace string
|
||||||
tenantName string
|
tenantName string
|
||||||
serviceName string
|
serviceName string
|
||||||
@@ -339,7 +339,7 @@ func Test_deleteTenantAction(t *testing.T) {
|
|||||||
opClient := opClientMock{}
|
opClient := opClientMock{}
|
||||||
type args struct {
|
type args struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
operatorClient OperatorClient
|
operatorClient OperatorClientI
|
||||||
nameSpace string
|
nameSpace string
|
||||||
tenantName string
|
tenantName string
|
||||||
deletePvcs bool
|
deletePvcs bool
|
||||||
@@ -532,7 +532,7 @@ func Test_TenantAddZone(t *testing.T) {
|
|||||||
|
|
||||||
type args struct {
|
type args struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
operatorClient OperatorClient
|
operatorClient OperatorClientI
|
||||||
nameSpace string
|
nameSpace string
|
||||||
mockTenantPatch func(ctx context.Context, namespace string, tenantName string, pt types.PatchType, data []byte, options metav1.PatchOptions) (*v1.Tenant, error)
|
mockTenantPatch func(ctx context.Context, namespace string, tenantName string, pt types.PatchType, data []byte, options metav1.PatchOptions) (*v1.Tenant, error)
|
||||||
mockTenantGet func(ctx context.Context, namespace string, tenantName string, options metav1.GetOptions) (*v1.Tenant, error)
|
mockTenantGet func(ctx context.Context, namespace string, tenantName string, options metav1.GetOptions) (*v1.Tenant, error)
|
||||||
@@ -706,7 +706,7 @@ func Test_UpdateTenantAction(t *testing.T) {
|
|||||||
|
|
||||||
type args struct {
|
type args struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
operatorClient OperatorClient
|
operatorClient OperatorClientI
|
||||||
httpCl cluster.HTTPClientI
|
httpCl cluster.HTTPClientI
|
||||||
nameSpace string
|
nameSpace string
|
||||||
tenantName string
|
tenantName string
|
||||||
@@ -871,7 +871,7 @@ func Test_UpdateTenantAction(t *testing.T) {
|
|||||||
},
|
},
|
||||||
params: admin_api.UpdateTenantParams{
|
params: admin_api.UpdateTenantParams{
|
||||||
Body: &models.UpdateTenantRequest{
|
Body: &models.UpdateTenantRequest{
|
||||||
ConsoleImage: "minio/console:v0.3.14",
|
ConsoleImage: "minio/console:v0.3.20",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ package restapi
|
|||||||
import (
|
import (
|
||||||
"github.com/go-openapi/errors"
|
"github.com/go-openapi/errors"
|
||||||
"github.com/go-openapi/runtime/middleware"
|
"github.com/go-openapi/runtime/middleware"
|
||||||
"github.com/go-openapi/swag"
|
|
||||||
"github.com/minio/console/models"
|
"github.com/minio/console/models"
|
||||||
"github.com/minio/console/restapi/operations"
|
"github.com/minio/console/restapi/operations"
|
||||||
"github.com/minio/console/restapi/operations/admin_api"
|
"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 {
|
api.AdminAPIListUsersHandler = admin_api.ListUsersHandlerFunc(func(params admin_api.ListUsersParams, session *models.Principal) middleware.Responder {
|
||||||
listUsersResponse, err := getListUsersResponse(session)
|
listUsersResponse, err := getListUsersResponse(session)
|
||||||
if err != nil {
|
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)
|
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 {
|
api.AdminAPIAddUserHandler = admin_api.AddUserHandlerFunc(func(params admin_api.AddUserParams, session *models.Principal) middleware.Responder {
|
||||||
userResponse, err := getUserAddResponse(session, params)
|
userResponse, err := getUserAddResponse(session, params)
|
||||||
if err != nil {
|
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)
|
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 {
|
api.AdminAPIRemoveUserHandler = admin_api.RemoveUserHandlerFunc(func(params admin_api.RemoveUserParams, session *models.Principal) middleware.Responder {
|
||||||
err := getRemoveUserResponse(session, params)
|
err := getRemoveUserResponse(session, params)
|
||||||
if err != nil {
|
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()
|
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 {
|
api.AdminAPIUpdateUserGroupsHandler = admin_api.UpdateUserGroupsHandlerFunc(func(params admin_api.UpdateUserGroupsParams, session *models.Principal) middleware.Responder {
|
||||||
userUpdateResponse, err := getUpdateUserGroupsResponse(session, params)
|
userUpdateResponse, err := getUpdateUserGroupsResponse(session, params)
|
||||||
if err != nil {
|
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)
|
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 {
|
api.AdminAPIGetUserInfoHandler = admin_api.GetUserInfoHandlerFunc(func(params admin_api.GetUserInfoParams, session *models.Principal) middleware.Responder {
|
||||||
userInfoResponse, err := getUserInfoResponse(session, params)
|
userInfoResponse, err := getUserInfoResponse(session, params)
|
||||||
if err != nil {
|
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)
|
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 {
|
api.AdminAPIUpdateUserInfoHandler = admin_api.UpdateUserInfoHandlerFunc(func(params admin_api.UpdateUserInfoParams, session *models.Principal) middleware.Responder {
|
||||||
userUpdateResponse, err := getUpdateUserResponse(session, params)
|
userUpdateResponse, err := getUpdateUserResponse(session, params)
|
||||||
if err != nil {
|
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)
|
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 {
|
api.AdminAPIBulkUpdateUsersGroupsHandler = admin_api.BulkUpdateUsersGroupsHandlerFunc(func(params admin_api.BulkUpdateUsersGroupsParams, session *models.Principal) middleware.Responder {
|
||||||
err := getAddUsersListToGroupsResponse(session, params)
|
err := getAddUsersListToGroupsResponse(session, params)
|
||||||
if err != nil {
|
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()
|
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
|
// 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()
|
ctx := context.Background()
|
||||||
mAdmin, err := newMAdminClient(session)
|
mAdmin, err := newMAdminClient(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating Madmin Client:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
// create a minioClient interface implementation
|
// create a minioClient interface implementation
|
||||||
// defining the client to be used
|
// defining the client to be used
|
||||||
@@ -132,8 +130,7 @@ func getListUsersResponse(session *models.Principal) (*models.ListUsersResponse,
|
|||||||
|
|
||||||
users, err := listUsers(ctx, adminClient)
|
users, err := listUsers(ctx, adminClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error listing users:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
// serialize output
|
// serialize output
|
||||||
listUsersResponse := &models.ListUsersResponse{
|
listUsersResponse := &models.ListUsersResponse{
|
||||||
@@ -167,12 +164,11 @@ func addUser(ctx context.Context, client MinioAdmin, accessKey, secretKey *strin
|
|||||||
return userRet, nil
|
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()
|
ctx := context.Background()
|
||||||
mAdmin, err := newMAdminClient(session)
|
mAdmin, err := newMAdminClient(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating Madmin Client:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
// create a minioClient interface implementation
|
// create a minioClient interface implementation
|
||||||
// defining the client to be used
|
// 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)
|
user, err := addUser(ctx, adminClient, params.Body.AccessKey, params.Body.SecretKey, params.Body.Groups)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error adding user:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
return user, nil
|
return user, nil
|
||||||
}
|
}
|
||||||
@@ -194,13 +189,12 @@ func removeUser(ctx context.Context, client MinioAdmin, accessKey string) error
|
|||||||
return nil
|
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()
|
ctx := context.Background()
|
||||||
|
|
||||||
mAdmin, err := newMAdminClient(session)
|
mAdmin, err := newMAdminClient(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating Madmin Client:", err)
|
return prepareError(err)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a minioClient interface implementation
|
// create a minioClient interface implementation
|
||||||
@@ -208,8 +202,7 @@ func getRemoveUserResponse(session *models.Principal, params admin_api.RemoveUse
|
|||||||
adminClient := adminClient{client: mAdmin}
|
adminClient := adminClient{client: mAdmin}
|
||||||
|
|
||||||
if err := removeUser(ctx, adminClient, params.Name); err != nil {
|
if err := removeUser(ctx, adminClient, params.Name); err != nil {
|
||||||
log.Println("error removing user:", err)
|
return prepareError(err)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Println("User removed successfully:", params.Name)
|
log.Println("User removed successfully:", params.Name)
|
||||||
@@ -226,13 +219,12 @@ func getUserInfo(ctx context.Context, client MinioAdmin, accessKey string) (*mad
|
|||||||
return &userInfo, nil
|
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()
|
ctx := context.Background()
|
||||||
|
|
||||||
mAdmin, err := newMAdminClient(session)
|
mAdmin, err := newMAdminClient(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating Madmin Client:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a minioClient interface implementation
|
// 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)
|
user, err := getUserInfo(ctx, adminClient, params.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error getting user:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
userInformation := &models.User{
|
userInformation := &models.User{
|
||||||
@@ -341,13 +332,12 @@ func updateUserGroups(ctx context.Context, client MinioAdmin, user string, group
|
|||||||
return userReturn, nil
|
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()
|
ctx := context.Background()
|
||||||
|
|
||||||
mAdmin, err := newMAdminClient(session)
|
mAdmin, err := newMAdminClient(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating Madmin Client:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a minioClient interface implementation
|
// 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)
|
user, err := updateUserGroups(ctx, adminClient, params.Name, params.Body.Groups)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error updating users's groups:", params.Body.Groups)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return user, nil
|
return user, nil
|
||||||
@@ -382,13 +371,12 @@ func setUserStatus(ctx context.Context, client MinioAdmin, user string, status s
|
|||||||
return nil
|
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()
|
ctx := context.Background()
|
||||||
|
|
||||||
mAdmin, err := newMAdminClient(session)
|
mAdmin, err := newMAdminClient(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating Madmin Client:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a minioClient interface implementation
|
// create a minioClient interface implementation
|
||||||
@@ -400,14 +388,13 @@ func getUpdateUserResponse(session *models.Principal, params admin_api.UpdateUse
|
|||||||
groups := params.Body.Groups
|
groups := params.Body.Groups
|
||||||
|
|
||||||
if err := setUserStatus(ctx, adminClient, name, status); err != nil {
|
if err := setUserStatus(ctx, adminClient, name, status); err != nil {
|
||||||
log.Println("error updating user status:", status)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
userElem, errUG := updateUserGroups(ctx, adminClient, name, groups)
|
userElem, errUG := updateUserGroups(ctx, adminClient, name, groups)
|
||||||
|
|
||||||
if errUG != nil {
|
if errUG != nil {
|
||||||
return nil, errUG
|
return nil, prepareError(errUG)
|
||||||
}
|
}
|
||||||
return userElem, nil
|
return userElem, nil
|
||||||
}
|
}
|
||||||
@@ -455,13 +442,12 @@ func addUsersListToGroups(ctx context.Context, client MinioAdmin, usersToUpdate
|
|||||||
return nil
|
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()
|
ctx := context.Background()
|
||||||
|
|
||||||
mAdmin, err := newMAdminClient(session)
|
mAdmin, err := newMAdminClient(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating Madmin Client:", err)
|
return prepareError(err)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a minioClient interface implementation
|
// create a minioClient interface implementation
|
||||||
@@ -472,8 +458,7 @@ func getAddUsersListToGroupsResponse(session *models.Principal, params admin_api
|
|||||||
groupsList := params.Body.Groups
|
groupsList := params.Body.Groups
|
||||||
|
|
||||||
if err := addUsersListToGroups(ctx, adminClient, usersList, groupsList); err != nil {
|
if err := addUsersListToGroups(ctx, adminClient, usersList, groupsList); err != nil {
|
||||||
log.Println("error updating groups bulk users:", err.Error())
|
return prepareError(err)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -112,6 +112,8 @@ func configureAPI(api *operations.ConsoleAPI) http.Handler {
|
|||||||
registerTenantHandlers(api)
|
registerTenantHandlers(api)
|
||||||
// Register ResourceQuota handlers
|
// Register ResourceQuota handlers
|
||||||
registerResourceQuotaHandlers(api)
|
registerResourceQuotaHandlers(api)
|
||||||
|
// Register Nodes' handlers
|
||||||
|
registerNodesHandlers(api)
|
||||||
|
|
||||||
api.PreServerShutdown = func() {}
|
api.PreServerShutdown = func() {}
|
||||||
|
|
||||||
|
|||||||
@@ -437,6 +437,39 @@ func init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/cluster/max-allocatable-memory": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"AdminAPI"
|
||||||
|
],
|
||||||
|
"summary": "Get maximum allocatable memory for given number of nodes",
|
||||||
|
"operationId": "GetMaxAllocatableMem",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"minimum": 1,
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int32",
|
||||||
|
"name": "num_nodes",
|
||||||
|
"in": "query",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A successful response.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/maxAllocatableMemResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"description": "Generic error response.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/configs": {
|
"/configs": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": [
|
||||||
@@ -1043,6 +1076,90 @@ func init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/namespaces/{namespace}/tenants/{tenant}/certificates": {
|
||||||
|
"put": {
|
||||||
|
"tags": [
|
||||||
|
"AdminAPI"
|
||||||
|
],
|
||||||
|
"summary": "Tenant Update Certificates",
|
||||||
|
"operationId": "TenantUpdateCertificate",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"name": "namespace",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"name": "tenant",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "body",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/tlsConfiguration"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"201": {
|
||||||
|
"description": "A successful response."
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"description": "Generic error response.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/namespaces/{namespace}/tenants/{tenant}/encryption": {
|
||||||
|
"put": {
|
||||||
|
"tags": [
|
||||||
|
"AdminAPI"
|
||||||
|
],
|
||||||
|
"summary": "Tenant Update Encryption",
|
||||||
|
"operationId": "TenantUpdateEncryption",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"name": "namespace",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"name": "tenant",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "body",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/encryptionConfiguration"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"201": {
|
||||||
|
"description": "A successful response."
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"description": "Generic error response.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/namespaces/{namespace}/tenants/{tenant}/usage": {
|
"/namespaces/{namespace}/tenants/{tenant}/usage": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": [
|
||||||
@@ -1081,6 +1198,49 @@ func init() {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/namespaces/{namespace}/tenants/{tenant}/zones": {
|
"/namespaces/{namespace}/tenants/{tenant}/zones": {
|
||||||
|
"put": {
|
||||||
|
"tags": [
|
||||||
|
"AdminAPI"
|
||||||
|
],
|
||||||
|
"summary": "Tenant Update Zones",
|
||||||
|
"operationId": "TenantUpdateZones",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"name": "namespace",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"name": "tenant",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "body",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/zoneUpdateRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A successful response.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/tenant"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"description": "Generic error response.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"post": {
|
"post": {
|
||||||
"tags": [
|
"tags": [
|
||||||
"AdminAPI"
|
"AdminAPI"
|
||||||
@@ -2038,6 +2198,10 @@ func init() {
|
|||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": true
|
"default": true
|
||||||
},
|
},
|
||||||
|
"enable_prometheus": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false
|
||||||
|
},
|
||||||
"enable_tls": {
|
"enable_tls": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": true
|
"default": true
|
||||||
@@ -2156,7 +2320,7 @@ func init() {
|
|||||||
"properties": {
|
"properties": {
|
||||||
"code": {
|
"code": {
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"format": "int64"
|
"format": "int32"
|
||||||
},
|
},
|
||||||
"message": {
|
"message": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
@@ -2513,6 +2677,15 @@ func init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"maxAllocatableMemResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"max_memory": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"nodeSelectorTerm": {
|
"nodeSelectorTerm": {
|
||||||
"description": "A null or empty node selector term matches no objects. The requirements of them are ANDed. The TopologySelectorTerm type implements a subset of the NodeSelectorTerm.",
|
"description": "A null or empty node selector term matches no objects. The requirements of them are ANDed. The TopologySelectorTerm type implements a subset of the NodeSelectorTerm.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
@@ -3250,6 +3423,12 @@ func init() {
|
|||||||
"size"
|
"size"
|
||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"labels": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
"size": {
|
"size": {
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
@@ -3449,6 +3628,20 @@ func init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"zoneUpdateRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"zones"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"zones": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/zone"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"securityDefinitions": {
|
"securityDefinitions": {
|
||||||
@@ -3868,6 +4061,39 @@ func init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/cluster/max-allocatable-memory": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"AdminAPI"
|
||||||
|
],
|
||||||
|
"summary": "Get maximum allocatable memory for given number of nodes",
|
||||||
|
"operationId": "GetMaxAllocatableMem",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"minimum": 1,
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int32",
|
||||||
|
"name": "num_nodes",
|
||||||
|
"in": "query",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A successful response.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/maxAllocatableMemResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"description": "Generic error response.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/configs": {
|
"/configs": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": [
|
||||||
@@ -4474,6 +4700,90 @@ func init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/namespaces/{namespace}/tenants/{tenant}/certificates": {
|
||||||
|
"put": {
|
||||||
|
"tags": [
|
||||||
|
"AdminAPI"
|
||||||
|
],
|
||||||
|
"summary": "Tenant Update Certificates",
|
||||||
|
"operationId": "TenantUpdateCertificate",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"name": "namespace",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"name": "tenant",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "body",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/tlsConfiguration"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"201": {
|
||||||
|
"description": "A successful response."
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"description": "Generic error response.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/namespaces/{namespace}/tenants/{tenant}/encryption": {
|
||||||
|
"put": {
|
||||||
|
"tags": [
|
||||||
|
"AdminAPI"
|
||||||
|
],
|
||||||
|
"summary": "Tenant Update Encryption",
|
||||||
|
"operationId": "TenantUpdateEncryption",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"name": "namespace",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"name": "tenant",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "body",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/encryptionConfiguration"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"201": {
|
||||||
|
"description": "A successful response."
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"description": "Generic error response.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/namespaces/{namespace}/tenants/{tenant}/usage": {
|
"/namespaces/{namespace}/tenants/{tenant}/usage": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": [
|
||||||
@@ -4512,6 +4822,49 @@ func init() {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/namespaces/{namespace}/tenants/{tenant}/zones": {
|
"/namespaces/{namespace}/tenants/{tenant}/zones": {
|
||||||
|
"put": {
|
||||||
|
"tags": [
|
||||||
|
"AdminAPI"
|
||||||
|
],
|
||||||
|
"summary": "Tenant Update Zones",
|
||||||
|
"operationId": "TenantUpdateZones",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"name": "namespace",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"name": "tenant",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "body",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/zoneUpdateRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A successful response.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/tenant"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"description": "Generic error response.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"post": {
|
"post": {
|
||||||
"tags": [
|
"tags": [
|
||||||
"AdminAPI"
|
"AdminAPI"
|
||||||
@@ -5721,6 +6074,12 @@ func init() {
|
|||||||
"size"
|
"size"
|
||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"labels": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
"size": {
|
"size": {
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
@@ -5980,6 +6339,10 @@ func init() {
|
|||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": true
|
"default": true
|
||||||
},
|
},
|
||||||
|
"enable_prometheus": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false
|
||||||
|
},
|
||||||
"enable_tls": {
|
"enable_tls": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": true
|
"default": true
|
||||||
@@ -6098,7 +6461,7 @@ func init() {
|
|||||||
"properties": {
|
"properties": {
|
||||||
"code": {
|
"code": {
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"format": "int64"
|
"format": "int32"
|
||||||
},
|
},
|
||||||
"message": {
|
"message": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
@@ -6455,6 +6818,15 @@ func init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"maxAllocatableMemResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"max_memory": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"nodeSelectorTerm": {
|
"nodeSelectorTerm": {
|
||||||
"description": "A null or empty node selector term matches no objects. The requirements of them are ANDed. The TopologySelectorTerm type implements a subset of the NodeSelectorTerm.",
|
"description": "A null or empty node selector term matches no objects. The requirements of them are ANDed. The TopologySelectorTerm type implements a subset of the NodeSelectorTerm.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
@@ -7126,6 +7498,12 @@ func init() {
|
|||||||
"size"
|
"size"
|
||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"labels": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
"size": {
|
"size": {
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
@@ -7256,6 +7634,20 @@ func init() {
|
|||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/definitions/ZoneTolerationsItems0"
|
"$ref": "#/definitions/ZoneTolerationsItems0"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"zoneUpdateRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"zones"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"zones": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/zone"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"securityDefinitions": {
|
"securityDefinitions": {
|
||||||
|
|||||||
100
restapi/error.go
Normal file
100
restapi/error.go
Normal 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 {
|
||||||
|
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 {
|
||||||
|
log.Print("debugging error: ", err[2].Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &models.Error{Code: errorCode, Message: swag.String(errorMessage)}
|
||||||
|
}
|
||||||
@@ -24,13 +24,16 @@ import (
|
|||||||
"k8s.io/client-go/kubernetes"
|
"k8s.io/client-go/kubernetes"
|
||||||
)
|
)
|
||||||
|
|
||||||
// K8sClient interface with all functions to be implemented
|
// K8sClientI interface with all functions to be implemented
|
||||||
// by mock when testing, it should include all K8sClient respective api calls
|
// by mock when testing, it should include all K8sClientI respective api calls
|
||||||
// that are used within this project.
|
// that are used within this project.
|
||||||
type K8sClient interface {
|
type K8sClientI interface {
|
||||||
getResourceQuota(ctx context.Context, namespace, resource string, opts metav1.GetOptions) (*v1.ResourceQuota, error)
|
getResourceQuota(ctx context.Context, namespace, resource string, opts metav1.GetOptions) (*v1.ResourceQuota, error)
|
||||||
getSecret(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*v1.Secret, error)
|
getSecret(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*v1.Secret, error)
|
||||||
getService(ctx context.Context, namespace, serviceName string, opts metav1.GetOptions) (*v1.Service, error)
|
getService(ctx context.Context, namespace, serviceName string, opts metav1.GetOptions) (*v1.Service, error)
|
||||||
|
deletePodCollection(ctx context.Context, namespace string, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error
|
||||||
|
deleteSecret(ctx context.Context, namespace string, name string, opts metav1.DeleteOptions) error
|
||||||
|
createSecret(ctx context.Context, namespace string, secret *v1.Secret, opts metav1.CreateOptions) (*v1.Secret, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interface implementation
|
// Interface implementation
|
||||||
@@ -51,3 +54,15 @@ func (c *k8sClient) getSecret(ctx context.Context, namespace, secretName string,
|
|||||||
func (c *k8sClient) getService(ctx context.Context, namespace, serviceName string, opts metav1.GetOptions) (*v1.Service, error) {
|
func (c *k8sClient) getService(ctx context.Context, namespace, serviceName string, opts metav1.GetOptions) (*v1.Service, error) {
|
||||||
return c.client.CoreV1().Services(namespace).Get(ctx, serviceName, opts)
|
return c.client.CoreV1().Services(namespace).Get(ctx, serviceName, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *k8sClient) deletePodCollection(ctx context.Context, namespace string, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error {
|
||||||
|
return c.client.CoreV1().Pods(namespace).DeleteCollection(ctx, opts, listOpts)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *k8sClient) deleteSecret(ctx context.Context, namespace string, name string, opts metav1.DeleteOptions) error {
|
||||||
|
return c.client.CoreV1().Secrets(namespace).Delete(ctx, name, opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *k8sClient) createSecret(ctx context.Context, namespace string, secret *v1.Secret, opts metav1.CreateOptions) (*v1.Secret, error) {
|
||||||
|
return c.client.CoreV1().Secrets(namespace).Create(ctx, secret, opts)
|
||||||
|
}
|
||||||
|
|||||||
90
restapi/operations/admin_api/get_max_allocatable_mem.go
Normal file
90
restapi/operations/admin_api/get_max_allocatable_mem.go
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
// 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 admin_api
|
||||||
|
|
||||||
|
// This file was generated by the swagger tool.
|
||||||
|
// Editing this file might prove futile when you re-run the generate command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/go-openapi/runtime/middleware"
|
||||||
|
|
||||||
|
"github.com/minio/console/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetMaxAllocatableMemHandlerFunc turns a function with the right signature into a get max allocatable mem handler
|
||||||
|
type GetMaxAllocatableMemHandlerFunc func(GetMaxAllocatableMemParams, *models.Principal) middleware.Responder
|
||||||
|
|
||||||
|
// Handle executing the request and returning a response
|
||||||
|
func (fn GetMaxAllocatableMemHandlerFunc) Handle(params GetMaxAllocatableMemParams, principal *models.Principal) middleware.Responder {
|
||||||
|
return fn(params, principal)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMaxAllocatableMemHandler interface for that can handle valid get max allocatable mem params
|
||||||
|
type GetMaxAllocatableMemHandler interface {
|
||||||
|
Handle(GetMaxAllocatableMemParams, *models.Principal) middleware.Responder
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewGetMaxAllocatableMem creates a new http.Handler for the get max allocatable mem operation
|
||||||
|
func NewGetMaxAllocatableMem(ctx *middleware.Context, handler GetMaxAllocatableMemHandler) *GetMaxAllocatableMem {
|
||||||
|
return &GetMaxAllocatableMem{Context: ctx, Handler: handler}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*GetMaxAllocatableMem swagger:route GET /cluster/max-allocatable-memory AdminAPI getMaxAllocatableMem
|
||||||
|
|
||||||
|
Get maximum allocatable memory for given number of nodes
|
||||||
|
|
||||||
|
*/
|
||||||
|
type GetMaxAllocatableMem struct {
|
||||||
|
Context *middleware.Context
|
||||||
|
Handler GetMaxAllocatableMemHandler
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *GetMaxAllocatableMem) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
||||||
|
route, rCtx, _ := o.Context.RouteInfo(r)
|
||||||
|
if rCtx != nil {
|
||||||
|
r = rCtx
|
||||||
|
}
|
||||||
|
var Params = NewGetMaxAllocatableMemParams()
|
||||||
|
|
||||||
|
uprinc, aCtx, err := o.Context.Authorize(r, route)
|
||||||
|
if err != nil {
|
||||||
|
o.Context.Respond(rw, r, route.Produces, route, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if aCtx != nil {
|
||||||
|
r = aCtx
|
||||||
|
}
|
||||||
|
var principal *models.Principal
|
||||||
|
if uprinc != nil {
|
||||||
|
principal = uprinc.(*models.Principal) // this is really a models.Principal, I promise
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params
|
||||||
|
o.Context.Respond(rw, r, route.Produces, route, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
res := o.Handler.Handle(Params, principal) // actually handle the request
|
||||||
|
|
||||||
|
o.Context.Respond(rw, r, route.Produces, route, res)
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,119 @@
|
|||||||
|
// 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 admin_api
|
||||||
|
|
||||||
|
// This file was generated by the swagger tool.
|
||||||
|
// Editing this file might prove futile when you re-run the swagger generate command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/go-openapi/errors"
|
||||||
|
"github.com/go-openapi/runtime"
|
||||||
|
"github.com/go-openapi/runtime/middleware"
|
||||||
|
"github.com/go-openapi/strfmt"
|
||||||
|
"github.com/go-openapi/swag"
|
||||||
|
"github.com/go-openapi/validate"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewGetMaxAllocatableMemParams creates a new GetMaxAllocatableMemParams object
|
||||||
|
// no default values defined in spec.
|
||||||
|
func NewGetMaxAllocatableMemParams() GetMaxAllocatableMemParams {
|
||||||
|
|
||||||
|
return GetMaxAllocatableMemParams{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMaxAllocatableMemParams contains all the bound params for the get max allocatable mem operation
|
||||||
|
// typically these are obtained from a http.Request
|
||||||
|
//
|
||||||
|
// swagger:parameters GetMaxAllocatableMem
|
||||||
|
type GetMaxAllocatableMemParams struct {
|
||||||
|
|
||||||
|
// HTTP Request Object
|
||||||
|
HTTPRequest *http.Request `json:"-"`
|
||||||
|
|
||||||
|
/*
|
||||||
|
Required: true
|
||||||
|
Minimum: 1
|
||||||
|
In: query
|
||||||
|
*/
|
||||||
|
NumNodes int32
|
||||||
|
}
|
||||||
|
|
||||||
|
// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface
|
||||||
|
// for simple values it will use straight method calls.
|
||||||
|
//
|
||||||
|
// To ensure default values, the struct must have been initialized with NewGetMaxAllocatableMemParams() beforehand.
|
||||||
|
func (o *GetMaxAllocatableMemParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error {
|
||||||
|
var res []error
|
||||||
|
|
||||||
|
o.HTTPRequest = r
|
||||||
|
|
||||||
|
qs := runtime.Values(r.URL.Query())
|
||||||
|
|
||||||
|
qNumNodes, qhkNumNodes, _ := qs.GetOK("num_nodes")
|
||||||
|
if err := o.bindNumNodes(qNumNodes, qhkNumNodes, route.Formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(res) > 0 {
|
||||||
|
return errors.CompositeValidationError(res...)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// bindNumNodes binds and validates parameter NumNodes from query.
|
||||||
|
func (o *GetMaxAllocatableMemParams) bindNumNodes(rawData []string, hasKey bool, formats strfmt.Registry) error {
|
||||||
|
if !hasKey {
|
||||||
|
return errors.Required("num_nodes", "query", rawData)
|
||||||
|
}
|
||||||
|
var raw string
|
||||||
|
if len(rawData) > 0 {
|
||||||
|
raw = rawData[len(rawData)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Required: true
|
||||||
|
// AllowEmptyValue: false
|
||||||
|
if err := validate.RequiredString("num_nodes", "query", raw); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
value, err := swag.ConvertInt32(raw)
|
||||||
|
if err != nil {
|
||||||
|
return errors.InvalidType("num_nodes", "query", "int32", raw)
|
||||||
|
}
|
||||||
|
o.NumNodes = value
|
||||||
|
|
||||||
|
if err := o.validateNumNodes(formats); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// validateNumNodes carries on validations for parameter NumNodes
|
||||||
|
func (o *GetMaxAllocatableMemParams) validateNumNodes(formats strfmt.Registry) error {
|
||||||
|
|
||||||
|
if err := validate.MinimumInt("num_nodes", "query", int64(o.NumNodes), 1, false); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,133 @@
|
|||||||
|
// 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 admin_api
|
||||||
|
|
||||||
|
// This file was generated by the swagger tool.
|
||||||
|
// Editing this file might prove futile when you re-run the swagger generate command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/go-openapi/runtime"
|
||||||
|
|
||||||
|
"github.com/minio/console/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetMaxAllocatableMemOKCode is the HTTP code returned for type GetMaxAllocatableMemOK
|
||||||
|
const GetMaxAllocatableMemOKCode int = 200
|
||||||
|
|
||||||
|
/*GetMaxAllocatableMemOK A successful response.
|
||||||
|
|
||||||
|
swagger:response getMaxAllocatableMemOK
|
||||||
|
*/
|
||||||
|
type GetMaxAllocatableMemOK struct {
|
||||||
|
|
||||||
|
/*
|
||||||
|
In: Body
|
||||||
|
*/
|
||||||
|
Payload *models.MaxAllocatableMemResponse `json:"body,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewGetMaxAllocatableMemOK creates GetMaxAllocatableMemOK with default headers values
|
||||||
|
func NewGetMaxAllocatableMemOK() *GetMaxAllocatableMemOK {
|
||||||
|
|
||||||
|
return &GetMaxAllocatableMemOK{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithPayload adds the payload to the get max allocatable mem o k response
|
||||||
|
func (o *GetMaxAllocatableMemOK) WithPayload(payload *models.MaxAllocatableMemResponse) *GetMaxAllocatableMemOK {
|
||||||
|
o.Payload = payload
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPayload sets the payload to the get max allocatable mem o k response
|
||||||
|
func (o *GetMaxAllocatableMemOK) SetPayload(payload *models.MaxAllocatableMemResponse) {
|
||||||
|
o.Payload = payload
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteResponse to the client
|
||||||
|
func (o *GetMaxAllocatableMemOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
|
||||||
|
|
||||||
|
rw.WriteHeader(200)
|
||||||
|
if o.Payload != nil {
|
||||||
|
payload := o.Payload
|
||||||
|
if err := producer.Produce(rw, payload); err != nil {
|
||||||
|
panic(err) // let the recovery middleware deal with this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*GetMaxAllocatableMemDefault Generic error response.
|
||||||
|
|
||||||
|
swagger:response getMaxAllocatableMemDefault
|
||||||
|
*/
|
||||||
|
type GetMaxAllocatableMemDefault struct {
|
||||||
|
_statusCode int
|
||||||
|
|
||||||
|
/*
|
||||||
|
In: Body
|
||||||
|
*/
|
||||||
|
Payload *models.Error `json:"body,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewGetMaxAllocatableMemDefault creates GetMaxAllocatableMemDefault with default headers values
|
||||||
|
func NewGetMaxAllocatableMemDefault(code int) *GetMaxAllocatableMemDefault {
|
||||||
|
if code <= 0 {
|
||||||
|
code = 500
|
||||||
|
}
|
||||||
|
|
||||||
|
return &GetMaxAllocatableMemDefault{
|
||||||
|
_statusCode: code,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithStatusCode adds the status to the get max allocatable mem default response
|
||||||
|
func (o *GetMaxAllocatableMemDefault) WithStatusCode(code int) *GetMaxAllocatableMemDefault {
|
||||||
|
o._statusCode = code
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetStatusCode sets the status to the get max allocatable mem default response
|
||||||
|
func (o *GetMaxAllocatableMemDefault) SetStatusCode(code int) {
|
||||||
|
o._statusCode = code
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithPayload adds the payload to the get max allocatable mem default response
|
||||||
|
func (o *GetMaxAllocatableMemDefault) WithPayload(payload *models.Error) *GetMaxAllocatableMemDefault {
|
||||||
|
o.Payload = payload
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPayload sets the payload to the get max allocatable mem default response
|
||||||
|
func (o *GetMaxAllocatableMemDefault) SetPayload(payload *models.Error) {
|
||||||
|
o.Payload = payload
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteResponse to the client
|
||||||
|
func (o *GetMaxAllocatableMemDefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
|
||||||
|
|
||||||
|
rw.WriteHeader(o._statusCode)
|
||||||
|
if o.Payload != nil {
|
||||||
|
payload := o.Payload
|
||||||
|
if err := producer.Produce(rw, payload); err != nil {
|
||||||
|
panic(err) // let the recovery middleware deal with this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,119 @@
|
|||||||
|
// 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 admin_api
|
||||||
|
|
||||||
|
// This file was generated by the swagger tool.
|
||||||
|
// Editing this file might prove futile when you re-run the generate command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"net/url"
|
||||||
|
golangswaggerpaths "path"
|
||||||
|
|
||||||
|
"github.com/go-openapi/swag"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetMaxAllocatableMemURL generates an URL for the get max allocatable mem operation
|
||||||
|
type GetMaxAllocatableMemURL struct {
|
||||||
|
NumNodes int32
|
||||||
|
|
||||||
|
_basePath string
|
||||||
|
// avoid unkeyed usage
|
||||||
|
_ struct{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithBasePath sets the base path for this url builder, only required when it's different from the
|
||||||
|
// base path specified in the swagger spec.
|
||||||
|
// When the value of the base path is an empty string
|
||||||
|
func (o *GetMaxAllocatableMemURL) WithBasePath(bp string) *GetMaxAllocatableMemURL {
|
||||||
|
o.SetBasePath(bp)
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetBasePath sets the base path for this url builder, only required when it's different from the
|
||||||
|
// base path specified in the swagger spec.
|
||||||
|
// When the value of the base path is an empty string
|
||||||
|
func (o *GetMaxAllocatableMemURL) SetBasePath(bp string) {
|
||||||
|
o._basePath = bp
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build a url path and query string
|
||||||
|
func (o *GetMaxAllocatableMemURL) Build() (*url.URL, error) {
|
||||||
|
var _result url.URL
|
||||||
|
|
||||||
|
var _path = "/cluster/max-allocatable-memory"
|
||||||
|
|
||||||
|
_basePath := o._basePath
|
||||||
|
if _basePath == "" {
|
||||||
|
_basePath = "/api/v1"
|
||||||
|
}
|
||||||
|
_result.Path = golangswaggerpaths.Join(_basePath, _path)
|
||||||
|
|
||||||
|
qs := make(url.Values)
|
||||||
|
|
||||||
|
numNodesQ := swag.FormatInt32(o.NumNodes)
|
||||||
|
if numNodesQ != "" {
|
||||||
|
qs.Set("num_nodes", numNodesQ)
|
||||||
|
}
|
||||||
|
|
||||||
|
_result.RawQuery = qs.Encode()
|
||||||
|
|
||||||
|
return &_result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Must is a helper function to panic when the url builder returns an error
|
||||||
|
func (o *GetMaxAllocatableMemURL) Must(u *url.URL, err error) *url.URL {
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if u == nil {
|
||||||
|
panic("url can't be nil")
|
||||||
|
}
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the string representation of the path with query string
|
||||||
|
func (o *GetMaxAllocatableMemURL) String() string {
|
||||||
|
return o.Must(o.Build()).String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// BuildFull builds a full url with scheme, host, path and query string
|
||||||
|
func (o *GetMaxAllocatableMemURL) BuildFull(scheme, host string) (*url.URL, error) {
|
||||||
|
if scheme == "" {
|
||||||
|
return nil, errors.New("scheme is required for a full url on GetMaxAllocatableMemURL")
|
||||||
|
}
|
||||||
|
if host == "" {
|
||||||
|
return nil, errors.New("host is required for a full url on GetMaxAllocatableMemURL")
|
||||||
|
}
|
||||||
|
|
||||||
|
base, err := o.Build()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
base.Scheme = scheme
|
||||||
|
base.Host = host
|
||||||
|
return base, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringFull returns the string representation of a complete url
|
||||||
|
func (o *GetMaxAllocatableMemURL) StringFull(scheme, host string) string {
|
||||||
|
return o.Must(o.BuildFull(scheme, host)).String()
|
||||||
|
}
|
||||||
90
restapi/operations/admin_api/tenant_update_certificate.go
Normal file
90
restapi/operations/admin_api/tenant_update_certificate.go
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
// 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 admin_api
|
||||||
|
|
||||||
|
// This file was generated by the swagger tool.
|
||||||
|
// Editing this file might prove futile when you re-run the generate command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/go-openapi/runtime/middleware"
|
||||||
|
|
||||||
|
"github.com/minio/console/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TenantUpdateCertificateHandlerFunc turns a function with the right signature into a tenant update certificate handler
|
||||||
|
type TenantUpdateCertificateHandlerFunc func(TenantUpdateCertificateParams, *models.Principal) middleware.Responder
|
||||||
|
|
||||||
|
// Handle executing the request and returning a response
|
||||||
|
func (fn TenantUpdateCertificateHandlerFunc) Handle(params TenantUpdateCertificateParams, principal *models.Principal) middleware.Responder {
|
||||||
|
return fn(params, principal)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TenantUpdateCertificateHandler interface for that can handle valid tenant update certificate params
|
||||||
|
type TenantUpdateCertificateHandler interface {
|
||||||
|
Handle(TenantUpdateCertificateParams, *models.Principal) middleware.Responder
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTenantUpdateCertificate creates a new http.Handler for the tenant update certificate operation
|
||||||
|
func NewTenantUpdateCertificate(ctx *middleware.Context, handler TenantUpdateCertificateHandler) *TenantUpdateCertificate {
|
||||||
|
return &TenantUpdateCertificate{Context: ctx, Handler: handler}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*TenantUpdateCertificate swagger:route PUT /namespaces/{namespace}/tenants/{tenant}/certificates AdminAPI tenantUpdateCertificate
|
||||||
|
|
||||||
|
Tenant Update Certificates
|
||||||
|
|
||||||
|
*/
|
||||||
|
type TenantUpdateCertificate struct {
|
||||||
|
Context *middleware.Context
|
||||||
|
Handler TenantUpdateCertificateHandler
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *TenantUpdateCertificate) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
||||||
|
route, rCtx, _ := o.Context.RouteInfo(r)
|
||||||
|
if rCtx != nil {
|
||||||
|
r = rCtx
|
||||||
|
}
|
||||||
|
var Params = NewTenantUpdateCertificateParams()
|
||||||
|
|
||||||
|
uprinc, aCtx, err := o.Context.Authorize(r, route)
|
||||||
|
if err != nil {
|
||||||
|
o.Context.Respond(rw, r, route.Produces, route, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if aCtx != nil {
|
||||||
|
r = aCtx
|
||||||
|
}
|
||||||
|
var principal *models.Principal
|
||||||
|
if uprinc != nil {
|
||||||
|
principal = uprinc.(*models.Principal) // this is really a models.Principal, I promise
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params
|
||||||
|
o.Context.Respond(rw, r, route.Produces, route, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
res := o.Handler.Handle(Params, principal) // actually handle the request
|
||||||
|
|
||||||
|
o.Context.Respond(rw, r, route.Produces, route, res)
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,145 @@
|
|||||||
|
// 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 admin_api
|
||||||
|
|
||||||
|
// This file was generated by the swagger tool.
|
||||||
|
// Editing this file might prove futile when you re-run the swagger generate command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/go-openapi/errors"
|
||||||
|
"github.com/go-openapi/runtime"
|
||||||
|
"github.com/go-openapi/runtime/middleware"
|
||||||
|
"github.com/go-openapi/strfmt"
|
||||||
|
|
||||||
|
"github.com/minio/console/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewTenantUpdateCertificateParams creates a new TenantUpdateCertificateParams object
|
||||||
|
// no default values defined in spec.
|
||||||
|
func NewTenantUpdateCertificateParams() TenantUpdateCertificateParams {
|
||||||
|
|
||||||
|
return TenantUpdateCertificateParams{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TenantUpdateCertificateParams contains all the bound params for the tenant update certificate operation
|
||||||
|
// typically these are obtained from a http.Request
|
||||||
|
//
|
||||||
|
// swagger:parameters TenantUpdateCertificate
|
||||||
|
type TenantUpdateCertificateParams struct {
|
||||||
|
|
||||||
|
// HTTP Request Object
|
||||||
|
HTTPRequest *http.Request `json:"-"`
|
||||||
|
|
||||||
|
/*
|
||||||
|
Required: true
|
||||||
|
In: body
|
||||||
|
*/
|
||||||
|
Body *models.TLSConfiguration
|
||||||
|
/*
|
||||||
|
Required: true
|
||||||
|
In: path
|
||||||
|
*/
|
||||||
|
Namespace string
|
||||||
|
/*
|
||||||
|
Required: true
|
||||||
|
In: path
|
||||||
|
*/
|
||||||
|
Tenant string
|
||||||
|
}
|
||||||
|
|
||||||
|
// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface
|
||||||
|
// for simple values it will use straight method calls.
|
||||||
|
//
|
||||||
|
// To ensure default values, the struct must have been initialized with NewTenantUpdateCertificateParams() beforehand.
|
||||||
|
func (o *TenantUpdateCertificateParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error {
|
||||||
|
var res []error
|
||||||
|
|
||||||
|
o.HTTPRequest = r
|
||||||
|
|
||||||
|
if runtime.HasBody(r) {
|
||||||
|
defer r.Body.Close()
|
||||||
|
var body models.TLSConfiguration
|
||||||
|
if err := route.Consumer.Consume(r.Body, &body); err != nil {
|
||||||
|
if err == io.EOF {
|
||||||
|
res = append(res, errors.Required("body", "body", ""))
|
||||||
|
} else {
|
||||||
|
res = append(res, errors.NewParseError("body", "body", "", err))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// validate body object
|
||||||
|
if err := body.Validate(route.Formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(res) == 0 {
|
||||||
|
o.Body = &body
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
res = append(res, errors.Required("body", "body", ""))
|
||||||
|
}
|
||||||
|
rNamespace, rhkNamespace, _ := route.Params.GetOK("namespace")
|
||||||
|
if err := o.bindNamespace(rNamespace, rhkNamespace, route.Formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
rTenant, rhkTenant, _ := route.Params.GetOK("tenant")
|
||||||
|
if err := o.bindTenant(rTenant, rhkTenant, route.Formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(res) > 0 {
|
||||||
|
return errors.CompositeValidationError(res...)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// bindNamespace binds and validates parameter Namespace from path.
|
||||||
|
func (o *TenantUpdateCertificateParams) bindNamespace(rawData []string, hasKey bool, formats strfmt.Registry) error {
|
||||||
|
var raw string
|
||||||
|
if len(rawData) > 0 {
|
||||||
|
raw = rawData[len(rawData)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Required: true
|
||||||
|
// Parameter is provided by construction from the route
|
||||||
|
|
||||||
|
o.Namespace = raw
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// bindTenant binds and validates parameter Tenant from path.
|
||||||
|
func (o *TenantUpdateCertificateParams) bindTenant(rawData []string, hasKey bool, formats strfmt.Registry) error {
|
||||||
|
var raw string
|
||||||
|
if len(rawData) > 0 {
|
||||||
|
raw = rawData[len(rawData)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Required: true
|
||||||
|
// Parameter is provided by construction from the route
|
||||||
|
|
||||||
|
o.Tenant = raw
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
// 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 admin_api
|
||||||
|
|
||||||
|
// This file was generated by the swagger tool.
|
||||||
|
// Editing this file might prove futile when you re-run the swagger generate command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/go-openapi/runtime"
|
||||||
|
|
||||||
|
"github.com/minio/console/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TenantUpdateCertificateCreatedCode is the HTTP code returned for type TenantUpdateCertificateCreated
|
||||||
|
const TenantUpdateCertificateCreatedCode int = 201
|
||||||
|
|
||||||
|
/*TenantUpdateCertificateCreated A successful response.
|
||||||
|
|
||||||
|
swagger:response tenantUpdateCertificateCreated
|
||||||
|
*/
|
||||||
|
type TenantUpdateCertificateCreated struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTenantUpdateCertificateCreated creates TenantUpdateCertificateCreated with default headers values
|
||||||
|
func NewTenantUpdateCertificateCreated() *TenantUpdateCertificateCreated {
|
||||||
|
|
||||||
|
return &TenantUpdateCertificateCreated{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteResponse to the client
|
||||||
|
func (o *TenantUpdateCertificateCreated) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
|
||||||
|
|
||||||
|
rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses
|
||||||
|
|
||||||
|
rw.WriteHeader(201)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*TenantUpdateCertificateDefault Generic error response.
|
||||||
|
|
||||||
|
swagger:response tenantUpdateCertificateDefault
|
||||||
|
*/
|
||||||
|
type TenantUpdateCertificateDefault struct {
|
||||||
|
_statusCode int
|
||||||
|
|
||||||
|
/*
|
||||||
|
In: Body
|
||||||
|
*/
|
||||||
|
Payload *models.Error `json:"body,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTenantUpdateCertificateDefault creates TenantUpdateCertificateDefault with default headers values
|
||||||
|
func NewTenantUpdateCertificateDefault(code int) *TenantUpdateCertificateDefault {
|
||||||
|
if code <= 0 {
|
||||||
|
code = 500
|
||||||
|
}
|
||||||
|
|
||||||
|
return &TenantUpdateCertificateDefault{
|
||||||
|
_statusCode: code,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithStatusCode adds the status to the tenant update certificate default response
|
||||||
|
func (o *TenantUpdateCertificateDefault) WithStatusCode(code int) *TenantUpdateCertificateDefault {
|
||||||
|
o._statusCode = code
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetStatusCode sets the status to the tenant update certificate default response
|
||||||
|
func (o *TenantUpdateCertificateDefault) SetStatusCode(code int) {
|
||||||
|
o._statusCode = code
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithPayload adds the payload to the tenant update certificate default response
|
||||||
|
func (o *TenantUpdateCertificateDefault) WithPayload(payload *models.Error) *TenantUpdateCertificateDefault {
|
||||||
|
o.Payload = payload
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPayload sets the payload to the tenant update certificate default response
|
||||||
|
func (o *TenantUpdateCertificateDefault) SetPayload(payload *models.Error) {
|
||||||
|
o.Payload = payload
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteResponse to the client
|
||||||
|
func (o *TenantUpdateCertificateDefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
|
||||||
|
|
||||||
|
rw.WriteHeader(o._statusCode)
|
||||||
|
if o.Payload != nil {
|
||||||
|
payload := o.Payload
|
||||||
|
if err := producer.Produce(rw, payload); err != nil {
|
||||||
|
panic(err) // let the recovery middleware deal with this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
// 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 admin_api
|
||||||
|
|
||||||
|
// This file was generated by the swagger tool.
|
||||||
|
// Editing this file might prove futile when you re-run the generate command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"net/url"
|
||||||
|
golangswaggerpaths "path"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TenantUpdateCertificateURL generates an URL for the tenant update certificate operation
|
||||||
|
type TenantUpdateCertificateURL struct {
|
||||||
|
Namespace string
|
||||||
|
Tenant string
|
||||||
|
|
||||||
|
_basePath string
|
||||||
|
// avoid unkeyed usage
|
||||||
|
_ struct{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithBasePath sets the base path for this url builder, only required when it's different from the
|
||||||
|
// base path specified in the swagger spec.
|
||||||
|
// When the value of the base path is an empty string
|
||||||
|
func (o *TenantUpdateCertificateURL) WithBasePath(bp string) *TenantUpdateCertificateURL {
|
||||||
|
o.SetBasePath(bp)
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetBasePath sets the base path for this url builder, only required when it's different from the
|
||||||
|
// base path specified in the swagger spec.
|
||||||
|
// When the value of the base path is an empty string
|
||||||
|
func (o *TenantUpdateCertificateURL) SetBasePath(bp string) {
|
||||||
|
o._basePath = bp
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build a url path and query string
|
||||||
|
func (o *TenantUpdateCertificateURL) Build() (*url.URL, error) {
|
||||||
|
var _result url.URL
|
||||||
|
|
||||||
|
var _path = "/namespaces/{namespace}/tenants/{tenant}/certificates"
|
||||||
|
|
||||||
|
namespace := o.Namespace
|
||||||
|
if namespace != "" {
|
||||||
|
_path = strings.Replace(_path, "{namespace}", namespace, -1)
|
||||||
|
} else {
|
||||||
|
return nil, errors.New("namespace is required on TenantUpdateCertificateURL")
|
||||||
|
}
|
||||||
|
|
||||||
|
tenant := o.Tenant
|
||||||
|
if tenant != "" {
|
||||||
|
_path = strings.Replace(_path, "{tenant}", tenant, -1)
|
||||||
|
} else {
|
||||||
|
return nil, errors.New("tenant is required on TenantUpdateCertificateURL")
|
||||||
|
}
|
||||||
|
|
||||||
|
_basePath := o._basePath
|
||||||
|
if _basePath == "" {
|
||||||
|
_basePath = "/api/v1"
|
||||||
|
}
|
||||||
|
_result.Path = golangswaggerpaths.Join(_basePath, _path)
|
||||||
|
|
||||||
|
return &_result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Must is a helper function to panic when the url builder returns an error
|
||||||
|
func (o *TenantUpdateCertificateURL) Must(u *url.URL, err error) *url.URL {
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if u == nil {
|
||||||
|
panic("url can't be nil")
|
||||||
|
}
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the string representation of the path with query string
|
||||||
|
func (o *TenantUpdateCertificateURL) String() string {
|
||||||
|
return o.Must(o.Build()).String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// BuildFull builds a full url with scheme, host, path and query string
|
||||||
|
func (o *TenantUpdateCertificateURL) BuildFull(scheme, host string) (*url.URL, error) {
|
||||||
|
if scheme == "" {
|
||||||
|
return nil, errors.New("scheme is required for a full url on TenantUpdateCertificateURL")
|
||||||
|
}
|
||||||
|
if host == "" {
|
||||||
|
return nil, errors.New("host is required for a full url on TenantUpdateCertificateURL")
|
||||||
|
}
|
||||||
|
|
||||||
|
base, err := o.Build()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
base.Scheme = scheme
|
||||||
|
base.Host = host
|
||||||
|
return base, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringFull returns the string representation of a complete url
|
||||||
|
func (o *TenantUpdateCertificateURL) StringFull(scheme, host string) string {
|
||||||
|
return o.Must(o.BuildFull(scheme, host)).String()
|
||||||
|
}
|
||||||
90
restapi/operations/admin_api/tenant_update_encryption.go
Normal file
90
restapi/operations/admin_api/tenant_update_encryption.go
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
// 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 admin_api
|
||||||
|
|
||||||
|
// This file was generated by the swagger tool.
|
||||||
|
// Editing this file might prove futile when you re-run the generate command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/go-openapi/runtime/middleware"
|
||||||
|
|
||||||
|
"github.com/minio/console/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TenantUpdateEncryptionHandlerFunc turns a function with the right signature into a tenant update encryption handler
|
||||||
|
type TenantUpdateEncryptionHandlerFunc func(TenantUpdateEncryptionParams, *models.Principal) middleware.Responder
|
||||||
|
|
||||||
|
// Handle executing the request and returning a response
|
||||||
|
func (fn TenantUpdateEncryptionHandlerFunc) Handle(params TenantUpdateEncryptionParams, principal *models.Principal) middleware.Responder {
|
||||||
|
return fn(params, principal)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TenantUpdateEncryptionHandler interface for that can handle valid tenant update encryption params
|
||||||
|
type TenantUpdateEncryptionHandler interface {
|
||||||
|
Handle(TenantUpdateEncryptionParams, *models.Principal) middleware.Responder
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTenantUpdateEncryption creates a new http.Handler for the tenant update encryption operation
|
||||||
|
func NewTenantUpdateEncryption(ctx *middleware.Context, handler TenantUpdateEncryptionHandler) *TenantUpdateEncryption {
|
||||||
|
return &TenantUpdateEncryption{Context: ctx, Handler: handler}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*TenantUpdateEncryption swagger:route PUT /namespaces/{namespace}/tenants/{tenant}/encryption AdminAPI tenantUpdateEncryption
|
||||||
|
|
||||||
|
Tenant Update Encryption
|
||||||
|
|
||||||
|
*/
|
||||||
|
type TenantUpdateEncryption struct {
|
||||||
|
Context *middleware.Context
|
||||||
|
Handler TenantUpdateEncryptionHandler
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *TenantUpdateEncryption) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
||||||
|
route, rCtx, _ := o.Context.RouteInfo(r)
|
||||||
|
if rCtx != nil {
|
||||||
|
r = rCtx
|
||||||
|
}
|
||||||
|
var Params = NewTenantUpdateEncryptionParams()
|
||||||
|
|
||||||
|
uprinc, aCtx, err := o.Context.Authorize(r, route)
|
||||||
|
if err != nil {
|
||||||
|
o.Context.Respond(rw, r, route.Produces, route, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if aCtx != nil {
|
||||||
|
r = aCtx
|
||||||
|
}
|
||||||
|
var principal *models.Principal
|
||||||
|
if uprinc != nil {
|
||||||
|
principal = uprinc.(*models.Principal) // this is really a models.Principal, I promise
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params
|
||||||
|
o.Context.Respond(rw, r, route.Produces, route, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
res := o.Handler.Handle(Params, principal) // actually handle the request
|
||||||
|
|
||||||
|
o.Context.Respond(rw, r, route.Produces, route, res)
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,145 @@
|
|||||||
|
// 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 admin_api
|
||||||
|
|
||||||
|
// This file was generated by the swagger tool.
|
||||||
|
// Editing this file might prove futile when you re-run the swagger generate command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/go-openapi/errors"
|
||||||
|
"github.com/go-openapi/runtime"
|
||||||
|
"github.com/go-openapi/runtime/middleware"
|
||||||
|
"github.com/go-openapi/strfmt"
|
||||||
|
|
||||||
|
"github.com/minio/console/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewTenantUpdateEncryptionParams creates a new TenantUpdateEncryptionParams object
|
||||||
|
// no default values defined in spec.
|
||||||
|
func NewTenantUpdateEncryptionParams() TenantUpdateEncryptionParams {
|
||||||
|
|
||||||
|
return TenantUpdateEncryptionParams{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TenantUpdateEncryptionParams contains all the bound params for the tenant update encryption operation
|
||||||
|
// typically these are obtained from a http.Request
|
||||||
|
//
|
||||||
|
// swagger:parameters TenantUpdateEncryption
|
||||||
|
type TenantUpdateEncryptionParams struct {
|
||||||
|
|
||||||
|
// HTTP Request Object
|
||||||
|
HTTPRequest *http.Request `json:"-"`
|
||||||
|
|
||||||
|
/*
|
||||||
|
Required: true
|
||||||
|
In: body
|
||||||
|
*/
|
||||||
|
Body *models.EncryptionConfiguration
|
||||||
|
/*
|
||||||
|
Required: true
|
||||||
|
In: path
|
||||||
|
*/
|
||||||
|
Namespace string
|
||||||
|
/*
|
||||||
|
Required: true
|
||||||
|
In: path
|
||||||
|
*/
|
||||||
|
Tenant string
|
||||||
|
}
|
||||||
|
|
||||||
|
// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface
|
||||||
|
// for simple values it will use straight method calls.
|
||||||
|
//
|
||||||
|
// To ensure default values, the struct must have been initialized with NewTenantUpdateEncryptionParams() beforehand.
|
||||||
|
func (o *TenantUpdateEncryptionParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error {
|
||||||
|
var res []error
|
||||||
|
|
||||||
|
o.HTTPRequest = r
|
||||||
|
|
||||||
|
if runtime.HasBody(r) {
|
||||||
|
defer r.Body.Close()
|
||||||
|
var body models.EncryptionConfiguration
|
||||||
|
if err := route.Consumer.Consume(r.Body, &body); err != nil {
|
||||||
|
if err == io.EOF {
|
||||||
|
res = append(res, errors.Required("body", "body", ""))
|
||||||
|
} else {
|
||||||
|
res = append(res, errors.NewParseError("body", "body", "", err))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// validate body object
|
||||||
|
if err := body.Validate(route.Formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(res) == 0 {
|
||||||
|
o.Body = &body
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
res = append(res, errors.Required("body", "body", ""))
|
||||||
|
}
|
||||||
|
rNamespace, rhkNamespace, _ := route.Params.GetOK("namespace")
|
||||||
|
if err := o.bindNamespace(rNamespace, rhkNamespace, route.Formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
rTenant, rhkTenant, _ := route.Params.GetOK("tenant")
|
||||||
|
if err := o.bindTenant(rTenant, rhkTenant, route.Formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(res) > 0 {
|
||||||
|
return errors.CompositeValidationError(res...)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// bindNamespace binds and validates parameter Namespace from path.
|
||||||
|
func (o *TenantUpdateEncryptionParams) bindNamespace(rawData []string, hasKey bool, formats strfmt.Registry) error {
|
||||||
|
var raw string
|
||||||
|
if len(rawData) > 0 {
|
||||||
|
raw = rawData[len(rawData)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Required: true
|
||||||
|
// Parameter is provided by construction from the route
|
||||||
|
|
||||||
|
o.Namespace = raw
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// bindTenant binds and validates parameter Tenant from path.
|
||||||
|
func (o *TenantUpdateEncryptionParams) bindTenant(rawData []string, hasKey bool, formats strfmt.Registry) error {
|
||||||
|
var raw string
|
||||||
|
if len(rawData) > 0 {
|
||||||
|
raw = rawData[len(rawData)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Required: true
|
||||||
|
// Parameter is provided by construction from the route
|
||||||
|
|
||||||
|
o.Tenant = raw
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
// 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 admin_api
|
||||||
|
|
||||||
|
// This file was generated by the swagger tool.
|
||||||
|
// Editing this file might prove futile when you re-run the swagger generate command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/go-openapi/runtime"
|
||||||
|
|
||||||
|
"github.com/minio/console/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TenantUpdateEncryptionCreatedCode is the HTTP code returned for type TenantUpdateEncryptionCreated
|
||||||
|
const TenantUpdateEncryptionCreatedCode int = 201
|
||||||
|
|
||||||
|
/*TenantUpdateEncryptionCreated A successful response.
|
||||||
|
|
||||||
|
swagger:response tenantUpdateEncryptionCreated
|
||||||
|
*/
|
||||||
|
type TenantUpdateEncryptionCreated struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTenantUpdateEncryptionCreated creates TenantUpdateEncryptionCreated with default headers values
|
||||||
|
func NewTenantUpdateEncryptionCreated() *TenantUpdateEncryptionCreated {
|
||||||
|
|
||||||
|
return &TenantUpdateEncryptionCreated{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteResponse to the client
|
||||||
|
func (o *TenantUpdateEncryptionCreated) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
|
||||||
|
|
||||||
|
rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses
|
||||||
|
|
||||||
|
rw.WriteHeader(201)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*TenantUpdateEncryptionDefault Generic error response.
|
||||||
|
|
||||||
|
swagger:response tenantUpdateEncryptionDefault
|
||||||
|
*/
|
||||||
|
type TenantUpdateEncryptionDefault struct {
|
||||||
|
_statusCode int
|
||||||
|
|
||||||
|
/*
|
||||||
|
In: Body
|
||||||
|
*/
|
||||||
|
Payload *models.Error `json:"body,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTenantUpdateEncryptionDefault creates TenantUpdateEncryptionDefault with default headers values
|
||||||
|
func NewTenantUpdateEncryptionDefault(code int) *TenantUpdateEncryptionDefault {
|
||||||
|
if code <= 0 {
|
||||||
|
code = 500
|
||||||
|
}
|
||||||
|
|
||||||
|
return &TenantUpdateEncryptionDefault{
|
||||||
|
_statusCode: code,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithStatusCode adds the status to the tenant update encryption default response
|
||||||
|
func (o *TenantUpdateEncryptionDefault) WithStatusCode(code int) *TenantUpdateEncryptionDefault {
|
||||||
|
o._statusCode = code
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetStatusCode sets the status to the tenant update encryption default response
|
||||||
|
func (o *TenantUpdateEncryptionDefault) SetStatusCode(code int) {
|
||||||
|
o._statusCode = code
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithPayload adds the payload to the tenant update encryption default response
|
||||||
|
func (o *TenantUpdateEncryptionDefault) WithPayload(payload *models.Error) *TenantUpdateEncryptionDefault {
|
||||||
|
o.Payload = payload
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPayload sets the payload to the tenant update encryption default response
|
||||||
|
func (o *TenantUpdateEncryptionDefault) SetPayload(payload *models.Error) {
|
||||||
|
o.Payload = payload
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteResponse to the client
|
||||||
|
func (o *TenantUpdateEncryptionDefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
|
||||||
|
|
||||||
|
rw.WriteHeader(o._statusCode)
|
||||||
|
if o.Payload != nil {
|
||||||
|
payload := o.Payload
|
||||||
|
if err := producer.Produce(rw, payload); err != nil {
|
||||||
|
panic(err) // let the recovery middleware deal with this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
// 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 admin_api
|
||||||
|
|
||||||
|
// This file was generated by the swagger tool.
|
||||||
|
// Editing this file might prove futile when you re-run the generate command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"net/url"
|
||||||
|
golangswaggerpaths "path"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TenantUpdateEncryptionURL generates an URL for the tenant update encryption operation
|
||||||
|
type TenantUpdateEncryptionURL struct {
|
||||||
|
Namespace string
|
||||||
|
Tenant string
|
||||||
|
|
||||||
|
_basePath string
|
||||||
|
// avoid unkeyed usage
|
||||||
|
_ struct{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithBasePath sets the base path for this url builder, only required when it's different from the
|
||||||
|
// base path specified in the swagger spec.
|
||||||
|
// When the value of the base path is an empty string
|
||||||
|
func (o *TenantUpdateEncryptionURL) WithBasePath(bp string) *TenantUpdateEncryptionURL {
|
||||||
|
o.SetBasePath(bp)
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetBasePath sets the base path for this url builder, only required when it's different from the
|
||||||
|
// base path specified in the swagger spec.
|
||||||
|
// When the value of the base path is an empty string
|
||||||
|
func (o *TenantUpdateEncryptionURL) SetBasePath(bp string) {
|
||||||
|
o._basePath = bp
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build a url path and query string
|
||||||
|
func (o *TenantUpdateEncryptionURL) Build() (*url.URL, error) {
|
||||||
|
var _result url.URL
|
||||||
|
|
||||||
|
var _path = "/namespaces/{namespace}/tenants/{tenant}/encryption"
|
||||||
|
|
||||||
|
namespace := o.Namespace
|
||||||
|
if namespace != "" {
|
||||||
|
_path = strings.Replace(_path, "{namespace}", namespace, -1)
|
||||||
|
} else {
|
||||||
|
return nil, errors.New("namespace is required on TenantUpdateEncryptionURL")
|
||||||
|
}
|
||||||
|
|
||||||
|
tenant := o.Tenant
|
||||||
|
if tenant != "" {
|
||||||
|
_path = strings.Replace(_path, "{tenant}", tenant, -1)
|
||||||
|
} else {
|
||||||
|
return nil, errors.New("tenant is required on TenantUpdateEncryptionURL")
|
||||||
|
}
|
||||||
|
|
||||||
|
_basePath := o._basePath
|
||||||
|
if _basePath == "" {
|
||||||
|
_basePath = "/api/v1"
|
||||||
|
}
|
||||||
|
_result.Path = golangswaggerpaths.Join(_basePath, _path)
|
||||||
|
|
||||||
|
return &_result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Must is a helper function to panic when the url builder returns an error
|
||||||
|
func (o *TenantUpdateEncryptionURL) Must(u *url.URL, err error) *url.URL {
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if u == nil {
|
||||||
|
panic("url can't be nil")
|
||||||
|
}
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the string representation of the path with query string
|
||||||
|
func (o *TenantUpdateEncryptionURL) String() string {
|
||||||
|
return o.Must(o.Build()).String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// BuildFull builds a full url with scheme, host, path and query string
|
||||||
|
func (o *TenantUpdateEncryptionURL) BuildFull(scheme, host string) (*url.URL, error) {
|
||||||
|
if scheme == "" {
|
||||||
|
return nil, errors.New("scheme is required for a full url on TenantUpdateEncryptionURL")
|
||||||
|
}
|
||||||
|
if host == "" {
|
||||||
|
return nil, errors.New("host is required for a full url on TenantUpdateEncryptionURL")
|
||||||
|
}
|
||||||
|
|
||||||
|
base, err := o.Build()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
base.Scheme = scheme
|
||||||
|
base.Host = host
|
||||||
|
return base, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringFull returns the string representation of a complete url
|
||||||
|
func (o *TenantUpdateEncryptionURL) StringFull(scheme, host string) string {
|
||||||
|
return o.Must(o.BuildFull(scheme, host)).String()
|
||||||
|
}
|
||||||
90
restapi/operations/admin_api/tenant_update_zones.go
Normal file
90
restapi/operations/admin_api/tenant_update_zones.go
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
// 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 admin_api
|
||||||
|
|
||||||
|
// This file was generated by the swagger tool.
|
||||||
|
// Editing this file might prove futile when you re-run the generate command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/go-openapi/runtime/middleware"
|
||||||
|
|
||||||
|
"github.com/minio/console/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TenantUpdateZonesHandlerFunc turns a function with the right signature into a tenant update zones handler
|
||||||
|
type TenantUpdateZonesHandlerFunc func(TenantUpdateZonesParams, *models.Principal) middleware.Responder
|
||||||
|
|
||||||
|
// Handle executing the request and returning a response
|
||||||
|
func (fn TenantUpdateZonesHandlerFunc) Handle(params TenantUpdateZonesParams, principal *models.Principal) middleware.Responder {
|
||||||
|
return fn(params, principal)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TenantUpdateZonesHandler interface for that can handle valid tenant update zones params
|
||||||
|
type TenantUpdateZonesHandler interface {
|
||||||
|
Handle(TenantUpdateZonesParams, *models.Principal) middleware.Responder
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTenantUpdateZones creates a new http.Handler for the tenant update zones operation
|
||||||
|
func NewTenantUpdateZones(ctx *middleware.Context, handler TenantUpdateZonesHandler) *TenantUpdateZones {
|
||||||
|
return &TenantUpdateZones{Context: ctx, Handler: handler}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*TenantUpdateZones swagger:route PUT /namespaces/{namespace}/tenants/{tenant}/zones AdminAPI tenantUpdateZones
|
||||||
|
|
||||||
|
Tenant Update Zones
|
||||||
|
|
||||||
|
*/
|
||||||
|
type TenantUpdateZones struct {
|
||||||
|
Context *middleware.Context
|
||||||
|
Handler TenantUpdateZonesHandler
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *TenantUpdateZones) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
||||||
|
route, rCtx, _ := o.Context.RouteInfo(r)
|
||||||
|
if rCtx != nil {
|
||||||
|
r = rCtx
|
||||||
|
}
|
||||||
|
var Params = NewTenantUpdateZonesParams()
|
||||||
|
|
||||||
|
uprinc, aCtx, err := o.Context.Authorize(r, route)
|
||||||
|
if err != nil {
|
||||||
|
o.Context.Respond(rw, r, route.Produces, route, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if aCtx != nil {
|
||||||
|
r = aCtx
|
||||||
|
}
|
||||||
|
var principal *models.Principal
|
||||||
|
if uprinc != nil {
|
||||||
|
principal = uprinc.(*models.Principal) // this is really a models.Principal, I promise
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params
|
||||||
|
o.Context.Respond(rw, r, route.Produces, route, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
res := o.Handler.Handle(Params, principal) // actually handle the request
|
||||||
|
|
||||||
|
o.Context.Respond(rw, r, route.Produces, route, res)
|
||||||
|
|
||||||
|
}
|
||||||
145
restapi/operations/admin_api/tenant_update_zones_parameters.go
Normal file
145
restapi/operations/admin_api/tenant_update_zones_parameters.go
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
// 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 admin_api
|
||||||
|
|
||||||
|
// This file was generated by the swagger tool.
|
||||||
|
// Editing this file might prove futile when you re-run the swagger generate command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/go-openapi/errors"
|
||||||
|
"github.com/go-openapi/runtime"
|
||||||
|
"github.com/go-openapi/runtime/middleware"
|
||||||
|
"github.com/go-openapi/strfmt"
|
||||||
|
|
||||||
|
"github.com/minio/console/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewTenantUpdateZonesParams creates a new TenantUpdateZonesParams object
|
||||||
|
// no default values defined in spec.
|
||||||
|
func NewTenantUpdateZonesParams() TenantUpdateZonesParams {
|
||||||
|
|
||||||
|
return TenantUpdateZonesParams{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TenantUpdateZonesParams contains all the bound params for the tenant update zones operation
|
||||||
|
// typically these are obtained from a http.Request
|
||||||
|
//
|
||||||
|
// swagger:parameters TenantUpdateZones
|
||||||
|
type TenantUpdateZonesParams struct {
|
||||||
|
|
||||||
|
// HTTP Request Object
|
||||||
|
HTTPRequest *http.Request `json:"-"`
|
||||||
|
|
||||||
|
/*
|
||||||
|
Required: true
|
||||||
|
In: body
|
||||||
|
*/
|
||||||
|
Body *models.ZoneUpdateRequest
|
||||||
|
/*
|
||||||
|
Required: true
|
||||||
|
In: path
|
||||||
|
*/
|
||||||
|
Namespace string
|
||||||
|
/*
|
||||||
|
Required: true
|
||||||
|
In: path
|
||||||
|
*/
|
||||||
|
Tenant string
|
||||||
|
}
|
||||||
|
|
||||||
|
// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface
|
||||||
|
// for simple values it will use straight method calls.
|
||||||
|
//
|
||||||
|
// To ensure default values, the struct must have been initialized with NewTenantUpdateZonesParams() beforehand.
|
||||||
|
func (o *TenantUpdateZonesParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error {
|
||||||
|
var res []error
|
||||||
|
|
||||||
|
o.HTTPRequest = r
|
||||||
|
|
||||||
|
if runtime.HasBody(r) {
|
||||||
|
defer r.Body.Close()
|
||||||
|
var body models.ZoneUpdateRequest
|
||||||
|
if err := route.Consumer.Consume(r.Body, &body); err != nil {
|
||||||
|
if err == io.EOF {
|
||||||
|
res = append(res, errors.Required("body", "body", ""))
|
||||||
|
} else {
|
||||||
|
res = append(res, errors.NewParseError("body", "body", "", err))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// validate body object
|
||||||
|
if err := body.Validate(route.Formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(res) == 0 {
|
||||||
|
o.Body = &body
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
res = append(res, errors.Required("body", "body", ""))
|
||||||
|
}
|
||||||
|
rNamespace, rhkNamespace, _ := route.Params.GetOK("namespace")
|
||||||
|
if err := o.bindNamespace(rNamespace, rhkNamespace, route.Formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
rTenant, rhkTenant, _ := route.Params.GetOK("tenant")
|
||||||
|
if err := o.bindTenant(rTenant, rhkTenant, route.Formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(res) > 0 {
|
||||||
|
return errors.CompositeValidationError(res...)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// bindNamespace binds and validates parameter Namespace from path.
|
||||||
|
func (o *TenantUpdateZonesParams) bindNamespace(rawData []string, hasKey bool, formats strfmt.Registry) error {
|
||||||
|
var raw string
|
||||||
|
if len(rawData) > 0 {
|
||||||
|
raw = rawData[len(rawData)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Required: true
|
||||||
|
// Parameter is provided by construction from the route
|
||||||
|
|
||||||
|
o.Namespace = raw
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// bindTenant binds and validates parameter Tenant from path.
|
||||||
|
func (o *TenantUpdateZonesParams) bindTenant(rawData []string, hasKey bool, formats strfmt.Registry) error {
|
||||||
|
var raw string
|
||||||
|
if len(rawData) > 0 {
|
||||||
|
raw = rawData[len(rawData)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Required: true
|
||||||
|
// Parameter is provided by construction from the route
|
||||||
|
|
||||||
|
o.Tenant = raw
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
133
restapi/operations/admin_api/tenant_update_zones_responses.go
Normal file
133
restapi/operations/admin_api/tenant_update_zones_responses.go
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
// 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 admin_api
|
||||||
|
|
||||||
|
// This file was generated by the swagger tool.
|
||||||
|
// Editing this file might prove futile when you re-run the swagger generate command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/go-openapi/runtime"
|
||||||
|
|
||||||
|
"github.com/minio/console/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TenantUpdateZonesOKCode is the HTTP code returned for type TenantUpdateZonesOK
|
||||||
|
const TenantUpdateZonesOKCode int = 200
|
||||||
|
|
||||||
|
/*TenantUpdateZonesOK A successful response.
|
||||||
|
|
||||||
|
swagger:response tenantUpdateZonesOK
|
||||||
|
*/
|
||||||
|
type TenantUpdateZonesOK struct {
|
||||||
|
|
||||||
|
/*
|
||||||
|
In: Body
|
||||||
|
*/
|
||||||
|
Payload *models.Tenant `json:"body,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTenantUpdateZonesOK creates TenantUpdateZonesOK with default headers values
|
||||||
|
func NewTenantUpdateZonesOK() *TenantUpdateZonesOK {
|
||||||
|
|
||||||
|
return &TenantUpdateZonesOK{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithPayload adds the payload to the tenant update zones o k response
|
||||||
|
func (o *TenantUpdateZonesOK) WithPayload(payload *models.Tenant) *TenantUpdateZonesOK {
|
||||||
|
o.Payload = payload
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPayload sets the payload to the tenant update zones o k response
|
||||||
|
func (o *TenantUpdateZonesOK) SetPayload(payload *models.Tenant) {
|
||||||
|
o.Payload = payload
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteResponse to the client
|
||||||
|
func (o *TenantUpdateZonesOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
|
||||||
|
|
||||||
|
rw.WriteHeader(200)
|
||||||
|
if o.Payload != nil {
|
||||||
|
payload := o.Payload
|
||||||
|
if err := producer.Produce(rw, payload); err != nil {
|
||||||
|
panic(err) // let the recovery middleware deal with this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*TenantUpdateZonesDefault Generic error response.
|
||||||
|
|
||||||
|
swagger:response tenantUpdateZonesDefault
|
||||||
|
*/
|
||||||
|
type TenantUpdateZonesDefault struct {
|
||||||
|
_statusCode int
|
||||||
|
|
||||||
|
/*
|
||||||
|
In: Body
|
||||||
|
*/
|
||||||
|
Payload *models.Error `json:"body,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTenantUpdateZonesDefault creates TenantUpdateZonesDefault with default headers values
|
||||||
|
func NewTenantUpdateZonesDefault(code int) *TenantUpdateZonesDefault {
|
||||||
|
if code <= 0 {
|
||||||
|
code = 500
|
||||||
|
}
|
||||||
|
|
||||||
|
return &TenantUpdateZonesDefault{
|
||||||
|
_statusCode: code,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithStatusCode adds the status to the tenant update zones default response
|
||||||
|
func (o *TenantUpdateZonesDefault) WithStatusCode(code int) *TenantUpdateZonesDefault {
|
||||||
|
o._statusCode = code
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetStatusCode sets the status to the tenant update zones default response
|
||||||
|
func (o *TenantUpdateZonesDefault) SetStatusCode(code int) {
|
||||||
|
o._statusCode = code
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithPayload adds the payload to the tenant update zones default response
|
||||||
|
func (o *TenantUpdateZonesDefault) WithPayload(payload *models.Error) *TenantUpdateZonesDefault {
|
||||||
|
o.Payload = payload
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPayload sets the payload to the tenant update zones default response
|
||||||
|
func (o *TenantUpdateZonesDefault) SetPayload(payload *models.Error) {
|
||||||
|
o.Payload = payload
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteResponse to the client
|
||||||
|
func (o *TenantUpdateZonesDefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
|
||||||
|
|
||||||
|
rw.WriteHeader(o._statusCode)
|
||||||
|
if o.Payload != nil {
|
||||||
|
payload := o.Payload
|
||||||
|
if err := producer.Produce(rw, payload); err != nil {
|
||||||
|
panic(err) // let the recovery middleware deal with this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
124
restapi/operations/admin_api/tenant_update_zones_urlbuilder.go
Normal file
124
restapi/operations/admin_api/tenant_update_zones_urlbuilder.go
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
// 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 admin_api
|
||||||
|
|
||||||
|
// This file was generated by the swagger tool.
|
||||||
|
// Editing this file might prove futile when you re-run the generate command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"net/url"
|
||||||
|
golangswaggerpaths "path"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TenantUpdateZonesURL generates an URL for the tenant update zones operation
|
||||||
|
type TenantUpdateZonesURL struct {
|
||||||
|
Namespace string
|
||||||
|
Tenant string
|
||||||
|
|
||||||
|
_basePath string
|
||||||
|
// avoid unkeyed usage
|
||||||
|
_ struct{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithBasePath sets the base path for this url builder, only required when it's different from the
|
||||||
|
// base path specified in the swagger spec.
|
||||||
|
// When the value of the base path is an empty string
|
||||||
|
func (o *TenantUpdateZonesURL) WithBasePath(bp string) *TenantUpdateZonesURL {
|
||||||
|
o.SetBasePath(bp)
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetBasePath sets the base path for this url builder, only required when it's different from the
|
||||||
|
// base path specified in the swagger spec.
|
||||||
|
// When the value of the base path is an empty string
|
||||||
|
func (o *TenantUpdateZonesURL) SetBasePath(bp string) {
|
||||||
|
o._basePath = bp
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build a url path and query string
|
||||||
|
func (o *TenantUpdateZonesURL) Build() (*url.URL, error) {
|
||||||
|
var _result url.URL
|
||||||
|
|
||||||
|
var _path = "/namespaces/{namespace}/tenants/{tenant}/zones"
|
||||||
|
|
||||||
|
namespace := o.Namespace
|
||||||
|
if namespace != "" {
|
||||||
|
_path = strings.Replace(_path, "{namespace}", namespace, -1)
|
||||||
|
} else {
|
||||||
|
return nil, errors.New("namespace is required on TenantUpdateZonesURL")
|
||||||
|
}
|
||||||
|
|
||||||
|
tenant := o.Tenant
|
||||||
|
if tenant != "" {
|
||||||
|
_path = strings.Replace(_path, "{tenant}", tenant, -1)
|
||||||
|
} else {
|
||||||
|
return nil, errors.New("tenant is required on TenantUpdateZonesURL")
|
||||||
|
}
|
||||||
|
|
||||||
|
_basePath := o._basePath
|
||||||
|
if _basePath == "" {
|
||||||
|
_basePath = "/api/v1"
|
||||||
|
}
|
||||||
|
_result.Path = golangswaggerpaths.Join(_basePath, _path)
|
||||||
|
|
||||||
|
return &_result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Must is a helper function to panic when the url builder returns an error
|
||||||
|
func (o *TenantUpdateZonesURL) Must(u *url.URL, err error) *url.URL {
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if u == nil {
|
||||||
|
panic("url can't be nil")
|
||||||
|
}
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the string representation of the path with query string
|
||||||
|
func (o *TenantUpdateZonesURL) String() string {
|
||||||
|
return o.Must(o.Build()).String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// BuildFull builds a full url with scheme, host, path and query string
|
||||||
|
func (o *TenantUpdateZonesURL) BuildFull(scheme, host string) (*url.URL, error) {
|
||||||
|
if scheme == "" {
|
||||||
|
return nil, errors.New("scheme is required for a full url on TenantUpdateZonesURL")
|
||||||
|
}
|
||||||
|
if host == "" {
|
||||||
|
return nil, errors.New("host is required for a full url on TenantUpdateZonesURL")
|
||||||
|
}
|
||||||
|
|
||||||
|
base, err := o.Build()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
base.Scheme = scheme
|
||||||
|
base.Host = host
|
||||||
|
return base, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringFull returns the string representation of a complete url
|
||||||
|
func (o *TenantUpdateZonesURL) StringFull(scheme, host string) string {
|
||||||
|
return o.Must(o.BuildFull(scheme, host)).String()
|
||||||
|
}
|
||||||
@@ -114,6 +114,9 @@ func NewConsoleAPI(spec *loads.Document) *ConsoleAPI {
|
|||||||
AdminAPIDeleteTenantHandler: admin_api.DeleteTenantHandlerFunc(func(params admin_api.DeleteTenantParams, principal *models.Principal) middleware.Responder {
|
AdminAPIDeleteTenantHandler: admin_api.DeleteTenantHandlerFunc(func(params admin_api.DeleteTenantParams, principal *models.Principal) middleware.Responder {
|
||||||
return middleware.NotImplemented("operation admin_api.DeleteTenant has not yet been implemented")
|
return middleware.NotImplemented("operation admin_api.DeleteTenant has not yet been implemented")
|
||||||
}),
|
}),
|
||||||
|
AdminAPIGetMaxAllocatableMemHandler: admin_api.GetMaxAllocatableMemHandlerFunc(func(params admin_api.GetMaxAllocatableMemParams, principal *models.Principal) middleware.Responder {
|
||||||
|
return middleware.NotImplemented("operation admin_api.GetMaxAllocatableMem has not yet been implemented")
|
||||||
|
}),
|
||||||
AdminAPIGetResourceQuotaHandler: admin_api.GetResourceQuotaHandlerFunc(func(params admin_api.GetResourceQuotaParams, principal *models.Principal) middleware.Responder {
|
AdminAPIGetResourceQuotaHandler: admin_api.GetResourceQuotaHandlerFunc(func(params admin_api.GetResourceQuotaParams, principal *models.Principal) middleware.Responder {
|
||||||
return middleware.NotImplemented("operation admin_api.GetResourceQuota has not yet been implemented")
|
return middleware.NotImplemented("operation admin_api.GetResourceQuota has not yet been implemented")
|
||||||
}),
|
}),
|
||||||
@@ -210,6 +213,15 @@ func NewConsoleAPI(spec *loads.Document) *ConsoleAPI {
|
|||||||
AdminAPITenantInfoHandler: admin_api.TenantInfoHandlerFunc(func(params admin_api.TenantInfoParams, principal *models.Principal) middleware.Responder {
|
AdminAPITenantInfoHandler: admin_api.TenantInfoHandlerFunc(func(params admin_api.TenantInfoParams, principal *models.Principal) middleware.Responder {
|
||||||
return middleware.NotImplemented("operation admin_api.TenantInfo has not yet been implemented")
|
return middleware.NotImplemented("operation admin_api.TenantInfo has not yet been implemented")
|
||||||
}),
|
}),
|
||||||
|
AdminAPITenantUpdateCertificateHandler: admin_api.TenantUpdateCertificateHandlerFunc(func(params admin_api.TenantUpdateCertificateParams, principal *models.Principal) middleware.Responder {
|
||||||
|
return middleware.NotImplemented("operation admin_api.TenantUpdateCertificate has not yet been implemented")
|
||||||
|
}),
|
||||||
|
AdminAPITenantUpdateEncryptionHandler: admin_api.TenantUpdateEncryptionHandlerFunc(func(params admin_api.TenantUpdateEncryptionParams, principal *models.Principal) middleware.Responder {
|
||||||
|
return middleware.NotImplemented("operation admin_api.TenantUpdateEncryption has not yet been implemented")
|
||||||
|
}),
|
||||||
|
AdminAPITenantUpdateZonesHandler: admin_api.TenantUpdateZonesHandlerFunc(func(params admin_api.TenantUpdateZonesParams, principal *models.Principal) middleware.Responder {
|
||||||
|
return middleware.NotImplemented("operation admin_api.TenantUpdateZones has not yet been implemented")
|
||||||
|
}),
|
||||||
AdminAPIUpdateGroupHandler: admin_api.UpdateGroupHandlerFunc(func(params admin_api.UpdateGroupParams, principal *models.Principal) middleware.Responder {
|
AdminAPIUpdateGroupHandler: admin_api.UpdateGroupHandlerFunc(func(params admin_api.UpdateGroupParams, principal *models.Principal) middleware.Responder {
|
||||||
return middleware.NotImplemented("operation admin_api.UpdateGroup has not yet been implemented")
|
return middleware.NotImplemented("operation admin_api.UpdateGroup has not yet been implemented")
|
||||||
}),
|
}),
|
||||||
@@ -305,6 +317,8 @@ type ConsoleAPI struct {
|
|||||||
UserAPIDeleteServiceAccountHandler user_api.DeleteServiceAccountHandler
|
UserAPIDeleteServiceAccountHandler user_api.DeleteServiceAccountHandler
|
||||||
// AdminAPIDeleteTenantHandler sets the operation handler for the delete tenant operation
|
// AdminAPIDeleteTenantHandler sets the operation handler for the delete tenant operation
|
||||||
AdminAPIDeleteTenantHandler admin_api.DeleteTenantHandler
|
AdminAPIDeleteTenantHandler admin_api.DeleteTenantHandler
|
||||||
|
// AdminAPIGetMaxAllocatableMemHandler sets the operation handler for the get max allocatable mem operation
|
||||||
|
AdminAPIGetMaxAllocatableMemHandler admin_api.GetMaxAllocatableMemHandler
|
||||||
// AdminAPIGetResourceQuotaHandler sets the operation handler for the get resource quota operation
|
// AdminAPIGetResourceQuotaHandler sets the operation handler for the get resource quota operation
|
||||||
AdminAPIGetResourceQuotaHandler admin_api.GetResourceQuotaHandler
|
AdminAPIGetResourceQuotaHandler admin_api.GetResourceQuotaHandler
|
||||||
// AdminAPIGetTenantUsageHandler sets the operation handler for the get tenant usage operation
|
// AdminAPIGetTenantUsageHandler sets the operation handler for the get tenant usage operation
|
||||||
@@ -369,6 +383,12 @@ type ConsoleAPI struct {
|
|||||||
AdminAPITenantAddZoneHandler admin_api.TenantAddZoneHandler
|
AdminAPITenantAddZoneHandler admin_api.TenantAddZoneHandler
|
||||||
// AdminAPITenantInfoHandler sets the operation handler for the tenant info operation
|
// AdminAPITenantInfoHandler sets the operation handler for the tenant info operation
|
||||||
AdminAPITenantInfoHandler admin_api.TenantInfoHandler
|
AdminAPITenantInfoHandler admin_api.TenantInfoHandler
|
||||||
|
// AdminAPITenantUpdateCertificateHandler sets the operation handler for the tenant update certificate operation
|
||||||
|
AdminAPITenantUpdateCertificateHandler admin_api.TenantUpdateCertificateHandler
|
||||||
|
// AdminAPITenantUpdateEncryptionHandler sets the operation handler for the tenant update encryption operation
|
||||||
|
AdminAPITenantUpdateEncryptionHandler admin_api.TenantUpdateEncryptionHandler
|
||||||
|
// AdminAPITenantUpdateZonesHandler sets the operation handler for the tenant update zones operation
|
||||||
|
AdminAPITenantUpdateZonesHandler admin_api.TenantUpdateZonesHandler
|
||||||
// AdminAPIUpdateGroupHandler sets the operation handler for the update group operation
|
// AdminAPIUpdateGroupHandler sets the operation handler for the update group operation
|
||||||
AdminAPIUpdateGroupHandler admin_api.UpdateGroupHandler
|
AdminAPIUpdateGroupHandler admin_api.UpdateGroupHandler
|
||||||
// AdminAPIUpdateTenantHandler sets the operation handler for the update tenant operation
|
// AdminAPIUpdateTenantHandler sets the operation handler for the update tenant operation
|
||||||
@@ -501,6 +521,9 @@ func (o *ConsoleAPI) Validate() error {
|
|||||||
if o.AdminAPIDeleteTenantHandler == nil {
|
if o.AdminAPIDeleteTenantHandler == nil {
|
||||||
unregistered = append(unregistered, "admin_api.DeleteTenantHandler")
|
unregistered = append(unregistered, "admin_api.DeleteTenantHandler")
|
||||||
}
|
}
|
||||||
|
if o.AdminAPIGetMaxAllocatableMemHandler == nil {
|
||||||
|
unregistered = append(unregistered, "admin_api.GetMaxAllocatableMemHandler")
|
||||||
|
}
|
||||||
if o.AdminAPIGetResourceQuotaHandler == nil {
|
if o.AdminAPIGetResourceQuotaHandler == nil {
|
||||||
unregistered = append(unregistered, "admin_api.GetResourceQuotaHandler")
|
unregistered = append(unregistered, "admin_api.GetResourceQuotaHandler")
|
||||||
}
|
}
|
||||||
@@ -597,6 +620,15 @@ func (o *ConsoleAPI) Validate() error {
|
|||||||
if o.AdminAPITenantInfoHandler == nil {
|
if o.AdminAPITenantInfoHandler == nil {
|
||||||
unregistered = append(unregistered, "admin_api.TenantInfoHandler")
|
unregistered = append(unregistered, "admin_api.TenantInfoHandler")
|
||||||
}
|
}
|
||||||
|
if o.AdminAPITenantUpdateCertificateHandler == nil {
|
||||||
|
unregistered = append(unregistered, "admin_api.TenantUpdateCertificateHandler")
|
||||||
|
}
|
||||||
|
if o.AdminAPITenantUpdateEncryptionHandler == nil {
|
||||||
|
unregistered = append(unregistered, "admin_api.TenantUpdateEncryptionHandler")
|
||||||
|
}
|
||||||
|
if o.AdminAPITenantUpdateZonesHandler == nil {
|
||||||
|
unregistered = append(unregistered, "admin_api.TenantUpdateZonesHandler")
|
||||||
|
}
|
||||||
if o.AdminAPIUpdateGroupHandler == nil {
|
if o.AdminAPIUpdateGroupHandler == nil {
|
||||||
unregistered = append(unregistered, "admin_api.UpdateGroupHandler")
|
unregistered = append(unregistered, "admin_api.UpdateGroupHandler")
|
||||||
}
|
}
|
||||||
@@ -780,6 +812,10 @@ func (o *ConsoleAPI) initHandlerCache() {
|
|||||||
if o.handlers["GET"] == nil {
|
if o.handlers["GET"] == nil {
|
||||||
o.handlers["GET"] = make(map[string]http.Handler)
|
o.handlers["GET"] = make(map[string]http.Handler)
|
||||||
}
|
}
|
||||||
|
o.handlers["GET"]["/cluster/max-allocatable-memory"] = admin_api.NewGetMaxAllocatableMem(o.context, o.AdminAPIGetMaxAllocatableMemHandler)
|
||||||
|
if o.handlers["GET"] == nil {
|
||||||
|
o.handlers["GET"] = make(map[string]http.Handler)
|
||||||
|
}
|
||||||
o.handlers["GET"]["/namespaces/{namespace}/resourcequotas/{resource-quota-name}"] = admin_api.NewGetResourceQuota(o.context, o.AdminAPIGetResourceQuotaHandler)
|
o.handlers["GET"]["/namespaces/{namespace}/resourcequotas/{resource-quota-name}"] = admin_api.NewGetResourceQuota(o.context, o.AdminAPIGetResourceQuotaHandler)
|
||||||
if o.handlers["GET"] == nil {
|
if o.handlers["GET"] == nil {
|
||||||
o.handlers["GET"] = make(map[string]http.Handler)
|
o.handlers["GET"] = make(map[string]http.Handler)
|
||||||
@@ -908,6 +944,18 @@ func (o *ConsoleAPI) initHandlerCache() {
|
|||||||
if o.handlers["PUT"] == nil {
|
if o.handlers["PUT"] == nil {
|
||||||
o.handlers["PUT"] = make(map[string]http.Handler)
|
o.handlers["PUT"] = make(map[string]http.Handler)
|
||||||
}
|
}
|
||||||
|
o.handlers["PUT"]["/namespaces/{namespace}/tenants/{tenant}/certificates"] = admin_api.NewTenantUpdateCertificate(o.context, o.AdminAPITenantUpdateCertificateHandler)
|
||||||
|
if o.handlers["PUT"] == nil {
|
||||||
|
o.handlers["PUT"] = make(map[string]http.Handler)
|
||||||
|
}
|
||||||
|
o.handlers["PUT"]["/namespaces/{namespace}/tenants/{tenant}/encryption"] = admin_api.NewTenantUpdateEncryption(o.context, o.AdminAPITenantUpdateEncryptionHandler)
|
||||||
|
if o.handlers["PUT"] == nil {
|
||||||
|
o.handlers["PUT"] = make(map[string]http.Handler)
|
||||||
|
}
|
||||||
|
o.handlers["PUT"]["/namespaces/{namespace}/tenants/{tenant}/zones"] = admin_api.NewTenantUpdateZones(o.context, o.AdminAPITenantUpdateZonesHandler)
|
||||||
|
if o.handlers["PUT"] == nil {
|
||||||
|
o.handlers["PUT"] = make(map[string]http.Handler)
|
||||||
|
}
|
||||||
o.handlers["PUT"]["/groups/{name}"] = admin_api.NewUpdateGroup(o.context, o.AdminAPIUpdateGroupHandler)
|
o.handlers["PUT"]["/groups/{name}"] = admin_api.NewUpdateGroup(o.context, o.AdminAPIUpdateGroupHandler)
|
||||||
if o.handlers["PUT"] == nil {
|
if o.handlers["PUT"] == nil {
|
||||||
o.handlers["PUT"] = make(map[string]http.Handler)
|
o.handlers["PUT"] = make(map[string]http.Handler)
|
||||||
|
|||||||
@@ -25,10 +25,10 @@ import (
|
|||||||
types "k8s.io/apimachinery/pkg/types"
|
types "k8s.io/apimachinery/pkg/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// OperatorClient interface with all functions to be implemented
|
// OperatorClientI interface with all functions to be implemented
|
||||||
// by mock when testing, it should include all OperatorClient respective api calls
|
// by mock when testing, it should include all OperatorClientI respective api calls
|
||||||
// that are used within this project.
|
// that are used within this project.
|
||||||
type OperatorClient interface {
|
type OperatorClientI interface {
|
||||||
TenantDelete(ctx context.Context, namespace string, instanceName string, options metav1.DeleteOptions) error
|
TenantDelete(ctx context.Context, namespace string, instanceName string, options metav1.DeleteOptions) error
|
||||||
TenantGet(ctx context.Context, namespace string, instanceName string, options metav1.GetOptions) (*v1.Tenant, error)
|
TenantGet(ctx context.Context, namespace string, instanceName string, options metav1.GetOptions) (*v1.Tenant, error)
|
||||||
TenantPatch(ctx context.Context, namespace string, instanceName string, pt types.PatchType, data []byte, options metav1.PatchOptions) (*v1.Tenant, error)
|
TenantPatch(ctx context.Context, namespace string, instanceName string, pt types.PatchType, data []byte, options metav1.PatchOptions) (*v1.Tenant, error)
|
||||||
|
|||||||
@@ -18,12 +18,10 @@ package restapi
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"log"
|
|
||||||
|
|
||||||
"github.com/minio/console/cluster"
|
"github.com/minio/console/cluster"
|
||||||
|
|
||||||
"github.com/go-openapi/runtime/middleware"
|
"github.com/go-openapi/runtime/middleware"
|
||||||
"github.com/go-openapi/swag"
|
|
||||||
"github.com/minio/console/models"
|
"github.com/minio/console/models"
|
||||||
"github.com/minio/console/restapi/operations"
|
"github.com/minio/console/restapi/operations"
|
||||||
"github.com/minio/console/restapi/operations/admin_api"
|
"github.com/minio/console/restapi/operations/admin_api"
|
||||||
@@ -35,14 +33,14 @@ func registerResourceQuotaHandlers(api *operations.ConsoleAPI) {
|
|||||||
api.AdminAPIGetResourceQuotaHandler = admin_api.GetResourceQuotaHandlerFunc(func(params admin_api.GetResourceQuotaParams, session *models.Principal) middleware.Responder {
|
api.AdminAPIGetResourceQuotaHandler = admin_api.GetResourceQuotaHandlerFunc(func(params admin_api.GetResourceQuotaParams, session *models.Principal) middleware.Responder {
|
||||||
resp, err := getResourceQuotaResponse(session, params)
|
resp, err := getResourceQuotaResponse(session, params)
|
||||||
if err != nil {
|
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)
|
return admin_api.NewGetResourceQuotaOK().WithPayload(resp)
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func getResourceQuota(ctx context.Context, client K8sClient, namespace, resourcequota string) (*models.ResourceQuota, error) {
|
func getResourceQuota(ctx context.Context, client K8sClientI, namespace, resourcequota string) (*models.ResourceQuota, error) {
|
||||||
resourceQuota, err := client.getResourceQuota(ctx, namespace, resourcequota, metav1.GetOptions{})
|
resourceQuota, err := client.getResourceQuota(ctx, namespace, resourcequota, metav1.GetOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -68,20 +66,18 @@ func getResourceQuota(ctx context.Context, client K8sClient, namespace, resource
|
|||||||
return &rq, nil
|
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()
|
ctx := context.Background()
|
||||||
client, err := cluster.K8sClient(session.SessionToken)
|
client, err := cluster.K8sClient(session.SessionToken)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error getting k8sClient:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
k8sClient := &k8sClient{
|
k8sClient := &k8sClient{
|
||||||
client: client,
|
client: client,
|
||||||
}
|
}
|
||||||
resourceQuota, err := getResourceQuota(ctx, k8sClient, params.Namespace, params.ResourceQuotaName)
|
resourceQuota, err := getResourceQuota(ctx, k8sClient, params.Namespace, params.ResourceQuotaName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error getting resource quota:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return resourceQuota, nil
|
return resourceQuota, nil
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ func Test_ResourceQuota(t *testing.T) {
|
|||||||
kClient := k8sClientMock{}
|
kClient := k8sClientMock{}
|
||||||
type args struct {
|
type args struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
client K8sClient
|
client K8sClientI
|
||||||
}
|
}
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
|
|||||||
@@ -27,9 +27,14 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func getCertPool() *x509.CertPool {
|
func getCertPool() *x509.CertPool {
|
||||||
|
rootCAs, _ := x509.SystemCertPool()
|
||||||
|
if rootCAs == nil {
|
||||||
|
// In some systems (like Windows) system cert pool is
|
||||||
|
// not supported or no certificates are present on the
|
||||||
|
// system - so we create a new cert pool.
|
||||||
|
rootCAs = x509.NewCertPool()
|
||||||
|
}
|
||||||
caCertFileNames := getMinioServerTLSRootCAs()
|
caCertFileNames := getMinioServerTLSRootCAs()
|
||||||
// If CAs certificates are configured we save them to the http.Client RootCAs store
|
|
||||||
certs := x509.NewCertPool()
|
|
||||||
for _, caCert := range caCertFileNames {
|
for _, caCert := range caCertFileNames {
|
||||||
pemData, err := ioutil.ReadFile(caCert)
|
pemData, err := ioutil.ReadFile(caCert)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -37,9 +42,9 @@ func getCertPool() *x509.CertPool {
|
|||||||
log.Println(err)
|
log.Println(err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
certs.AppendCertsFromPEM(pemData)
|
rootCAs.AppendCertsFromPEM(pemData)
|
||||||
}
|
}
|
||||||
return certs
|
return rootCAs
|
||||||
}
|
}
|
||||||
|
|
||||||
var certPool = getCertPool()
|
var certPool = getCertPool()
|
||||||
|
|||||||
@@ -20,11 +20,9 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-openapi/errors"
|
|
||||||
"github.com/go-openapi/runtime/middleware"
|
"github.com/go-openapi/runtime/middleware"
|
||||||
"github.com/go-openapi/swag"
|
"github.com/go-openapi/swag"
|
||||||
"github.com/minio/console/models"
|
"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 {
|
api.UserAPIListBucketsHandler = user_api.ListBucketsHandlerFunc(func(params user_api.ListBucketsParams, session *models.Principal) middleware.Responder {
|
||||||
listBucketsResponse, err := getListBucketsResponse(session)
|
listBucketsResponse, err := getListBucketsResponse(session)
|
||||||
if err != nil {
|
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)
|
return user_api.NewListBucketsOK().WithPayload(listBucketsResponse)
|
||||||
})
|
})
|
||||||
// make bucket
|
// make bucket
|
||||||
api.UserAPIMakeBucketHandler = user_api.MakeBucketHandlerFunc(func(params user_api.MakeBucketParams, session *models.Principal) middleware.Responder {
|
api.UserAPIMakeBucketHandler = user_api.MakeBucketHandlerFunc(func(params user_api.MakeBucketParams, session *models.Principal) middleware.Responder {
|
||||||
if err := getMakeBucketResponse(session, params.Body); err != nil {
|
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()
|
return user_api.NewMakeBucketCreated()
|
||||||
})
|
})
|
||||||
// delete bucket
|
// delete bucket
|
||||||
api.UserAPIDeleteBucketHandler = user_api.DeleteBucketHandlerFunc(func(params user_api.DeleteBucketParams, session *models.Principal) middleware.Responder {
|
api.UserAPIDeleteBucketHandler = user_api.DeleteBucketHandlerFunc(func(params user_api.DeleteBucketParams, session *models.Principal) middleware.Responder {
|
||||||
if err := getDeleteBucketResponse(session, params); err != nil {
|
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()
|
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 {
|
api.UserAPIBucketInfoHandler = user_api.BucketInfoHandlerFunc(func(params user_api.BucketInfoParams, session *models.Principal) middleware.Responder {
|
||||||
bucketInfoResp, err := getBucketInfoResponse(session, params)
|
bucketInfoResp, err := getBucketInfoResponse(session, params)
|
||||||
if err != nil {
|
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)
|
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 {
|
api.UserAPIBucketSetPolicyHandler = user_api.BucketSetPolicyHandlerFunc(func(params user_api.BucketSetPolicyParams, session *models.Principal) middleware.Responder {
|
||||||
bucketSetPolicyResp, err := getBucketSetPolicyResponse(session, params.Name, params.Body)
|
bucketSetPolicyResp, err := getBucketSetPolicyResponse(session, params.Name, params.Body)
|
||||||
if err != nil {
|
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)
|
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
|
// 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)
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second*20)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
mAdmin, err := newMAdminClient(session)
|
mAdmin, err := newMAdminClient(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating Madmin Client:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
// create a minioClient interface implementation
|
// create a minioClient interface implementation
|
||||||
// defining the client to be used
|
// defining the client to be used
|
||||||
adminClient := adminClient{client: mAdmin}
|
adminClient := adminClient{client: mAdmin}
|
||||||
buckets, err := getaAcountUsageInfo(ctx, adminClient)
|
buckets, err := getaAcountUsageInfo(ctx, adminClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error accountingUsageInfo:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// serialize output
|
// 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
|
// 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)
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second*20)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
// bucket request needed to proceed
|
// bucket request needed to proceed
|
||||||
if br == nil {
|
if br == nil {
|
||||||
log.Println("error bucket body not in request")
|
return prepareError(errBucketBodyNotInRequest)
|
||||||
return errors.New(500, "error bucket body not in request")
|
|
||||||
}
|
}
|
||||||
mClient, err := newMinioClient(session)
|
mClient, err := newMinioClient(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating MinIO Client:", err)
|
return prepareError(err)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
// create a minioClient interface implementation
|
// create a minioClient interface implementation
|
||||||
// defining the client to be used
|
// defining the client to be used
|
||||||
minioClient := minioClient{client: mClient}
|
minioClient := minioClient{client: mClient}
|
||||||
|
|
||||||
if err := makeBucket(ctx, minioClient, *br.Name); err != nil {
|
if err := makeBucket(ctx, minioClient, *br.Name); err != nil {
|
||||||
log.Println("error making bucket:", err)
|
return prepareError(err)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
return nil
|
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
|
// getBucketSetPolicyResponse calls setBucketAccessPolicy() to set a access policy to a bucket
|
||||||
// and returns the serialized output.
|
// 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)
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second*20)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
mClient, err := newMinioClient(session)
|
mClient, err := newMinioClient(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating MinIO Client:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
// create a minioClient interface implementation
|
// create a minioClient interface implementation
|
||||||
// defining the client to be used
|
// defining the client to be used
|
||||||
@@ -197,14 +189,12 @@ func getBucketSetPolicyResponse(session *models.Principal, bucketName string, re
|
|||||||
|
|
||||||
// set bucket access policy
|
// set bucket access policy
|
||||||
if err := setBucketAccessPolicy(ctx, minioClient, bucketName, req.Access); err != nil {
|
if err := setBucketAccessPolicy(ctx, minioClient, bucketName, req.Access); err != nil {
|
||||||
log.Println("error setting bucket access policy:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
// get updated bucket details and return it
|
// get updated bucket details and return it
|
||||||
bucket, err := getBucketInfo(minioClient, bucketName)
|
bucket, err := getBucketInfo(minioClient, bucketName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error getting bucket's info:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
return bucket, nil
|
return bucket, nil
|
||||||
}
|
}
|
||||||
@@ -215,23 +205,23 @@ func removeBucket(client MinioClient, bucketName string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// getDeleteBucketResponse performs removeBucket() to delete a bucket
|
// 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 == "" {
|
if params.Name == "" {
|
||||||
log.Println("error bucket name not in request")
|
return prepareError(errBucketNameNotInRequest)
|
||||||
return errors.New(500, "error bucket name not in request")
|
|
||||||
}
|
}
|
||||||
bucketName := params.Name
|
bucketName := params.Name
|
||||||
|
|
||||||
mClient, err := newMinioClient(session)
|
mClient, err := newMinioClient(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating MinIO Client:", err)
|
return prepareError(err)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
// create a minioClient interface implementation
|
// create a minioClient interface implementation
|
||||||
// defining the client to be used
|
// defining the client to be used
|
||||||
minioClient := minioClient{client: mClient}
|
minioClient := minioClient{client: mClient}
|
||||||
|
if err := removeBucket(minioClient, bucketName); err != nil {
|
||||||
return removeBucket(minioClient, bucketName)
|
return prepareError(err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// getBucketInfo return bucket information including name, policy access, size and creation date
|
// 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
|
// 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)
|
mClient, err := newMinioClient(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating MinIO Client:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
// create a minioClient interface implementation
|
// create a minioClient interface implementation
|
||||||
// defining the client to be used
|
// 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)
|
bucket, err := getBucketInfo(minioClient, params.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error getting bucket's info:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
return bucket, nil
|
return bucket, nil
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ package restapi
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"log"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/go-openapi/runtime/middleware"
|
"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 {
|
api.UserAPIListBucketEventsHandler = user_api.ListBucketEventsHandlerFunc(func(params user_api.ListBucketEventsParams, session *models.Principal) middleware.Responder {
|
||||||
listBucketEventsResponse, err := getListBucketEventsResponse(session, params)
|
listBucketEventsResponse, err := getListBucketEventsResponse(session, params)
|
||||||
if err != nil {
|
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)
|
return user_api.NewListBucketEventsOK().WithPayload(listBucketEventsResponse)
|
||||||
})
|
})
|
||||||
// create bucket event
|
// create bucket event
|
||||||
api.UserAPICreateBucketEventHandler = user_api.CreateBucketEventHandlerFunc(func(params user_api.CreateBucketEventParams, session *models.Principal) middleware.Responder {
|
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 {
|
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()
|
return user_api.NewCreateBucketEventCreated()
|
||||||
})
|
})
|
||||||
// delete bucket event
|
// delete bucket event
|
||||||
api.UserAPIDeleteBucketEventHandler = user_api.DeleteBucketEventHandlerFunc(func(params user_api.DeleteBucketEventParams, session *models.Principal) middleware.Responder {
|
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 {
|
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()
|
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
|
// 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)
|
mClient, err := newMinioClient(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating MinIO Client:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
// create a minioClient interface implementation
|
// create a minioClient interface implementation
|
||||||
// defining the client to be used
|
// 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)
|
bucketEvents, err := listBucketEvents(minioClient, params.BucketName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error listing bucket events:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
// serialize output
|
// serialize output
|
||||||
listBucketsResponse := &models.ListBucketEventsResponse{
|
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
|
// 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()
|
ctx := context.Background()
|
||||||
s3Client, err := newS3BucketClient(session, bucketName)
|
s3Client, err := newS3BucketClient(session, bucketName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating S3Client:", err)
|
return prepareError(err)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
// create a mc S3Client interface implementation
|
// create a mc S3Client interface implementation
|
||||||
// defining the client to be used
|
// defining the client to be used
|
||||||
mcClient := mcClient{client: s3Client}
|
mcClient := mcClient{client: s3Client}
|
||||||
err = createBucketEvent(ctx, mcClient, *eventReq.Configuration.Arn, eventReq.Configuration.Events, eventReq.Configuration.Prefix, eventReq.Configuration.Suffix, eventReq.IgnoreExisting)
|
err = createBucketEvent(ctx, mcClient, *eventReq.Configuration.Arn, eventReq.Configuration.Events, eventReq.Configuration.Prefix, eventReq.Configuration.Suffix, eventReq.IgnoreExisting)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating bucket event:", err)
|
return prepareError(err)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -215,20 +210,18 @@ func joinNotificationEvents(events []models.NotificationEventType) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// getDeleteBucketEventsResponse calls deleteBucketEventNotification() to delete a bucket event notification
|
// 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()
|
ctx := context.Background()
|
||||||
s3Client, err := newS3BucketClient(session, bucketName)
|
s3Client, err := newS3BucketClient(session, bucketName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating S3Client:", err)
|
return prepareError(err)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
// create a mc S3Client interface implementation
|
// create a mc S3Client interface implementation
|
||||||
// defining the client to be used
|
// defining the client to be used
|
||||||
mcClient := mcClient{client: s3Client}
|
mcClient := mcClient{client: s3Client}
|
||||||
err = deleteBucketEventNotification(ctx, mcClient, arn, events, prefix, suffix)
|
err = deleteBucketEventNotification(ctx, mcClient, arn, events, prefix, suffix)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error deleting bucket event:", err)
|
return prepareError(err)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,11 +18,9 @@ package restapi
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/go-openapi/runtime/middleware"
|
"github.com/go-openapi/runtime/middleware"
|
||||||
"github.com/go-openapi/swag"
|
|
||||||
"github.com/minio/console/models"
|
"github.com/minio/console/models"
|
||||||
"github.com/minio/console/pkg/acl"
|
"github.com/minio/console/pkg/acl"
|
||||||
"github.com/minio/console/pkg/auth"
|
"github.com/minio/console/pkg/auth"
|
||||||
@@ -32,17 +30,12 @@ import (
|
|||||||
"github.com/minio/console/restapi/operations/user_api"
|
"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) {
|
func registerLoginHandlers(api *operations.ConsoleAPI) {
|
||||||
// get login strategy
|
// get login strategy
|
||||||
api.UserAPILoginDetailHandler = user_api.LoginDetailHandlerFunc(func(params user_api.LoginDetailParams) middleware.Responder {
|
api.UserAPILoginDetailHandler = user_api.LoginDetailHandlerFunc(func(params user_api.LoginDetailParams) middleware.Responder {
|
||||||
loginDetails, err := getLoginDetailsResponse()
|
loginDetails, err := getLoginDetailsResponse()
|
||||||
if err != nil {
|
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)
|
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 {
|
api.UserAPILoginHandler = user_api.LoginHandlerFunc(func(params user_api.LoginParams) middleware.Responder {
|
||||||
loginResponse, err := getLoginResponse(params.Body)
|
loginResponse, err := getLoginResponse(params.Body)
|
||||||
if err != nil {
|
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)
|
return user_api.NewLoginCreated().WithPayload(loginResponse)
|
||||||
})
|
})
|
||||||
api.UserAPILoginOauth2AuthHandler = user_api.LoginOauth2AuthHandlerFunc(func(params user_api.LoginOauth2AuthParams) middleware.Responder {
|
api.UserAPILoginOauth2AuthHandler = user_api.LoginOauth2AuthHandlerFunc(func(params user_api.LoginOauth2AuthParams) middleware.Responder {
|
||||||
loginResponse, err := getLoginOauth2AuthResponse(params.Body)
|
loginResponse, err := getLoginOauth2AuthResponse(params.Body)
|
||||||
if err != nil {
|
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)
|
return user_api.NewLoginOauth2AuthCreated().WithPayload(loginResponse)
|
||||||
})
|
})
|
||||||
api.UserAPILoginOperatorHandler = user_api.LoginOperatorHandlerFunc(func(params user_api.LoginOperatorParams) middleware.Responder {
|
api.UserAPILoginOperatorHandler = user_api.LoginOperatorHandlerFunc(func(params user_api.LoginOperatorParams) middleware.Responder {
|
||||||
loginResponse, err := getLoginOperatorResponse(params.Body)
|
loginResponse, err := getLoginOperatorResponse(params.Body)
|
||||||
if err != nil {
|
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)
|
return user_api.NewLoginOperatorCreated().WithPayload(loginResponse)
|
||||||
})
|
})
|
||||||
@@ -76,8 +69,7 @@ func login(credentials ConsoleCredentials, actions []string) (*string, error) {
|
|||||||
// try to obtain consoleCredentials,
|
// try to obtain consoleCredentials,
|
||||||
tokens, err := credentials.Get()
|
tokens, err := credentials.Get()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error authenticating user", err)
|
return nil, err
|
||||||
return nil, errInvalidCredentials
|
|
||||||
}
|
}
|
||||||
// if we made it here, the consoleCredentials work, generate a jwt with claims
|
// if we made it here, the consoleCredentials work, generate a jwt with claims
|
||||||
jwt, err := auth.NewEncryptedTokenForClient(&tokens, actions)
|
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
|
// 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()
|
ctx := context.Background()
|
||||||
mAdmin, err := newSuperMAdminClient()
|
mAdmin, err := newSuperMAdminClient()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating Madmin Client:", err)
|
return nil, prepareError(err)
|
||||||
return nil, errorGeneric
|
|
||||||
}
|
}
|
||||||
adminClient := adminClient{client: mAdmin}
|
adminClient := adminClient{client: mAdmin}
|
||||||
// obtain the configured MinIO region
|
// obtain the configured MinIO region
|
||||||
// need it for user authentication
|
// need it for user authentication
|
||||||
location, err := getConfiguredRegionForLogin(adminClient)
|
location, err := getConfiguredRegionForLogin(adminClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, prepareError(err)
|
||||||
}
|
}
|
||||||
creds, err := newConsoleCredentials(*lr.AccessKey, *lr.SecretKey, location)
|
creds, err := newConsoleCredentials(*lr.AccessKey, *lr.SecretKey, location)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error login:", err)
|
return nil, prepareError(err)
|
||||||
return nil, errInvalidCredentials
|
|
||||||
}
|
}
|
||||||
credentials := consoleCredentials{consoleCredentials: creds}
|
credentials := consoleCredentials{consoleCredentials: creds}
|
||||||
// obtain the current policy assigned to this user
|
// obtain the current policy assigned to this user
|
||||||
// necessary for generating the list of allowed endpoints
|
// necessary for generating the list of allowed endpoints
|
||||||
userInfo, err := adminClient.getUserInfo(ctx, *lr.AccessKey)
|
userInfo, err := adminClient.getUserInfo(ctx, *lr.AccessKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error login:", err)
|
return nil, prepareError(err)
|
||||||
return nil, errInvalidCredentials
|
|
||||||
}
|
}
|
||||||
policy, _ := adminClient.getPolicy(ctx, userInfo.PolicyName)
|
policy, _ := adminClient.getPolicy(ctx, userInfo.PolicyName)
|
||||||
// by default every user starts with an empty array of available actions
|
// 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)
|
sessionID, err := login(credentials, actions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, prepareError(errInvalidCredentials, nil, err)
|
||||||
}
|
}
|
||||||
// serialize output
|
// serialize output
|
||||||
loginResponse := &models.LoginResponse{
|
loginResponse := &models.LoginResponse{
|
||||||
@@ -151,7 +140,7 @@ func getLoginResponse(lr *models.LoginRequest) (*models.LoginResponse, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// getLoginDetailsResponse returns information regarding the Console authentication mechanism.
|
// getLoginDetailsResponse returns information regarding the Console authentication mechanism.
|
||||||
func getLoginDetailsResponse() (*models.LoginDetails, error) {
|
func getLoginDetailsResponse() (*models.LoginDetails, *models.Error) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
loginStrategy := models.LoginDetailsLoginStrategyForm
|
loginStrategy := models.LoginDetailsLoginStrategyForm
|
||||||
redirectURL := ""
|
redirectURL := ""
|
||||||
@@ -162,8 +151,7 @@ func getLoginDetailsResponse() (*models.LoginDetails, error) {
|
|||||||
// initialize new oauth2 client
|
// initialize new oauth2 client
|
||||||
oauth2Client, err := oauth2.NewOauth2ProviderClient(ctx, nil)
|
oauth2Client, err := oauth2.NewOauth2ProviderClient(ctx, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error getting new oauth2 provider client", err)
|
return nil, prepareError(err)
|
||||||
return nil, errorGeneric
|
|
||||||
}
|
}
|
||||||
// Validate user against IDP
|
// Validate user against IDP
|
||||||
identityProvider := &auth.IdentityProvider{Client: oauth2Client}
|
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)
|
userIdentity, err := provider.VerifyIdentity(ctx, code, state)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error validating user identity against idp:", err)
|
log.Println("error validating user identity against idp:", err)
|
||||||
return nil, errorGeneric
|
return nil, errInvalidCredentials
|
||||||
}
|
}
|
||||||
return userIdentity, nil
|
return userIdentity, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getLoginOauth2AuthResponse(lr *models.LoginOauth2AuthRequest) (*models.LoginResponse, error) {
|
func getLoginOauth2AuthResponse(lr *models.LoginOauth2AuthRequest) (*models.LoginResponse, *models.Error) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
if oauth2.IsIdpEnabled() {
|
if oauth2.IsIdpEnabled() {
|
||||||
// initialize new oauth2 client
|
// initialize new oauth2 client
|
||||||
oauth2Client, err := oauth2.NewOauth2ProviderClient(ctx, nil)
|
oauth2Client, err := oauth2.NewOauth2ProviderClient(ctx, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error getting new oauth2 client:", err)
|
return nil, prepareError(err)
|
||||||
return nil, errorGeneric
|
|
||||||
}
|
}
|
||||||
// initialize new identity provider
|
// initialize new identity provider
|
||||||
identityProvider := &auth.IdentityProvider{Client: oauth2Client}
|
identityProvider := &auth.IdentityProvider{Client: oauth2Client}
|
||||||
// Validate user against IDP
|
// Validate user against IDP
|
||||||
identity, err := loginOauth2Auth(ctx, identityProvider, *lr.Code, *lr.State)
|
identity, err := loginOauth2Auth(ctx, identityProvider, *lr.Code, *lr.State)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, prepareError(errInvalidCredentials, nil, err)
|
||||||
}
|
}
|
||||||
mAdmin, err := newSuperMAdminClient()
|
mAdmin, err := newSuperMAdminClient()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating Madmin Client:", err)
|
return nil, prepareError(err)
|
||||||
return nil, errorGeneric
|
|
||||||
}
|
}
|
||||||
adminClient := adminClient{client: mAdmin}
|
adminClient := adminClient{client: mAdmin}
|
||||||
accessKey := identity.Email
|
accessKey := identity.Email
|
||||||
@@ -213,12 +199,11 @@ func getLoginOauth2AuthResponse(lr *models.LoginOauth2AuthRequest) (*models.Logi
|
|||||||
// need it for user authentication
|
// need it for user authentication
|
||||||
location, err := getConfiguredRegionForLogin(adminClient)
|
location, err := getConfiguredRegionForLogin(adminClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, prepareError(err)
|
||||||
}
|
}
|
||||||
// create user in MinIO
|
// create user in MinIO
|
||||||
if _, err := addUser(ctx, adminClient, &accessKey, &secretKey, []string{}); err != nil {
|
if _, err := addUser(ctx, adminClient, &accessKey, &secretKey, []string{}); err != nil {
|
||||||
log.Println("error adding user:", err)
|
return nil, prepareError(err)
|
||||||
return nil, errorGeneric
|
|
||||||
}
|
}
|
||||||
// rollback user if there's an error after this point
|
// rollback user if there's an error after this point
|
||||||
defer func() {
|
defer func() {
|
||||||
@@ -231,26 +216,23 @@ func getLoginOauth2AuthResponse(lr *models.LoginOauth2AuthRequest) (*models.Logi
|
|||||||
// assign the "consoleAdmin" policy to this user
|
// assign the "consoleAdmin" policy to this user
|
||||||
policyName := oauth2.GetIDPPolicyForUser()
|
policyName := oauth2.GetIDPPolicyForUser()
|
||||||
if err := setPolicy(ctx, adminClient, policyName, accessKey, models.PolicyEntityUser); err != nil {
|
if err := setPolicy(ctx, adminClient, policyName, accessKey, models.PolicyEntityUser); err != nil {
|
||||||
log.Println("error setting policy:", err)
|
return nil, prepareError(err)
|
||||||
return nil, errorGeneric
|
|
||||||
}
|
}
|
||||||
// obtain the current policy details, necessary for generating the list of allowed endpoints
|
// obtain the current policy details, necessary for generating the list of allowed endpoints
|
||||||
policy, err := adminClient.getPolicy(ctx, policyName)
|
policy, err := adminClient.getPolicy(ctx, policyName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error reading policy:", err)
|
return nil, prepareError(err)
|
||||||
return nil, errorGeneric
|
|
||||||
}
|
}
|
||||||
actions := acl.GetActionsStringFromPolicy(policy)
|
actions := acl.GetActionsStringFromPolicy(policy)
|
||||||
// User was created correctly, create a new session/JWT
|
// User was created correctly, create a new session/JWT
|
||||||
creds, err := newConsoleCredentials(accessKey, secretKey, location)
|
creds, err := newConsoleCredentials(accessKey, secretKey, location)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error login:", err)
|
return nil, prepareError(err)
|
||||||
return nil, errorGeneric
|
|
||||||
}
|
}
|
||||||
credentials := consoleCredentials{consoleCredentials: creds}
|
credentials := consoleCredentials{consoleCredentials: creds}
|
||||||
jwt, err := login(credentials, actions)
|
jwt, err := login(credentials, actions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, prepareError(errInvalidCredentials, nil, err)
|
||||||
}
|
}
|
||||||
// serialize output
|
// serialize output
|
||||||
loginResponse := &models.LoginResponse{
|
loginResponse := &models.LoginResponse{
|
||||||
@@ -258,21 +240,20 @@ func getLoginOauth2AuthResponse(lr *models.LoginOauth2AuthRequest) (*models.Logi
|
|||||||
}
|
}
|
||||||
return loginResponse, nil
|
return loginResponse, nil
|
||||||
}
|
}
|
||||||
return nil, errorGeneric
|
return nil, prepareError(errorGeneric)
|
||||||
}
|
}
|
||||||
|
|
||||||
// getLoginOperatorResponse validate the provided service account token against k8s api
|
// 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, "")
|
creds, err := newConsoleCredentials("", *lmr.Jwt, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error login:", err)
|
return nil, prepareError(err)
|
||||||
return nil, errInvalidCredentials
|
|
||||||
}
|
}
|
||||||
credentials := consoleCredentials{consoleCredentials: creds}
|
credentials := consoleCredentials{consoleCredentials: creds}
|
||||||
var actions []string
|
var actions []string
|
||||||
jwt, err := login(credentials, actions)
|
jwt, err := login(credentials, actions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, prepareError(errInvalidCredentials, nil, err)
|
||||||
}
|
}
|
||||||
// serialize output
|
// serialize output
|
||||||
loginResponse := &models.LoginResponse{
|
loginResponse := &models.LoginResponse{
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ func TestLoginOauth2Auth(t *testing.T) {
|
|||||||
return nil, errors.New("error")
|
return nil, errors.New("error")
|
||||||
}
|
}
|
||||||
if _, err := loginOauth2Auth(ctx, identityProvider, mockCode, mockState); funcAssert.Error(err) {
|
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())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,12 +19,10 @@ package restapi
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"log"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-openapi/runtime/middleware"
|
"github.com/go-openapi/runtime/middleware"
|
||||||
"github.com/go-openapi/swag"
|
|
||||||
"github.com/minio/console/models"
|
"github.com/minio/console/models"
|
||||||
"github.com/minio/console/restapi/operations"
|
"github.com/minio/console/restapi/operations"
|
||||||
"github.com/minio/console/restapi/operations/user_api"
|
"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 {
|
api.UserAPICreateServiceAccountHandler = user_api.CreateServiceAccountHandlerFunc(func(params user_api.CreateServiceAccountParams, session *models.Principal) middleware.Responder {
|
||||||
creds, err := getCreateServiceAccountResponse(session, params.Body)
|
creds, err := getCreateServiceAccountResponse(session, params.Body)
|
||||||
if err != nil {
|
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)
|
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 {
|
api.UserAPIListUserServiceAccountsHandler = user_api.ListUserServiceAccountsHandlerFunc(func(params user_api.ListUserServiceAccountsParams, session *models.Principal) middleware.Responder {
|
||||||
serviceAccounts, err := getUserServiceAccountsResponse(session)
|
serviceAccounts, err := getUserServiceAccountsResponse(session)
|
||||||
if err != nil {
|
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)
|
return user_api.NewListUserServiceAccountsOK().WithPayload(serviceAccounts)
|
||||||
})
|
})
|
||||||
@@ -52,7 +50,7 @@ func registerServiceAccountsHandlers(api *operations.ConsoleAPI) {
|
|||||||
// Delete a User's service account
|
// Delete a User's service account
|
||||||
api.UserAPIDeleteServiceAccountHandler = user_api.DeleteServiceAccountHandlerFunc(func(params user_api.DeleteServiceAccountParams, session *models.Principal) middleware.Responder {
|
api.UserAPIDeleteServiceAccountHandler = user_api.DeleteServiceAccountHandlerFunc(func(params user_api.DeleteServiceAccountParams, session *models.Principal) middleware.Responder {
|
||||||
if err := getDeleteServiceAccountResponse(session, params.AccessKey); err != nil {
|
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()
|
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
|
// 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
|
// 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
|
// 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)
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second*20)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
userAdmin, err := newMAdminClient(session)
|
userAdmin, err := newMAdminClient(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating user Client:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
// create a MinIO user Admin Client interface implementation
|
// create a MinIO user Admin Client interface implementation
|
||||||
// defining the client to be used
|
// defining the client to be used
|
||||||
@@ -94,8 +91,7 @@ func getCreateServiceAccountResponse(session *models.Principal, serviceAccount *
|
|||||||
|
|
||||||
saCreds, err := createServiceAccount(ctx, userAdminClient, serviceAccount.Policy)
|
saCreds, err := createServiceAccount(ctx, userAdminClient, serviceAccount.Policy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating service account:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
return saCreds, nil
|
return saCreds, nil
|
||||||
}
|
}
|
||||||
@@ -115,14 +111,13 @@ func getUserServiceAccounts(ctx context.Context, userClient MinioAdmin) (models.
|
|||||||
|
|
||||||
// getUserServiceAccountsResponse authenticates the user and calls
|
// getUserServiceAccountsResponse authenticates the user and calls
|
||||||
// getUserServiceAccounts to list the user's service accounts
|
// 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)
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second*20)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
userAdmin, err := newMAdminClient(session)
|
userAdmin, err := newMAdminClient(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating user Client:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
// create a MinIO user Admin Client interface implementation
|
// create a MinIO user Admin Client interface implementation
|
||||||
// defining the client to be used
|
// defining the client to be used
|
||||||
@@ -130,11 +125,9 @@ func getUserServiceAccountsResponse(session *models.Principal) (models.ServiceAc
|
|||||||
|
|
||||||
serviceAccounts, err := getUserServiceAccounts(ctx, userAdminClient)
|
serviceAccounts, err := getUserServiceAccounts(ctx, userAdminClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error listing user's service account:", err)
|
return nil, prepareError(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
return serviceAccounts, nil
|
return serviceAccounts, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// deleteServiceAccount calls delete service account api
|
// 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
|
// 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)
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second*20)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
userAdmin, err := newMAdminClient(session)
|
userAdmin, err := newMAdminClient(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("error creating user Client:", err)
|
return prepareError(err)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
// create a MinIO user Admin Client interface implementation
|
// create a MinIO user Admin Client interface implementation
|
||||||
// defining the client to be used
|
// defining the client to be used
|
||||||
userAdminClient := adminClient{client: userAdmin}
|
userAdminClient := adminClient{client: userAdmin}
|
||||||
|
|
||||||
if err := deleteServiceAccount(ctx, userAdminClient, accessKey); err != nil {
|
if err := deleteServiceAccount(ctx, userAdminClient, accessKey); err != nil {
|
||||||
log.Println("error deleting user's service account:", err)
|
return prepareError(err)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,36 +17,29 @@
|
|||||||
package restapi
|
package restapi
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
|
|
||||||
"github.com/go-openapi/runtime/middleware"
|
"github.com/go-openapi/runtime/middleware"
|
||||||
"github.com/go-openapi/swag"
|
|
||||||
"github.com/minio/console/models"
|
"github.com/minio/console/models"
|
||||||
"github.com/minio/console/pkg/acl"
|
"github.com/minio/console/pkg/acl"
|
||||||
"github.com/minio/console/restapi/operations"
|
"github.com/minio/console/restapi/operations"
|
||||||
"github.com/minio/console/restapi/operations/user_api"
|
"github.com/minio/console/restapi/operations/user_api"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
errorGenericInvalidSession = errors.New("invalid session")
|
|
||||||
)
|
|
||||||
|
|
||||||
func registerSessionHandlers(api *operations.ConsoleAPI) {
|
func registerSessionHandlers(api *operations.ConsoleAPI) {
|
||||||
// session check
|
// session check
|
||||||
api.UserAPISessionCheckHandler = user_api.SessionCheckHandlerFunc(func(params user_api.SessionCheckParams, session *models.Principal) middleware.Responder {
|
api.UserAPISessionCheckHandler = user_api.SessionCheckHandlerFunc(func(params user_api.SessionCheckParams, session *models.Principal) middleware.Responder {
|
||||||
sessionResp, err := getSessionResponse(session)
|
sessionResp, err := getSessionResponse(session)
|
||||||
if err != nil {
|
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)
|
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
|
// 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
|
// serialize output
|
||||||
if session == nil {
|
if session == nil {
|
||||||
return nil, errorGenericInvalidSession
|
return nil, prepareError(errorGenericInvalidSession)
|
||||||
}
|
}
|
||||||
sessionResp := &models.SessionResponse{
|
sessionResp := &models.SessionResponse{
|
||||||
Pages: acl.GetAuthorizedEndpoints(session.Actions),
|
Pages: acl.GetAuthorizedEndpoints(session.Actions),
|
||||||
|
|||||||
134
swagger.yml
134
swagger.yml
@@ -1148,6 +1148,34 @@ paths:
|
|||||||
$ref: "#/definitions/error"
|
$ref: "#/definitions/error"
|
||||||
tags:
|
tags:
|
||||||
- AdminAPI
|
- AdminAPI
|
||||||
|
put:
|
||||||
|
summary: Tenant Update Zones
|
||||||
|
operationId: TenantUpdateZones
|
||||||
|
parameters:
|
||||||
|
- name: namespace
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
- name: tenant
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
- name: body
|
||||||
|
in: body
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: "#/definitions/zoneUpdateRequest"
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: A successful response.
|
||||||
|
schema:
|
||||||
|
$ref: "#/definitions/tenant"
|
||||||
|
default:
|
||||||
|
description: Generic error response.
|
||||||
|
schema:
|
||||||
|
$ref: "#/definitions/error"
|
||||||
|
tags:
|
||||||
|
- AdminAPI
|
||||||
|
|
||||||
/namespaces/{namespace}/tenants/{tenant}/usage:
|
/namespaces/{namespace}/tenants/{tenant}/usage:
|
||||||
get:
|
get:
|
||||||
@@ -1174,6 +1202,62 @@ paths:
|
|||||||
tags:
|
tags:
|
||||||
- AdminAPI
|
- AdminAPI
|
||||||
|
|
||||||
|
/namespaces/{namespace}/tenants/{tenant}/certificates:
|
||||||
|
put:
|
||||||
|
summary: Tenant Update Certificates
|
||||||
|
operationId: TenantUpdateCertificate
|
||||||
|
parameters:
|
||||||
|
- name: namespace
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
- name: tenant
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
- name: body
|
||||||
|
in: body
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: "#/definitions/tlsConfiguration"
|
||||||
|
responses:
|
||||||
|
201:
|
||||||
|
description: A successful response.
|
||||||
|
default:
|
||||||
|
description: Generic error response.
|
||||||
|
schema:
|
||||||
|
$ref: "#/definitions/error"
|
||||||
|
tags:
|
||||||
|
- AdminAPI
|
||||||
|
|
||||||
|
/namespaces/{namespace}/tenants/{tenant}/encryption:
|
||||||
|
put:
|
||||||
|
summary: Tenant Update Encryption
|
||||||
|
operationId: TenantUpdateEncryption
|
||||||
|
parameters:
|
||||||
|
- name: namespace
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
- name: tenant
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
- name: body
|
||||||
|
in: body
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: "#/definitions/encryptionConfiguration"
|
||||||
|
responses:
|
||||||
|
201:
|
||||||
|
description: A successful response.
|
||||||
|
default:
|
||||||
|
description: Generic error response.
|
||||||
|
schema:
|
||||||
|
$ref: "#/definitions/error"
|
||||||
|
tags:
|
||||||
|
- AdminAPI
|
||||||
|
|
||||||
/namespaces/{namespace}/resourcequotas/{resource-quota-name}:
|
/namespaces/{namespace}/resourcequotas/{resource-quota-name}:
|
||||||
get:
|
get:
|
||||||
summary: Get Resource Quota
|
summary: Get Resource Quota
|
||||||
@@ -1198,6 +1282,29 @@ paths:
|
|||||||
$ref: "#/definitions/error"
|
$ref: "#/definitions/error"
|
||||||
tags:
|
tags:
|
||||||
- AdminAPI
|
- AdminAPI
|
||||||
|
|
||||||
|
/cluster/max-allocatable-memory:
|
||||||
|
get:
|
||||||
|
summary: Get maximum allocatable memory for given number of nodes
|
||||||
|
operationId: GetMaxAllocatableMem
|
||||||
|
parameters:
|
||||||
|
- name: num_nodes
|
||||||
|
in: query
|
||||||
|
required: true
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
minimum: 1
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: A successful response.
|
||||||
|
schema:
|
||||||
|
$ref: "#/definitions/maxAllocatableMemResponse"
|
||||||
|
default:
|
||||||
|
description: Generic error response.
|
||||||
|
schema:
|
||||||
|
$ref: "#/definitions/error"
|
||||||
|
tags:
|
||||||
|
- AdminAPI
|
||||||
|
|
||||||
definitions:
|
definitions:
|
||||||
bucketAccess:
|
bucketAccess:
|
||||||
@@ -1248,7 +1355,7 @@ definitions:
|
|||||||
properties:
|
properties:
|
||||||
code:
|
code:
|
||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int32
|
||||||
message:
|
message:
|
||||||
type: string
|
type: string
|
||||||
user:
|
user:
|
||||||
@@ -1764,6 +1871,7 @@ definitions:
|
|||||||
type: string
|
type: string
|
||||||
namespace:
|
namespace:
|
||||||
type: string
|
type: string
|
||||||
|
|
||||||
listTenantsResponse:
|
listTenantsResponse:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
@@ -1837,6 +1945,9 @@ definitions:
|
|||||||
enable_tls:
|
enable_tls:
|
||||||
type: boolean
|
type: boolean
|
||||||
default: true
|
default: true
|
||||||
|
enable_prometheus:
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
namespace:
|
namespace:
|
||||||
type: string
|
type: string
|
||||||
erasureCodingParity:
|
erasureCodingParity:
|
||||||
@@ -2088,6 +2199,10 @@ definitions:
|
|||||||
type: integer
|
type: integer
|
||||||
storage_class_name:
|
storage_class_name:
|
||||||
type: string
|
type: string
|
||||||
|
labels:
|
||||||
|
type: object
|
||||||
|
additionalProperties:
|
||||||
|
type: string
|
||||||
resources:
|
resources:
|
||||||
$ref: "#/definitions/zoneResources"
|
$ref: "#/definitions/zoneResources"
|
||||||
node_selector:
|
node_selector:
|
||||||
@@ -2527,3 +2642,20 @@ definitions:
|
|||||||
properties:
|
properties:
|
||||||
delete_pvcs:
|
delete_pvcs:
|
||||||
type: boolean
|
type: boolean
|
||||||
|
|
||||||
|
zoneUpdateRequest:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- zones
|
||||||
|
properties:
|
||||||
|
zones:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: "#/definitions/zone"
|
||||||
|
|
||||||
|
maxAllocatableMemResponse:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
max_memory:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
|||||||
Reference in New Issue
Block a user