Add support for edit/add/remove environment variables to MinIO tenant (#2331)
 Signed-off-by: Lenin Alevski <alevsk.8772@gmail.com> Signed-off-by: Lenin Alevski <alevsk.8772@gmail.com>
This commit is contained in:
133
models/tenant_configuration_response.go
Normal file
133
models/tenant_configuration_response.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) 2022 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 (
|
||||
"context"
|
||||
"strconv"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// TenantConfigurationResponse tenant configuration response
|
||||
//
|
||||
// swagger:model tenantConfigurationResponse
|
||||
type TenantConfigurationResponse struct {
|
||||
|
||||
// environment variables
|
||||
EnvironmentVariables []*EnvironmentVariable `json:"environmentVariables"`
|
||||
}
|
||||
|
||||
// Validate validates this tenant configuration response
|
||||
func (m *TenantConfigurationResponse) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateEnvironmentVariables(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *TenantConfigurationResponse) validateEnvironmentVariables(formats strfmt.Registry) error {
|
||||
if swag.IsZero(m.EnvironmentVariables) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
for i := 0; i < len(m.EnvironmentVariables); i++ {
|
||||
if swag.IsZero(m.EnvironmentVariables[i]) { // not required
|
||||
continue
|
||||
}
|
||||
|
||||
if m.EnvironmentVariables[i] != nil {
|
||||
if err := m.EnvironmentVariables[i].Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("environmentVariables" + "." + strconv.Itoa(i))
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("environmentVariables" + "." + strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validate this tenant configuration response based on the context it is used
|
||||
func (m *TenantConfigurationResponse) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.contextValidateEnvironmentVariables(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *TenantConfigurationResponse) contextValidateEnvironmentVariables(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
for i := 0; i < len(m.EnvironmentVariables); i++ {
|
||||
|
||||
if m.EnvironmentVariables[i] != nil {
|
||||
if err := m.EnvironmentVariables[i].ContextValidate(ctx, formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("environmentVariables" + "." + strconv.Itoa(i))
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("environmentVariables" + "." + strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *TenantConfigurationResponse) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *TenantConfigurationResponse) UnmarshalBinary(b []byte) error {
|
||||
var res TenantConfigurationResponse
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
136
models/update_tenant_configuration_request.go
Normal file
136
models/update_tenant_configuration_request.go
Normal file
@@ -0,0 +1,136 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2022 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 (
|
||||
"context"
|
||||
"strconv"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// UpdateTenantConfigurationRequest update tenant configuration request
|
||||
//
|
||||
// swagger:model updateTenantConfigurationRequest
|
||||
type UpdateTenantConfigurationRequest struct {
|
||||
|
||||
// environment variables
|
||||
EnvironmentVariables []*EnvironmentVariable `json:"environmentVariables"`
|
||||
|
||||
// keys to be deleted
|
||||
KeysToBeDeleted []string `json:"keysToBeDeleted"`
|
||||
}
|
||||
|
||||
// Validate validates this update tenant configuration request
|
||||
func (m *UpdateTenantConfigurationRequest) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateEnvironmentVariables(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *UpdateTenantConfigurationRequest) validateEnvironmentVariables(formats strfmt.Registry) error {
|
||||
if swag.IsZero(m.EnvironmentVariables) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
for i := 0; i < len(m.EnvironmentVariables); i++ {
|
||||
if swag.IsZero(m.EnvironmentVariables[i]) { // not required
|
||||
continue
|
||||
}
|
||||
|
||||
if m.EnvironmentVariables[i] != nil {
|
||||
if err := m.EnvironmentVariables[i].Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("environmentVariables" + "." + strconv.Itoa(i))
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("environmentVariables" + "." + strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validate this update tenant configuration request based on the context it is used
|
||||
func (m *UpdateTenantConfigurationRequest) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.contextValidateEnvironmentVariables(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *UpdateTenantConfigurationRequest) contextValidateEnvironmentVariables(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
for i := 0; i < len(m.EnvironmentVariables); i++ {
|
||||
|
||||
if m.EnvironmentVariables[i] != nil {
|
||||
if err := m.EnvironmentVariables[i].ContextValidate(ctx, formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("environmentVariables" + "." + strconv.Itoa(i))
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("environmentVariables" + "." + strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *UpdateTenantConfigurationRequest) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *UpdateTenantConfigurationRequest) UnmarshalBinary(b []byte) error {
|
||||
var res UpdateTenantConfigurationRequest
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
@@ -742,6 +742,83 @@ func init() {
|
||||
}
|
||||
}
|
||||
},
|
||||
"/namespaces/{namespace}/tenants/{tenant}/configuration": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"OperatorAPI"
|
||||
],
|
||||
"summary": "Tenant Configuration",
|
||||
"operationId": "TenantConfiguration",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"name": "namespace",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "tenant",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/tenantConfigurationResponse"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "Generic error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/error"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"patch": {
|
||||
"tags": [
|
||||
"OperatorAPI"
|
||||
],
|
||||
"summary": "Update Tenant Configuration",
|
||||
"operationId": "UpdateTenantConfiguration",
|
||||
"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/updateTenantConfigurationRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"204": {
|
||||
"description": "A successful response."
|
||||
},
|
||||
"default": {
|
||||
"description": "Generic error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/error"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/namespaces/{namespace}/tenants/{tenant}/csr": {
|
||||
"get": {
|
||||
"tags": [
|
||||
@@ -4514,6 +4591,17 @@ func init() {
|
||||
}
|
||||
}
|
||||
},
|
||||
"tenantConfigurationResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"environmentVariables": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/environmentVariable"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tenantList": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -4921,6 +5009,23 @@ func init() {
|
||||
}
|
||||
}
|
||||
},
|
||||
"updateTenantConfigurationRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"environmentVariables": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/environmentVariable"
|
||||
}
|
||||
},
|
||||
"keysToBeDeleted": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"updateTenantRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -5848,6 +5953,83 @@ func init() {
|
||||
}
|
||||
}
|
||||
},
|
||||
"/namespaces/{namespace}/tenants/{tenant}/configuration": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"OperatorAPI"
|
||||
],
|
||||
"summary": "Tenant Configuration",
|
||||
"operationId": "TenantConfiguration",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"name": "namespace",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "tenant",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/tenantConfigurationResponse"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "Generic error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/error"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"patch": {
|
||||
"tags": [
|
||||
"OperatorAPI"
|
||||
],
|
||||
"summary": "Update Tenant Configuration",
|
||||
"operationId": "UpdateTenantConfiguration",
|
||||
"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/updateTenantConfigurationRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"204": {
|
||||
"description": "A successful response."
|
||||
},
|
||||
"default": {
|
||||
"description": "Generic error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/error"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/namespaces/{namespace}/tenants/{tenant}/csr": {
|
||||
"get": {
|
||||
"tags": [
|
||||
@@ -10328,6 +10510,17 @@ func init() {
|
||||
}
|
||||
}
|
||||
},
|
||||
"tenantConfigurationResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"environmentVariables": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/environmentVariable"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tenantList": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -10735,6 +10928,23 @@ func init() {
|
||||
}
|
||||
}
|
||||
},
|
||||
"updateTenantConfigurationRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"environmentVariables": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/environmentVariable"
|
||||
}
|
||||
},
|
||||
"keysToBeDeleted": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"updateTenantRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
||||
@@ -223,6 +223,9 @@ func NewOperatorAPI(spec *loads.Document) *OperatorAPI {
|
||||
OperatorAPITenantAddPoolHandler: operator_api.TenantAddPoolHandlerFunc(func(params operator_api.TenantAddPoolParams, principal *models.Principal) middleware.Responder {
|
||||
return middleware.NotImplemented("operation operator_api.TenantAddPool has not yet been implemented")
|
||||
}),
|
||||
OperatorAPITenantConfigurationHandler: operator_api.TenantConfigurationHandlerFunc(func(params operator_api.TenantConfigurationParams, principal *models.Principal) middleware.Responder {
|
||||
return middleware.NotImplemented("operation operator_api.TenantConfiguration has not yet been implemented")
|
||||
}),
|
||||
OperatorAPITenantDeleteEncryptionHandler: operator_api.TenantDeleteEncryptionHandlerFunc(func(params operator_api.TenantDeleteEncryptionParams, principal *models.Principal) middleware.Responder {
|
||||
return middleware.NotImplemented("operation operator_api.TenantDeleteEncryption has not yet been implemented")
|
||||
}),
|
||||
@@ -250,6 +253,9 @@ func NewOperatorAPI(spec *loads.Document) *OperatorAPI {
|
||||
OperatorAPIUpdateTenantHandler: operator_api.UpdateTenantHandlerFunc(func(params operator_api.UpdateTenantParams, principal *models.Principal) middleware.Responder {
|
||||
return middleware.NotImplemented("operation operator_api.UpdateTenant has not yet been implemented")
|
||||
}),
|
||||
OperatorAPIUpdateTenantConfigurationHandler: operator_api.UpdateTenantConfigurationHandlerFunc(func(params operator_api.UpdateTenantConfigurationParams, principal *models.Principal) middleware.Responder {
|
||||
return middleware.NotImplemented("operation operator_api.UpdateTenantConfiguration has not yet been implemented")
|
||||
}),
|
||||
OperatorAPIUpdateTenantDomainsHandler: operator_api.UpdateTenantDomainsHandlerFunc(func(params operator_api.UpdateTenantDomainsParams, principal *models.Principal) middleware.Responder {
|
||||
return middleware.NotImplemented("operation operator_api.UpdateTenantDomains has not yet been implemented")
|
||||
}),
|
||||
@@ -414,6 +420,8 @@ type OperatorAPI struct {
|
||||
OperatorAPISubscriptionValidateHandler operator_api.SubscriptionValidateHandler
|
||||
// OperatorAPITenantAddPoolHandler sets the operation handler for the tenant add pool operation
|
||||
OperatorAPITenantAddPoolHandler operator_api.TenantAddPoolHandler
|
||||
// OperatorAPITenantConfigurationHandler sets the operation handler for the tenant configuration operation
|
||||
OperatorAPITenantConfigurationHandler operator_api.TenantConfigurationHandler
|
||||
// OperatorAPITenantDeleteEncryptionHandler sets the operation handler for the tenant delete encryption operation
|
||||
OperatorAPITenantDeleteEncryptionHandler operator_api.TenantDeleteEncryptionHandler
|
||||
// OperatorAPITenantDetailsHandler sets the operation handler for the tenant details operation
|
||||
@@ -432,6 +440,8 @@ type OperatorAPI struct {
|
||||
OperatorAPITenantUpdatePoolsHandler operator_api.TenantUpdatePoolsHandler
|
||||
// OperatorAPIUpdateTenantHandler sets the operation handler for the update tenant operation
|
||||
OperatorAPIUpdateTenantHandler operator_api.UpdateTenantHandler
|
||||
// OperatorAPIUpdateTenantConfigurationHandler sets the operation handler for the update tenant configuration operation
|
||||
OperatorAPIUpdateTenantConfigurationHandler operator_api.UpdateTenantConfigurationHandler
|
||||
// OperatorAPIUpdateTenantDomainsHandler sets the operation handler for the update tenant domains operation
|
||||
OperatorAPIUpdateTenantDomainsHandler operator_api.UpdateTenantDomainsHandler
|
||||
// OperatorAPIUpdateTenantIdentityProviderHandler sets the operation handler for the update tenant identity provider operation
|
||||
@@ -678,6 +688,9 @@ func (o *OperatorAPI) Validate() error {
|
||||
if o.OperatorAPITenantAddPoolHandler == nil {
|
||||
unregistered = append(unregistered, "operator_api.TenantAddPoolHandler")
|
||||
}
|
||||
if o.OperatorAPITenantConfigurationHandler == nil {
|
||||
unregistered = append(unregistered, "operator_api.TenantConfigurationHandler")
|
||||
}
|
||||
if o.OperatorAPITenantDeleteEncryptionHandler == nil {
|
||||
unregistered = append(unregistered, "operator_api.TenantDeleteEncryptionHandler")
|
||||
}
|
||||
@@ -705,6 +718,9 @@ func (o *OperatorAPI) Validate() error {
|
||||
if o.OperatorAPIUpdateTenantHandler == nil {
|
||||
unregistered = append(unregistered, "operator_api.UpdateTenantHandler")
|
||||
}
|
||||
if o.OperatorAPIUpdateTenantConfigurationHandler == nil {
|
||||
unregistered = append(unregistered, "operator_api.UpdateTenantConfigurationHandler")
|
||||
}
|
||||
if o.OperatorAPIUpdateTenantDomainsHandler == nil {
|
||||
unregistered = append(unregistered, "operator_api.UpdateTenantDomainsHandler")
|
||||
}
|
||||
@@ -1024,6 +1040,10 @@ func (o *OperatorAPI) initHandlerCache() {
|
||||
o.handlers["POST"] = make(map[string]http.Handler)
|
||||
}
|
||||
o.handlers["POST"]["/namespaces/{namespace}/tenants/{tenant}/pools"] = operator_api.NewTenantAddPool(o.context, o.OperatorAPITenantAddPoolHandler)
|
||||
if o.handlers["GET"] == nil {
|
||||
o.handlers["GET"] = make(map[string]http.Handler)
|
||||
}
|
||||
o.handlers["GET"]["/namespaces/{namespace}/tenants/{tenant}/configuration"] = operator_api.NewTenantConfiguration(o.context, o.OperatorAPITenantConfigurationHandler)
|
||||
if o.handlers["DELETE"] == nil {
|
||||
o.handlers["DELETE"] = make(map[string]http.Handler)
|
||||
}
|
||||
@@ -1060,6 +1080,10 @@ func (o *OperatorAPI) initHandlerCache() {
|
||||
o.handlers["PUT"] = make(map[string]http.Handler)
|
||||
}
|
||||
o.handlers["PUT"]["/namespaces/{namespace}/tenants/{tenant}"] = operator_api.NewUpdateTenant(o.context, o.OperatorAPIUpdateTenantHandler)
|
||||
if o.handlers["PATCH"] == nil {
|
||||
o.handlers["PATCH"] = make(map[string]http.Handler)
|
||||
}
|
||||
o.handlers["PATCH"]["/namespaces/{namespace}/tenants/{tenant}/configuration"] = operator_api.NewUpdateTenantConfiguration(o.context, o.OperatorAPIUpdateTenantConfigurationHandler)
|
||||
if o.handlers["PUT"] == nil {
|
||||
o.handlers["PUT"] = make(map[string]http.Handler)
|
||||
}
|
||||
|
||||
88
operatorapi/operations/operator_api/tenant_configuration.go
Normal file
88
operatorapi/operations/operator_api/tenant_configuration.go
Normal file
@@ -0,0 +1,88 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2022 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 operator_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"
|
||||
)
|
||||
|
||||
// TenantConfigurationHandlerFunc turns a function with the right signature into a tenant configuration handler
|
||||
type TenantConfigurationHandlerFunc func(TenantConfigurationParams, *models.Principal) middleware.Responder
|
||||
|
||||
// Handle executing the request and returning a response
|
||||
func (fn TenantConfigurationHandlerFunc) Handle(params TenantConfigurationParams, principal *models.Principal) middleware.Responder {
|
||||
return fn(params, principal)
|
||||
}
|
||||
|
||||
// TenantConfigurationHandler interface for that can handle valid tenant configuration params
|
||||
type TenantConfigurationHandler interface {
|
||||
Handle(TenantConfigurationParams, *models.Principal) middleware.Responder
|
||||
}
|
||||
|
||||
// NewTenantConfiguration creates a new http.Handler for the tenant configuration operation
|
||||
func NewTenantConfiguration(ctx *middleware.Context, handler TenantConfigurationHandler) *TenantConfiguration {
|
||||
return &TenantConfiguration{Context: ctx, Handler: handler}
|
||||
}
|
||||
|
||||
/*
|
||||
TenantConfiguration swagger:route GET /namespaces/{namespace}/tenants/{tenant}/configuration OperatorAPI tenantConfiguration
|
||||
|
||||
Tenant Configuration
|
||||
*/
|
||||
type TenantConfiguration struct {
|
||||
Context *middleware.Context
|
||||
Handler TenantConfigurationHandler
|
||||
}
|
||||
|
||||
func (o *TenantConfiguration) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
||||
route, rCtx, _ := o.Context.RouteInfo(r)
|
||||
if rCtx != nil {
|
||||
*r = *rCtx
|
||||
}
|
||||
var Params = NewTenantConfigurationParams()
|
||||
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,112 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2022 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 operator_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/middleware"
|
||||
"github.com/go-openapi/strfmt"
|
||||
)
|
||||
|
||||
// NewTenantConfigurationParams creates a new TenantConfigurationParams object
|
||||
//
|
||||
// There are no default values defined in the spec.
|
||||
func NewTenantConfigurationParams() TenantConfigurationParams {
|
||||
|
||||
return TenantConfigurationParams{}
|
||||
}
|
||||
|
||||
// TenantConfigurationParams contains all the bound params for the tenant configuration operation
|
||||
// typically these are obtained from a http.Request
|
||||
//
|
||||
// swagger:parameters TenantConfiguration
|
||||
type TenantConfigurationParams struct {
|
||||
|
||||
// HTTP Request Object
|
||||
HTTPRequest *http.Request `json:"-"`
|
||||
|
||||
/*
|
||||
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 NewTenantConfigurationParams() beforehand.
|
||||
func (o *TenantConfigurationParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error {
|
||||
var res []error
|
||||
|
||||
o.HTTPRequest = r
|
||||
|
||||
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 *TenantConfigurationParams) 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 *TenantConfigurationParams) 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,135 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2022 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 operator_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"
|
||||
)
|
||||
|
||||
// TenantConfigurationOKCode is the HTTP code returned for type TenantConfigurationOK
|
||||
const TenantConfigurationOKCode int = 200
|
||||
|
||||
/*
|
||||
TenantConfigurationOK A successful response.
|
||||
|
||||
swagger:response tenantConfigurationOK
|
||||
*/
|
||||
type TenantConfigurationOK struct {
|
||||
|
||||
/*
|
||||
In: Body
|
||||
*/
|
||||
Payload *models.TenantConfigurationResponse `json:"body,omitempty"`
|
||||
}
|
||||
|
||||
// NewTenantConfigurationOK creates TenantConfigurationOK with default headers values
|
||||
func NewTenantConfigurationOK() *TenantConfigurationOK {
|
||||
|
||||
return &TenantConfigurationOK{}
|
||||
}
|
||||
|
||||
// WithPayload adds the payload to the tenant configuration o k response
|
||||
func (o *TenantConfigurationOK) WithPayload(payload *models.TenantConfigurationResponse) *TenantConfigurationOK {
|
||||
o.Payload = payload
|
||||
return o
|
||||
}
|
||||
|
||||
// SetPayload sets the payload to the tenant configuration o k response
|
||||
func (o *TenantConfigurationOK) SetPayload(payload *models.TenantConfigurationResponse) {
|
||||
o.Payload = payload
|
||||
}
|
||||
|
||||
// WriteResponse to the client
|
||||
func (o *TenantConfigurationOK) 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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
TenantConfigurationDefault Generic error response.
|
||||
|
||||
swagger:response tenantConfigurationDefault
|
||||
*/
|
||||
type TenantConfigurationDefault struct {
|
||||
_statusCode int
|
||||
|
||||
/*
|
||||
In: Body
|
||||
*/
|
||||
Payload *models.Error `json:"body,omitempty"`
|
||||
}
|
||||
|
||||
// NewTenantConfigurationDefault creates TenantConfigurationDefault with default headers values
|
||||
func NewTenantConfigurationDefault(code int) *TenantConfigurationDefault {
|
||||
if code <= 0 {
|
||||
code = 500
|
||||
}
|
||||
|
||||
return &TenantConfigurationDefault{
|
||||
_statusCode: code,
|
||||
}
|
||||
}
|
||||
|
||||
// WithStatusCode adds the status to the tenant configuration default response
|
||||
func (o *TenantConfigurationDefault) WithStatusCode(code int) *TenantConfigurationDefault {
|
||||
o._statusCode = code
|
||||
return o
|
||||
}
|
||||
|
||||
// SetStatusCode sets the status to the tenant configuration default response
|
||||
func (o *TenantConfigurationDefault) SetStatusCode(code int) {
|
||||
o._statusCode = code
|
||||
}
|
||||
|
||||
// WithPayload adds the payload to the tenant configuration default response
|
||||
func (o *TenantConfigurationDefault) WithPayload(payload *models.Error) *TenantConfigurationDefault {
|
||||
o.Payload = payload
|
||||
return o
|
||||
}
|
||||
|
||||
// SetPayload sets the payload to the tenant configuration default response
|
||||
func (o *TenantConfigurationDefault) SetPayload(payload *models.Error) {
|
||||
o.Payload = payload
|
||||
}
|
||||
|
||||
// WriteResponse to the client
|
||||
func (o *TenantConfigurationDefault) 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) 2022 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 operator_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"
|
||||
)
|
||||
|
||||
// TenantConfigurationURL generates an URL for the tenant configuration operation
|
||||
type TenantConfigurationURL 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 *TenantConfigurationURL) WithBasePath(bp string) *TenantConfigurationURL {
|
||||
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 *TenantConfigurationURL) SetBasePath(bp string) {
|
||||
o._basePath = bp
|
||||
}
|
||||
|
||||
// Build a url path and query string
|
||||
func (o *TenantConfigurationURL) Build() (*url.URL, error) {
|
||||
var _result url.URL
|
||||
|
||||
var _path = "/namespaces/{namespace}/tenants/{tenant}/configuration"
|
||||
|
||||
namespace := o.Namespace
|
||||
if namespace != "" {
|
||||
_path = strings.Replace(_path, "{namespace}", namespace, -1)
|
||||
} else {
|
||||
return nil, errors.New("namespace is required on TenantConfigurationURL")
|
||||
}
|
||||
|
||||
tenant := o.Tenant
|
||||
if tenant != "" {
|
||||
_path = strings.Replace(_path, "{tenant}", tenant, -1)
|
||||
} else {
|
||||
return nil, errors.New("tenant is required on TenantConfigurationURL")
|
||||
}
|
||||
|
||||
_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 *TenantConfigurationURL) 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 *TenantConfigurationURL) String() string {
|
||||
return o.Must(o.Build()).String()
|
||||
}
|
||||
|
||||
// BuildFull builds a full url with scheme, host, path and query string
|
||||
func (o *TenantConfigurationURL) BuildFull(scheme, host string) (*url.URL, error) {
|
||||
if scheme == "" {
|
||||
return nil, errors.New("scheme is required for a full url on TenantConfigurationURL")
|
||||
}
|
||||
if host == "" {
|
||||
return nil, errors.New("host is required for a full url on TenantConfigurationURL")
|
||||
}
|
||||
|
||||
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 *TenantConfigurationURL) StringFull(scheme, host string) string {
|
||||
return o.Must(o.BuildFull(scheme, host)).String()
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2022 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 operator_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"
|
||||
)
|
||||
|
||||
// UpdateTenantConfigurationHandlerFunc turns a function with the right signature into a update tenant configuration handler
|
||||
type UpdateTenantConfigurationHandlerFunc func(UpdateTenantConfigurationParams, *models.Principal) middleware.Responder
|
||||
|
||||
// Handle executing the request and returning a response
|
||||
func (fn UpdateTenantConfigurationHandlerFunc) Handle(params UpdateTenantConfigurationParams, principal *models.Principal) middleware.Responder {
|
||||
return fn(params, principal)
|
||||
}
|
||||
|
||||
// UpdateTenantConfigurationHandler interface for that can handle valid update tenant configuration params
|
||||
type UpdateTenantConfigurationHandler interface {
|
||||
Handle(UpdateTenantConfigurationParams, *models.Principal) middleware.Responder
|
||||
}
|
||||
|
||||
// NewUpdateTenantConfiguration creates a new http.Handler for the update tenant configuration operation
|
||||
func NewUpdateTenantConfiguration(ctx *middleware.Context, handler UpdateTenantConfigurationHandler) *UpdateTenantConfiguration {
|
||||
return &UpdateTenantConfiguration{Context: ctx, Handler: handler}
|
||||
}
|
||||
|
||||
/*
|
||||
UpdateTenantConfiguration swagger:route PATCH /namespaces/{namespace}/tenants/{tenant}/configuration OperatorAPI updateTenantConfiguration
|
||||
|
||||
Update Tenant Configuration
|
||||
*/
|
||||
type UpdateTenantConfiguration struct {
|
||||
Context *middleware.Context
|
||||
Handler UpdateTenantConfigurationHandler
|
||||
}
|
||||
|
||||
func (o *UpdateTenantConfiguration) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
||||
route, rCtx, _ := o.Context.RouteInfo(r)
|
||||
if rCtx != nil {
|
||||
*r = *rCtx
|
||||
}
|
||||
var Params = NewUpdateTenantConfigurationParams()
|
||||
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,150 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2022 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 operator_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/go-openapi/validate"
|
||||
|
||||
"github.com/minio/console/models"
|
||||
)
|
||||
|
||||
// NewUpdateTenantConfigurationParams creates a new UpdateTenantConfigurationParams object
|
||||
//
|
||||
// There are no default values defined in the spec.
|
||||
func NewUpdateTenantConfigurationParams() UpdateTenantConfigurationParams {
|
||||
|
||||
return UpdateTenantConfigurationParams{}
|
||||
}
|
||||
|
||||
// UpdateTenantConfigurationParams contains all the bound params for the update tenant configuration operation
|
||||
// typically these are obtained from a http.Request
|
||||
//
|
||||
// swagger:parameters UpdateTenantConfiguration
|
||||
type UpdateTenantConfigurationParams struct {
|
||||
|
||||
// HTTP Request Object
|
||||
HTTPRequest *http.Request `json:"-"`
|
||||
|
||||
/*
|
||||
Required: true
|
||||
In: body
|
||||
*/
|
||||
Body *models.UpdateTenantConfigurationRequest
|
||||
/*
|
||||
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 NewUpdateTenantConfigurationParams() beforehand.
|
||||
func (o *UpdateTenantConfigurationParams) 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.UpdateTenantConfigurationRequest
|
||||
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)
|
||||
}
|
||||
|
||||
ctx := validate.WithOperationRequest(r.Context())
|
||||
if err := body.ContextValidate(ctx, 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 *UpdateTenantConfigurationParams) 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 *UpdateTenantConfigurationParams) 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,115 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2022 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 operator_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"
|
||||
)
|
||||
|
||||
// UpdateTenantConfigurationNoContentCode is the HTTP code returned for type UpdateTenantConfigurationNoContent
|
||||
const UpdateTenantConfigurationNoContentCode int = 204
|
||||
|
||||
/*
|
||||
UpdateTenantConfigurationNoContent A successful response.
|
||||
|
||||
swagger:response updateTenantConfigurationNoContent
|
||||
*/
|
||||
type UpdateTenantConfigurationNoContent struct {
|
||||
}
|
||||
|
||||
// NewUpdateTenantConfigurationNoContent creates UpdateTenantConfigurationNoContent with default headers values
|
||||
func NewUpdateTenantConfigurationNoContent() *UpdateTenantConfigurationNoContent {
|
||||
|
||||
return &UpdateTenantConfigurationNoContent{}
|
||||
}
|
||||
|
||||
// WriteResponse to the client
|
||||
func (o *UpdateTenantConfigurationNoContent) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
|
||||
|
||||
rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses
|
||||
|
||||
rw.WriteHeader(204)
|
||||
}
|
||||
|
||||
/*
|
||||
UpdateTenantConfigurationDefault Generic error response.
|
||||
|
||||
swagger:response updateTenantConfigurationDefault
|
||||
*/
|
||||
type UpdateTenantConfigurationDefault struct {
|
||||
_statusCode int
|
||||
|
||||
/*
|
||||
In: Body
|
||||
*/
|
||||
Payload *models.Error `json:"body,omitempty"`
|
||||
}
|
||||
|
||||
// NewUpdateTenantConfigurationDefault creates UpdateTenantConfigurationDefault with default headers values
|
||||
func NewUpdateTenantConfigurationDefault(code int) *UpdateTenantConfigurationDefault {
|
||||
if code <= 0 {
|
||||
code = 500
|
||||
}
|
||||
|
||||
return &UpdateTenantConfigurationDefault{
|
||||
_statusCode: code,
|
||||
}
|
||||
}
|
||||
|
||||
// WithStatusCode adds the status to the update tenant configuration default response
|
||||
func (o *UpdateTenantConfigurationDefault) WithStatusCode(code int) *UpdateTenantConfigurationDefault {
|
||||
o._statusCode = code
|
||||
return o
|
||||
}
|
||||
|
||||
// SetStatusCode sets the status to the update tenant configuration default response
|
||||
func (o *UpdateTenantConfigurationDefault) SetStatusCode(code int) {
|
||||
o._statusCode = code
|
||||
}
|
||||
|
||||
// WithPayload adds the payload to the update tenant configuration default response
|
||||
func (o *UpdateTenantConfigurationDefault) WithPayload(payload *models.Error) *UpdateTenantConfigurationDefault {
|
||||
o.Payload = payload
|
||||
return o
|
||||
}
|
||||
|
||||
// SetPayload sets the payload to the update tenant configuration default response
|
||||
func (o *UpdateTenantConfigurationDefault) SetPayload(payload *models.Error) {
|
||||
o.Payload = payload
|
||||
}
|
||||
|
||||
// WriteResponse to the client
|
||||
func (o *UpdateTenantConfigurationDefault) 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) 2022 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 operator_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"
|
||||
)
|
||||
|
||||
// UpdateTenantConfigurationURL generates an URL for the update tenant configuration operation
|
||||
type UpdateTenantConfigurationURL 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 *UpdateTenantConfigurationURL) WithBasePath(bp string) *UpdateTenantConfigurationURL {
|
||||
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 *UpdateTenantConfigurationURL) SetBasePath(bp string) {
|
||||
o._basePath = bp
|
||||
}
|
||||
|
||||
// Build a url path and query string
|
||||
func (o *UpdateTenantConfigurationURL) Build() (*url.URL, error) {
|
||||
var _result url.URL
|
||||
|
||||
var _path = "/namespaces/{namespace}/tenants/{tenant}/configuration"
|
||||
|
||||
namespace := o.Namespace
|
||||
if namespace != "" {
|
||||
_path = strings.Replace(_path, "{namespace}", namespace, -1)
|
||||
} else {
|
||||
return nil, errors.New("namespace is required on UpdateTenantConfigurationURL")
|
||||
}
|
||||
|
||||
tenant := o.Tenant
|
||||
if tenant != "" {
|
||||
_path = strings.Replace(_path, "{tenant}", tenant, -1)
|
||||
} else {
|
||||
return nil, errors.New("tenant is required on UpdateTenantConfigurationURL")
|
||||
}
|
||||
|
||||
_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 *UpdateTenantConfigurationURL) 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 *UpdateTenantConfigurationURL) String() string {
|
||||
return o.Must(o.Build()).String()
|
||||
}
|
||||
|
||||
// BuildFull builds a full url with scheme, host, path and query string
|
||||
func (o *UpdateTenantConfigurationURL) BuildFull(scheme, host string) (*url.URL, error) {
|
||||
if scheme == "" {
|
||||
return nil, errors.New("scheme is required for a full url on UpdateTenantConfigurationURL")
|
||||
}
|
||||
if host == "" {
|
||||
return nil, errors.New("host is required for a full url on UpdateTenantConfigurationURL")
|
||||
}
|
||||
|
||||
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 *UpdateTenantConfigurationURL) StringFull(scheme, host string) string {
|
||||
return o.Must(o.BuildFull(scheme, host)).String()
|
||||
}
|
||||
@@ -110,6 +110,24 @@ func registerTenantHandlers(api *operations.OperatorAPI) {
|
||||
return operator_api.NewTenantDetailsOK().WithPayload(resp)
|
||||
})
|
||||
|
||||
// Tenant Configuration details
|
||||
// Tenant Security details
|
||||
api.OperatorAPITenantConfigurationHandler = operator_api.TenantConfigurationHandlerFunc(func(params operator_api.TenantConfigurationParams, session *models.Principal) middleware.Responder {
|
||||
resp, err := getTenantConfigurationResponse(session, params)
|
||||
if err != nil {
|
||||
return operator_api.NewTenantConfigurationDefault(int(err.Code)).WithPayload(err)
|
||||
}
|
||||
return operator_api.NewTenantConfigurationOK().WithPayload(resp)
|
||||
})
|
||||
// Update Tenant Configuration
|
||||
api.OperatorAPIUpdateTenantConfigurationHandler = operator_api.UpdateTenantConfigurationHandlerFunc(func(params operator_api.UpdateTenantConfigurationParams, session *models.Principal) middleware.Responder {
|
||||
err := getUpdateTenantConfigurationResponse(session, params)
|
||||
if err != nil {
|
||||
return operator_api.NewUpdateTenantConfigurationDefault(int(err.Code)).WithPayload(err)
|
||||
}
|
||||
return operator_api.NewUpdateTenantConfigurationNoContent()
|
||||
})
|
||||
|
||||
// Tenant Security details
|
||||
api.OperatorAPITenantSecurityHandler = operator_api.TenantSecurityHandlerFunc(func(params operator_api.TenantSecurityParams, session *models.Principal) middleware.Responder {
|
||||
resp, err := getTenantSecurityResponse(session, params)
|
||||
@@ -972,6 +990,123 @@ func getSetTenantAdministratorsResponse(session *models.Principal, params operat
|
||||
return nil
|
||||
}
|
||||
|
||||
func getTenantConfigurationResponse(session *models.Principal, params operator_api.TenantConfigurationParams) (*models.TenantConfigurationResponse, *models.Error) {
|
||||
ctx, cancel := context.WithCancel(params.HTTPRequest.Context())
|
||||
defer cancel()
|
||||
opClientClientSet, err := cluster.OperatorClient(session.STSSessionToken)
|
||||
if err != nil {
|
||||
return nil, restapi.ErrorWithContext(ctx, err)
|
||||
}
|
||||
opClient := &operatorClient{
|
||||
client: opClientClientSet,
|
||||
}
|
||||
minTenant, err := getTenant(ctx, opClient, params.Namespace, params.Tenant)
|
||||
if err != nil {
|
||||
return nil, restapi.ErrorWithContext(ctx, err)
|
||||
}
|
||||
// get Kubernetes Client
|
||||
clientSet, err := cluster.K8sClient(session.STSSessionToken)
|
||||
k8sClient := k8sClient{
|
||||
client: clientSet,
|
||||
}
|
||||
if err != nil {
|
||||
return nil, restapi.ErrorWithContext(ctx, err)
|
||||
}
|
||||
tenantConfiguration, err := GetTenantConfiguration(ctx, &k8sClient, minTenant)
|
||||
if err != nil {
|
||||
return nil, restapi.ErrorWithContext(ctx, err)
|
||||
}
|
||||
delete(tenantConfiguration, "accesskey")
|
||||
delete(tenantConfiguration, "secretkey")
|
||||
var envVars []*models.EnvironmentVariable
|
||||
for key, value := range tenantConfiguration {
|
||||
envVars = append(envVars, &models.EnvironmentVariable{
|
||||
Key: key,
|
||||
Value: value,
|
||||
})
|
||||
}
|
||||
sort.Slice(envVars, func(i, j int) bool {
|
||||
return envVars[i].Key < envVars[j].Key
|
||||
})
|
||||
configurationInfo := &models.TenantConfigurationResponse{EnvironmentVariables: envVars}
|
||||
return configurationInfo, nil
|
||||
}
|
||||
|
||||
func getUpdateTenantConfigurationResponse(session *models.Principal, params operator_api.UpdateTenantConfigurationParams) *models.Error {
|
||||
ctx, cancel := context.WithCancel(params.HTTPRequest.Context())
|
||||
defer cancel()
|
||||
opClientClientSet, err := cluster.OperatorClient(session.STSSessionToken)
|
||||
if err != nil {
|
||||
return restapi.ErrorWithContext(ctx, err)
|
||||
}
|
||||
// get Kubernetes Client
|
||||
clientSet, err := cluster.K8sClient(session.STSSessionToken)
|
||||
if err != nil {
|
||||
return restapi.ErrorWithContext(ctx, err)
|
||||
}
|
||||
k8sClient := k8sClient{
|
||||
client: clientSet,
|
||||
}
|
||||
opClient := &operatorClient{
|
||||
client: opClientClientSet,
|
||||
}
|
||||
if err := updateTenantConfigurationFile(ctx, opClient, &k8sClient, params.Namespace, params); err != nil {
|
||||
return restapi.ErrorWithContext(ctx, err, errors.New("unable to update tenant configuration"))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func updateTenantConfigurationFile(ctx context.Context, operatorClient OperatorClientI, client K8sClientI, namespace string, params operator_api.UpdateTenantConfigurationParams) error {
|
||||
tenant, err := operatorClient.TenantGet(ctx, namespace, params.Tenant, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tenantConfiguration, err := GetTenantConfiguration(ctx, client, tenant)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
delete(tenantConfiguration, "accesskey")
|
||||
delete(tenantConfiguration, "secretkey")
|
||||
|
||||
requestBody := params.Body
|
||||
if requestBody == nil {
|
||||
return errors.New("missing request body")
|
||||
}
|
||||
// Patch tenant configuration file with the new values provided by the user
|
||||
for _, envVar := range requestBody.EnvironmentVariables {
|
||||
if envVar.Key == "" {
|
||||
continue
|
||||
}
|
||||
tenantConfiguration[envVar.Key] = envVar.Value
|
||||
}
|
||||
// Remove existing values from configuration file
|
||||
for _, keyToBeDeleted := range requestBody.KeysToBeDeleted {
|
||||
delete(tenantConfiguration, keyToBeDeleted)
|
||||
}
|
||||
|
||||
if !tenant.HasConfigurationSecret() {
|
||||
return errors.New("tenant configuration file not found")
|
||||
}
|
||||
tenantConfigurationSecret, err := client.getSecret(ctx, tenant.Namespace, tenant.Spec.Configuration.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tenantConfigurationSecret.Data["config.env"] = []byte(GenerateTenantConfigurationFile(tenantConfiguration))
|
||||
_, err = client.updateSecret(ctx, namespace, tenantConfigurationSecret, metav1.UpdateOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Restart all MinIO pods at the same time for they to take the new configuration
|
||||
err = client.deletePodCollection(ctx, namespace, metav1.DeleteOptions{}, metav1.ListOptions{
|
||||
LabelSelector: fmt.Sprintf("%s=%s", miniov2.TenantLabel, tenant.Name),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getTenantSecurityResponse(session *models.Principal, params operator_api.TenantSecurityParams) (*models.TenantSecurityResponse, *models.Error) {
|
||||
ctx, cancel := context.WithCancel(params.HTTPRequest.Context())
|
||||
defer cancel()
|
||||
|
||||
@@ -129,7 +129,7 @@ func Test_TenantInfoTenantAdminClient(t *testing.T) {
|
||||
mockGetService func(ctx context.Context, namespace, serviceName string, opts metav1.GetOptions) (*corev1.Service, error)
|
||||
}{
|
||||
{
|
||||
name: "Return Tenant Admin, no errors",
|
||||
name: "Return Tenant Admin, no errors using legacy credentials",
|
||||
args: args{
|
||||
ctx: ctx,
|
||||
client: kClient,
|
||||
@@ -138,7 +138,11 @@ func Test_TenantInfoTenantAdminClient(t *testing.T) {
|
||||
Namespace: "default",
|
||||
Name: "tenant-1",
|
||||
},
|
||||
Spec: miniov2.TenantSpec{CredsSecret: &corev1.LocalObjectReference{Name: "secret-name"}},
|
||||
Spec: miniov2.TenantSpec{
|
||||
CredsSecret: &corev1.LocalObjectReference{
|
||||
Name: "secret-name",
|
||||
},
|
||||
},
|
||||
},
|
||||
serviceURL: "http://service-1.default.svc.cluster.local:80",
|
||||
},
|
||||
@@ -161,6 +165,90 @@ func Test_TenantInfoTenantAdminClient(t *testing.T) {
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "Return Tenant Admin, no errors using credentials from configuration file",
|
||||
args: args{
|
||||
ctx: ctx,
|
||||
client: kClient,
|
||||
tenant: miniov2.Tenant{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "default",
|
||||
Name: "tenant-1",
|
||||
},
|
||||
Spec: miniov2.TenantSpec{
|
||||
CredsSecret: &corev1.LocalObjectReference{
|
||||
Name: "secret-name",
|
||||
},
|
||||
Configuration: &corev1.LocalObjectReference{
|
||||
Name: "tenant-configuration",
|
||||
},
|
||||
},
|
||||
},
|
||||
serviceURL: "http://service-1.default.svc.cluster.local:80",
|
||||
},
|
||||
mockGetSecret: func(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*corev1.Secret, error) {
|
||||
vals := make(map[string][]byte)
|
||||
vals["config.env"] = []byte(`
|
||||
export MINIO_ROOT_USER=minio
|
||||
export MINIO_ROOT_PASSWORD=minio123
|
||||
`)
|
||||
sec := &corev1.Secret{
|
||||
Data: vals,
|
||||
}
|
||||
return sec, nil
|
||||
},
|
||||
mockGetService: func(ctx context.Context, namespace, serviceName string, opts metav1.GetOptions) (*corev1.Service, error) {
|
||||
serv := &corev1.Service{
|
||||
Spec: corev1.ServiceSpec{
|
||||
ClusterIP: "10.1.1.2",
|
||||
},
|
||||
}
|
||||
return serv, nil
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "Return Tenant Admin, no errors using credentials from configuration file 2",
|
||||
args: args{
|
||||
ctx: ctx,
|
||||
client: kClient,
|
||||
tenant: miniov2.Tenant{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "default",
|
||||
Name: "tenant-1",
|
||||
},
|
||||
Spec: miniov2.TenantSpec{
|
||||
CredsSecret: &corev1.LocalObjectReference{
|
||||
Name: "secret-name",
|
||||
},
|
||||
Configuration: &corev1.LocalObjectReference{
|
||||
Name: "tenant-configuration",
|
||||
},
|
||||
},
|
||||
},
|
||||
serviceURL: "http://service-1.default.svc.cluster.local:80",
|
||||
},
|
||||
mockGetSecret: func(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*corev1.Secret, error) {
|
||||
vals := make(map[string][]byte)
|
||||
vals["config.env"] = []byte(`
|
||||
export MINIO_ACCESS_KEY=minio
|
||||
export MINIO_SECRET_KEY=minio123
|
||||
`)
|
||||
sec := &corev1.Secret{
|
||||
Data: vals,
|
||||
}
|
||||
return sec, nil
|
||||
},
|
||||
mockGetService: func(ctx context.Context, namespace, serviceName string, opts metav1.GetOptions) (*corev1.Service, error) {
|
||||
serv := &corev1.Service{
|
||||
Spec: corev1.ServiceSpec{
|
||||
ClusterIP: "10.1.1.2",
|
||||
},
|
||||
}
|
||||
return serv, nil
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "Access key not stored on secrets",
|
||||
args: args{
|
||||
@@ -1354,3 +1442,405 @@ ZrJuAw==
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_getTenant(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
opClient := opClientMock{}
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
operatorClient OperatorClientI
|
||||
namespace string
|
||||
tenantName string
|
||||
mockTenantGet func(ctx context.Context, namespace string, tenantName string, options metav1.GetOptions) (*miniov2.Tenant, error)
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want *miniov2.Tenant
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "error getting tenant information",
|
||||
args: args{
|
||||
ctx: ctx,
|
||||
operatorClient: opClient,
|
||||
namespace: "default",
|
||||
tenantName: "test",
|
||||
mockTenantGet: func(ctx context.Context, namespace string, tenantName string, options metav1.GetOptions) (*miniov2.Tenant, error) {
|
||||
return nil, errors.New("error getting tenant information")
|
||||
},
|
||||
},
|
||||
want: nil,
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "success getting tenant information",
|
||||
args: args{
|
||||
ctx: ctx,
|
||||
operatorClient: opClient,
|
||||
namespace: "default",
|
||||
tenantName: "test",
|
||||
mockTenantGet: func(ctx context.Context, namespace string, tenantName string, options metav1.GetOptions) (*miniov2.Tenant, error) {
|
||||
return &miniov2.Tenant{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test",
|
||||
Namespace: "default",
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
want: &miniov2.Tenant{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test",
|
||||
Namespace: "default",
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
opClientTenantGetMock = tt.args.mockTenantGet
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := getTenant(tt.args.ctx, tt.args.operatorClient, tt.args.namespace, tt.args.tenantName)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("getTenant(%v, %v, %v, %v)", tt.args.ctx, tt.args.operatorClient, tt.args.namespace, tt.args.tenantName)
|
||||
}
|
||||
assert.Equalf(t, tt.want, got, "getTenant(%v, %v, %v, %v)", tt.args.ctx, tt.args.operatorClient, tt.args.namespace, tt.args.tenantName)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_updateTenantConfigurationFile(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
opClient := opClientMock{}
|
||||
kClient := k8sClientMock{}
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
operatorClient OperatorClientI
|
||||
client K8sClientI
|
||||
namespace string
|
||||
params operator_api.UpdateTenantConfigurationParams
|
||||
mockTenantGet func(ctx context.Context, namespace string, tenantName string, options metav1.GetOptions) (*miniov2.Tenant, error)
|
||||
mockGetSecret func(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*corev1.Secret, error)
|
||||
mockUpdateSecret func(ctx context.Context, namespace string, secret *corev1.Secret, opts metav1.UpdateOptions) (*corev1.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",
|
||||
wantErr: true,
|
||||
args: args{
|
||||
ctx: ctx,
|
||||
operatorClient: opClient,
|
||||
client: kClient,
|
||||
namespace: "default",
|
||||
params: operator_api.UpdateTenantConfigurationParams{
|
||||
Namespace: "default",
|
||||
Tenant: "test",
|
||||
},
|
||||
mockTenantGet: func(ctx context.Context, namespace string, tenantName string, options metav1.GetOptions) (*miniov2.Tenant, error) {
|
||||
return nil, errors.New("error getting tenant")
|
||||
},
|
||||
mockGetSecret: func(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*corev1.Secret, error) {
|
||||
return nil, nil
|
||||
},
|
||||
mockUpdateSecret: func(ctx context.Context, namespace string, secret *corev1.Secret, opts metav1.UpdateOptions) (*corev1.Secret, error) {
|
||||
return nil, nil
|
||||
},
|
||||
mockDeletePodCollection: func(ctx context.Context, namespace string, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error {
|
||||
return nil
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "error during getting tenant configuration",
|
||||
wantErr: true,
|
||||
args: args{
|
||||
ctx: ctx,
|
||||
operatorClient: opClient,
|
||||
client: kClient,
|
||||
namespace: "default",
|
||||
params: operator_api.UpdateTenantConfigurationParams{
|
||||
Namespace: "default",
|
||||
Tenant: "test",
|
||||
},
|
||||
mockTenantGet: func(ctx context.Context, namespace string, tenantName string, options metav1.GetOptions) (*miniov2.Tenant, error) {
|
||||
return &miniov2.Tenant{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "default",
|
||||
Name: "test",
|
||||
},
|
||||
Spec: miniov2.TenantSpec{
|
||||
Configuration: &corev1.LocalObjectReference{
|
||||
Name: "tenant-configuration-secret",
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
mockGetSecret: func(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*corev1.Secret, error) {
|
||||
return nil, errors.New("error getting tenant configuration")
|
||||
},
|
||||
mockUpdateSecret: func(ctx context.Context, namespace string, secret *corev1.Secret, opts metav1.UpdateOptions) (*corev1.Secret, error) {
|
||||
return nil, nil
|
||||
},
|
||||
mockDeletePodCollection: func(ctx context.Context, namespace string, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error {
|
||||
return nil
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "error updating tenant configuration because of missing configuration secret",
|
||||
wantErr: true,
|
||||
args: args{
|
||||
ctx: ctx,
|
||||
operatorClient: opClient,
|
||||
client: kClient,
|
||||
namespace: "default",
|
||||
params: operator_api.UpdateTenantConfigurationParams{
|
||||
Namespace: "default",
|
||||
Tenant: "test",
|
||||
Body: &models.UpdateTenantConfigurationRequest{},
|
||||
},
|
||||
mockTenantGet: func(ctx context.Context, namespace string, tenantName string, options metav1.GetOptions) (*miniov2.Tenant, error) {
|
||||
return &miniov2.Tenant{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "default",
|
||||
Name: "test",
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
mockGetSecret: func(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*corev1.Secret, error) {
|
||||
return &corev1.Secret{Data: map[string][]byte{
|
||||
"config.env": []byte(`
|
||||
export MINIO_ROOT_USER=minio
|
||||
export MINIO_ROOT_PASSWORD=minio123
|
||||
export MINIO_CONSOLE_ADDRESS=:8080
|
||||
export MINIO_IDENTITY_LDAP_SERVER_ADDR=localhost:389
|
||||
export MINIO_IDENTITY_LDAP_LOOKUP_BIND_DN="cn=admin,dc=min,dc=io"
|
||||
export MINIO_IDENTITY_LDAP_LOOKUP_BIND_PASSWORD="admin"
|
||||
export MINIO_IDENTITY_LDAP_USER_DN_SEARCH_BASE_DN="dc=min,dc=io"
|
||||
export MINIO_IDENTITY_LDAP_USER_DN_SEARCH_FILTER="(uid=%s)"
|
||||
export MINIO_IDENTITY_LDAP_GROUP_SEARCH_BASE_DN="ou=swengg,dc=min,dc=io"
|
||||
export MINIO_IDENTITY_LDAP_GROUP_SEARCH_FILTER="(&(objectclass=groupOfNames)(member=%d))"
|
||||
export MINIO_IDENTITY_LDAP_SERVER_INSECURE="on"
|
||||
`),
|
||||
}}, nil
|
||||
},
|
||||
mockUpdateSecret: func(ctx context.Context, namespace string, secret *corev1.Secret, opts metav1.UpdateOptions) (*corev1.Secret, error) {
|
||||
return nil, nil
|
||||
},
|
||||
mockDeletePodCollection: func(ctx context.Context, namespace string, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error {
|
||||
return nil
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "error because tenant configuration secret is nil",
|
||||
wantErr: true,
|
||||
args: args{
|
||||
ctx: ctx,
|
||||
operatorClient: opClient,
|
||||
client: kClient,
|
||||
namespace: "default",
|
||||
params: operator_api.UpdateTenantConfigurationParams{
|
||||
Namespace: "default",
|
||||
Tenant: "test",
|
||||
Body: &models.UpdateTenantConfigurationRequest{},
|
||||
},
|
||||
mockTenantGet: func(ctx context.Context, namespace string, tenantName string, options metav1.GetOptions) (*miniov2.Tenant, error) {
|
||||
return &miniov2.Tenant{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "default",
|
||||
Name: "test",
|
||||
},
|
||||
Spec: miniov2.TenantSpec{
|
||||
Configuration: &corev1.LocalObjectReference{
|
||||
Name: "tenant-configuration-secret",
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
mockGetSecret: func(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*corev1.Secret, error) {
|
||||
return nil, nil
|
||||
},
|
||||
mockUpdateSecret: func(ctx context.Context, namespace string, secret *corev1.Secret, opts metav1.UpdateOptions) (*corev1.Secret, error) {
|
||||
return nil, nil
|
||||
},
|
||||
mockDeletePodCollection: func(ctx context.Context, namespace string, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error {
|
||||
return nil
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "error updating tenant configuration because of k8s issue",
|
||||
wantErr: true,
|
||||
args: args{
|
||||
ctx: ctx,
|
||||
operatorClient: opClient,
|
||||
client: kClient,
|
||||
namespace: "default",
|
||||
params: operator_api.UpdateTenantConfigurationParams{
|
||||
Namespace: "default",
|
||||
Tenant: "test",
|
||||
Body: &models.UpdateTenantConfigurationRequest{},
|
||||
},
|
||||
mockTenantGet: func(ctx context.Context, namespace string, tenantName string, options metav1.GetOptions) (*miniov2.Tenant, error) {
|
||||
return &miniov2.Tenant{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "default",
|
||||
Name: "test",
|
||||
},
|
||||
Spec: miniov2.TenantSpec{
|
||||
Configuration: &corev1.LocalObjectReference{
|
||||
Name: "tenant-configuration-secret",
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
mockGetSecret: func(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*corev1.Secret, error) {
|
||||
return &corev1.Secret{Data: map[string][]byte{
|
||||
"config.env": []byte(`
|
||||
export MINIO_ROOT_USER=minio
|
||||
export MINIO_ROOT_PASSWORD=minio123
|
||||
export MINIO_CONSOLE_ADDRESS=:8080
|
||||
export MINIO_IDENTITY_LDAP_SERVER_ADDR=localhost:389
|
||||
export MINIO_IDENTITY_LDAP_LOOKUP_BIND_DN="cn=admin,dc=min,dc=io"
|
||||
export MINIO_IDENTITY_LDAP_LOOKUP_BIND_PASSWORD="admin"
|
||||
export MINIO_IDENTITY_LDAP_USER_DN_SEARCH_BASE_DN="dc=min,dc=io"
|
||||
export MINIO_IDENTITY_LDAP_USER_DN_SEARCH_FILTER="(uid=%s)"
|
||||
export MINIO_IDENTITY_LDAP_GROUP_SEARCH_BASE_DN="ou=swengg,dc=min,dc=io"
|
||||
export MINIO_IDENTITY_LDAP_GROUP_SEARCH_FILTER="(&(objectclass=groupOfNames)(member=%d))"
|
||||
export MINIO_IDENTITY_LDAP_SERVER_INSECURE="on"
|
||||
`),
|
||||
}}, nil
|
||||
},
|
||||
mockUpdateSecret: func(ctx context.Context, namespace string, secret *corev1.Secret, opts metav1.UpdateOptions) (*corev1.Secret, error) {
|
||||
return nil, errors.New("error updating configuration secret")
|
||||
},
|
||||
mockDeletePodCollection: func(ctx context.Context, namespace string, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error {
|
||||
return nil
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "error during deleting pod collection",
|
||||
wantErr: true,
|
||||
args: args{
|
||||
ctx: ctx,
|
||||
operatorClient: opClient,
|
||||
client: kClient,
|
||||
namespace: "default",
|
||||
params: operator_api.UpdateTenantConfigurationParams{
|
||||
Namespace: "default",
|
||||
Tenant: "test",
|
||||
Body: &models.UpdateTenantConfigurationRequest{},
|
||||
},
|
||||
mockTenantGet: func(ctx context.Context, namespace string, tenantName string, options metav1.GetOptions) (*miniov2.Tenant, error) {
|
||||
return &miniov2.Tenant{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "default",
|
||||
Name: "test",
|
||||
},
|
||||
Spec: miniov2.TenantSpec{
|
||||
Configuration: &corev1.LocalObjectReference{
|
||||
Name: "tenant-configuration-secret",
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
mockGetSecret: func(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*corev1.Secret, error) {
|
||||
return &corev1.Secret{Data: map[string][]byte{
|
||||
"config.env": []byte(`
|
||||
export MINIO_ROOT_USER=minio
|
||||
export MINIO_ROOT_PASSWORD=minio123
|
||||
export MINIO_CONSOLE_ADDRESS=:8080
|
||||
export MINIO_IDENTITY_LDAP_SERVER_ADDR=localhost:389
|
||||
export MINIO_IDENTITY_LDAP_LOOKUP_BIND_DN="cn=admin,dc=min,dc=io"
|
||||
export MINIO_IDENTITY_LDAP_LOOKUP_BIND_PASSWORD="admin"
|
||||
export MINIO_IDENTITY_LDAP_USER_DN_SEARCH_BASE_DN="dc=min,dc=io"
|
||||
export MINIO_IDENTITY_LDAP_USER_DN_SEARCH_FILTER="(uid=%s)"
|
||||
export MINIO_IDENTITY_LDAP_GROUP_SEARCH_BASE_DN="ou=swengg,dc=min,dc=io"
|
||||
export MINIO_IDENTITY_LDAP_GROUP_SEARCH_FILTER="(&(objectclass=groupOfNames)(member=%d))"
|
||||
export MINIO_IDENTITY_LDAP_SERVER_INSECURE="on"
|
||||
`),
|
||||
}}, nil
|
||||
},
|
||||
mockUpdateSecret: func(ctx context.Context, namespace string, secret *corev1.Secret, opts metav1.UpdateOptions) (*corev1.Secret, error) {
|
||||
return nil, nil
|
||||
},
|
||||
mockDeletePodCollection: func(ctx context.Context, namespace string, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error {
|
||||
return errors.New("error deleting minio pods")
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "success updating tenant configuration secret",
|
||||
wantErr: false,
|
||||
args: args{
|
||||
ctx: ctx,
|
||||
operatorClient: opClient,
|
||||
client: kClient,
|
||||
namespace: "default",
|
||||
params: operator_api.UpdateTenantConfigurationParams{
|
||||
Namespace: "default",
|
||||
Tenant: "test",
|
||||
Body: &models.UpdateTenantConfigurationRequest{},
|
||||
},
|
||||
mockTenantGet: func(ctx context.Context, namespace string, tenantName string, options metav1.GetOptions) (*miniov2.Tenant, error) {
|
||||
return &miniov2.Tenant{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "default",
|
||||
Name: "test",
|
||||
},
|
||||
Spec: miniov2.TenantSpec{
|
||||
Configuration: &corev1.LocalObjectReference{
|
||||
Name: "tenant-configuration-secret",
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
mockGetSecret: func(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*corev1.Secret, error) {
|
||||
return &corev1.Secret{Data: map[string][]byte{
|
||||
"config.env": []byte(`
|
||||
export MINIO_ROOT_USER=minio
|
||||
export MINIO_ROOT_PASSWORD=minio123
|
||||
export MINIO_CONSOLE_ADDRESS=:8080
|
||||
export MINIO_IDENTITY_LDAP_SERVER_ADDR=localhost:389
|
||||
export MINIO_IDENTITY_LDAP_LOOKUP_BIND_DN="cn=admin,dc=min,dc=io"
|
||||
export MINIO_IDENTITY_LDAP_LOOKUP_BIND_PASSWORD="admin"
|
||||
export MINIO_IDENTITY_LDAP_USER_DN_SEARCH_BASE_DN="dc=min,dc=io"
|
||||
export MINIO_IDENTITY_LDAP_USER_DN_SEARCH_FILTER="(uid=%s)"
|
||||
export MINIO_IDENTITY_LDAP_GROUP_SEARCH_BASE_DN="ou=swengg,dc=min,dc=io"
|
||||
export MINIO_IDENTITY_LDAP_GROUP_SEARCH_FILTER="(&(objectclass=groupOfNames)(member=%d))"
|
||||
export MINIO_IDENTITY_LDAP_SERVER_INSECURE="on"
|
||||
`),
|
||||
}}, nil
|
||||
},
|
||||
mockUpdateSecret: func(ctx context.Context, namespace string, secret *corev1.Secret, opts metav1.UpdateOptions) (*corev1.Secret, error) {
|
||||
return nil, nil
|
||||
},
|
||||
mockDeletePodCollection: func(ctx context.Context, namespace string, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error {
|
||||
return nil
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
k8sclientGetSecretMock = tt.args.mockGetSecret
|
||||
opClientTenantGetMock = tt.args.mockTenantGet
|
||||
UpdateSecretMock = tt.args.mockUpdateSecret
|
||||
DeletePodCollectionMock = tt.args.mockDeletePodCollection
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := updateTenantConfigurationFile(tt.args.ctx, tt.args.operatorClient, tt.args.client, tt.args.namespace, tt.args.params)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("updateTenantConfigurationFile(%v, %v, %v, %v, %v)", tt.args.ctx, tt.args.operatorClient, tt.args.client, tt.args.namespace, tt.args.params)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,11 +46,15 @@ func GetTenantConfiguration(ctx context.Context, clientSet K8sClientI, tenant *m
|
||||
}
|
||||
if tenant.HasConfigurationSecret() {
|
||||
minioConfigurationSecret, err := clientSet.getSecret(ctx, tenant.Namespace, tenant.Spec.Configuration.Name, metav1.GetOptions{})
|
||||
if err == nil {
|
||||
configFromFile := miniov2.ParseRawConfiguration(minioConfigurationSecret.Data["config.env"])
|
||||
for key, val := range configFromFile {
|
||||
tenantConfiguration[key] = string(val)
|
||||
}
|
||||
if err != nil {
|
||||
return tenantConfiguration, err
|
||||
}
|
||||
if minioConfigurationSecret == nil {
|
||||
return tenantConfiguration, errors.New("tenant configuration secret is empty")
|
||||
}
|
||||
configFromFile := miniov2.ParseRawConfiguration(minioConfigurationSecret.Data["config.env"])
|
||||
for key, val := range configFromFile {
|
||||
tenantConfiguration[key] = string(val)
|
||||
}
|
||||
}
|
||||
return tenantConfiguration, nil
|
||||
|
||||
230
operatorapi/utils_test.go
Normal file
230
operatorapi/utils_test.go
Normal file
@@ -0,0 +1,230 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2022 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 operatorapi
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
miniov2 "github.com/minio/operator/pkg/apis/minio.min.io/v2"
|
||||
"github.com/stretchr/testify/assert"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
func TestGetTenantConfiguration(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
kClient := k8sClientMock{}
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
clientSet K8sClientI
|
||||
tenant *miniov2.Tenant
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want map[string]string
|
||||
mockGetSecret func(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*corev1.Secret, error)
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "error because nil tenant",
|
||||
args: args{
|
||||
ctx: ctx,
|
||||
clientSet: kClient,
|
||||
tenant: nil,
|
||||
},
|
||||
mockGetSecret: func(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*corev1.Secret, error) {
|
||||
return nil, nil
|
||||
},
|
||||
want: nil,
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "empty configuration map because no configuration secret is present",
|
||||
args: args{
|
||||
ctx: ctx,
|
||||
clientSet: kClient,
|
||||
tenant: &miniov2.Tenant{},
|
||||
},
|
||||
mockGetSecret: func(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*corev1.Secret, error) {
|
||||
return nil, nil
|
||||
},
|
||||
want: map[string]string{},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "empty configuration map because error while retrieving configuration secret",
|
||||
args: args{
|
||||
ctx: ctx,
|
||||
clientSet: kClient,
|
||||
tenant: &miniov2.Tenant{
|
||||
Spec: miniov2.TenantSpec{
|
||||
Configuration: &corev1.LocalObjectReference{
|
||||
Name: "tenant-configuration-secret",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
mockGetSecret: func(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*corev1.Secret, error) {
|
||||
return nil, errors.New("an error has occurred")
|
||||
},
|
||||
want: map[string]string{},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "parsing tenant configuration from secret file",
|
||||
args: args{
|
||||
ctx: ctx,
|
||||
clientSet: kClient,
|
||||
tenant: &miniov2.Tenant{
|
||||
Spec: miniov2.TenantSpec{
|
||||
Configuration: &corev1.LocalObjectReference{
|
||||
Name: "tenant-configuration-secret",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
mockGetSecret: func(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*corev1.Secret, error) {
|
||||
return &corev1.Secret{Data: map[string][]byte{
|
||||
"config.env": []byte(`
|
||||
export MINIO_ROOT_USER=minio
|
||||
export MINIO_ROOT_PASSWORD=minio123
|
||||
export MINIO_CONSOLE_ADDRESS=:8080
|
||||
export MINIO_IDENTITY_LDAP_SERVER_ADDR=localhost:389
|
||||
export MINIO_IDENTITY_LDAP_LOOKUP_BIND_DN="cn=admin,dc=min,dc=io"
|
||||
export MINIO_IDENTITY_LDAP_LOOKUP_BIND_PASSWORD="admin"
|
||||
export MINIO_IDENTITY_LDAP_USER_DN_SEARCH_BASE_DN="dc=min,dc=io"
|
||||
export MINIO_IDENTITY_LDAP_USER_DN_SEARCH_FILTER="(uid=%s)"
|
||||
export MINIO_IDENTITY_LDAP_GROUP_SEARCH_BASE_DN="ou=swengg,dc=min,dc=io"
|
||||
export MINIO_IDENTITY_LDAP_GROUP_SEARCH_FILTER="(&(objectclass=groupOfNames)(member=%d))"
|
||||
export MINIO_IDENTITY_LDAP_SERVER_INSECURE="on"
|
||||
`),
|
||||
}}, nil
|
||||
},
|
||||
want: map[string]string{
|
||||
"MINIO_ROOT_USER": "minio",
|
||||
"MINIO_ROOT_PASSWORD": "minio123",
|
||||
"MINIO_CONSOLE_ADDRESS": ":8080",
|
||||
"accesskey": "minio",
|
||||
"secretkey": "minio123",
|
||||
"MINIO_IDENTITY_LDAP_SERVER_INSECURE": "on",
|
||||
"MINIO_IDENTITY_LDAP_GROUP_SEARCH_FILTER": "(&(objectclass=groupOfNames)(member=%d))",
|
||||
"MINIO_IDENTITY_LDAP_GROUP_SEARCH_BASE_DN": "ou=swengg,dc=min,dc=io",
|
||||
"MINIO_IDENTITY_LDAP_USER_DN_SEARCH_FILTER": "(uid=%s)",
|
||||
"MINIO_IDENTITY_LDAP_USER_DN_SEARCH_BASE_DN": "dc=min,dc=io",
|
||||
"MINIO_IDENTITY_LDAP_LOOKUP_BIND_PASSWORD": "admin",
|
||||
"MINIO_IDENTITY_LDAP_LOOKUP_BIND_DN": "cn=admin,dc=min,dc=io",
|
||||
"MINIO_IDENTITY_LDAP_SERVER_ADDR": "localhost:389",
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "parsing tenant configuration from secret file and environment variables",
|
||||
args: args{
|
||||
ctx: ctx,
|
||||
clientSet: kClient,
|
||||
tenant: &miniov2.Tenant{
|
||||
Spec: miniov2.TenantSpec{
|
||||
Env: []corev1.EnvVar{
|
||||
{
|
||||
Name: "MINIO_KMS_SECRET_KEY",
|
||||
Value: "my-minio-key:OSMM+vkKUTCvQs9YL/CVMIMt43HFhkUpqJxTmGl6rYw=",
|
||||
},
|
||||
},
|
||||
Configuration: &corev1.LocalObjectReference{
|
||||
Name: "tenant-configuration-secret",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
mockGetSecret: func(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*corev1.Secret, error) {
|
||||
return &corev1.Secret{Data: map[string][]byte{
|
||||
"config.env": []byte(`
|
||||
export MINIO_ROOT_USER=minio
|
||||
export MINIO_ROOT_PASSWORD=minio123
|
||||
export MINIO_CONSOLE_ADDRESS=:8080
|
||||
export MINIO_IDENTITY_LDAP_SERVER_ADDR=localhost:389
|
||||
export MINIO_IDENTITY_LDAP_LOOKUP_BIND_DN="cn=admin,dc=min,dc=io"
|
||||
export MINIO_IDENTITY_LDAP_LOOKUP_BIND_PASSWORD="admin"
|
||||
export MINIO_IDENTITY_LDAP_USER_DN_SEARCH_BASE_DN="dc=min,dc=io"
|
||||
export MINIO_IDENTITY_LDAP_USER_DN_SEARCH_FILTER="(uid=%s)"
|
||||
export MINIO_IDENTITY_LDAP_GROUP_SEARCH_BASE_DN="ou=swengg,dc=min,dc=io"
|
||||
export MINIO_IDENTITY_LDAP_GROUP_SEARCH_FILTER="(&(objectclass=groupOfNames)(member=%d))"
|
||||
export MINIO_IDENTITY_LDAP_SERVER_INSECURE="on"
|
||||
`),
|
||||
}}, nil
|
||||
},
|
||||
want: map[string]string{
|
||||
"MINIO_ROOT_USER": "minio",
|
||||
"MINIO_ROOT_PASSWORD": "minio123",
|
||||
"MINIO_CONSOLE_ADDRESS": ":8080",
|
||||
"accesskey": "minio",
|
||||
"secretkey": "minio123",
|
||||
"MINIO_IDENTITY_LDAP_SERVER_INSECURE": "on",
|
||||
"MINIO_IDENTITY_LDAP_GROUP_SEARCH_FILTER": "(&(objectclass=groupOfNames)(member=%d))",
|
||||
"MINIO_IDENTITY_LDAP_GROUP_SEARCH_BASE_DN": "ou=swengg,dc=min,dc=io",
|
||||
"MINIO_IDENTITY_LDAP_USER_DN_SEARCH_FILTER": "(uid=%s)",
|
||||
"MINIO_IDENTITY_LDAP_USER_DN_SEARCH_BASE_DN": "dc=min,dc=io",
|
||||
"MINIO_IDENTITY_LDAP_LOOKUP_BIND_PASSWORD": "admin",
|
||||
"MINIO_IDENTITY_LDAP_LOOKUP_BIND_DN": "cn=admin,dc=min,dc=io",
|
||||
"MINIO_IDENTITY_LDAP_SERVER_ADDR": "localhost:389",
|
||||
"MINIO_KMS_SECRET_KEY": "my-minio-key:OSMM+vkKUTCvQs9YL/CVMIMt43HFhkUpqJxTmGl6rYw=",
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
k8sclientGetSecretMock = tt.mockGetSecret
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := GetTenantConfiguration(tt.args.ctx, tt.args.clientSet, tt.args.tenant)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("GetTenantConfiguration(%v, %v, %v)", tt.args.ctx, tt.args.clientSet, tt.args.tenant)
|
||||
}
|
||||
assert.Equalf(t, tt.want, got, "GetTenantConfiguration(%v, %v, %v)", tt.args.ctx, tt.args.clientSet, tt.args.tenant)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateTenantConfigurationFile(t *testing.T) {
|
||||
type args struct {
|
||||
configuration map[string]string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "convert configuration map into raw string",
|
||||
args: args{
|
||||
configuration: map[string]string{
|
||||
"MINIO_ROOT_USER": "minio",
|
||||
},
|
||||
},
|
||||
want: `export MINIO_ROOT_USER="minio"
|
||||
`,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert.Equalf(t, tt.want, GenerateTenantConfigurationFile(tt.args.configuration), "GenerateTenantConfigurationFile(%v)", tt.args.configuration)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -733,6 +733,26 @@ export const getClientOS = (): string => {
|
||||
return getPlatform;
|
||||
};
|
||||
|
||||
export const MinIOEnvVarsSettings: any = {
|
||||
MINIO_ACCESS_KEY: { secret: true },
|
||||
MINIO_ACCESS_KEY_OLD: { secret: true },
|
||||
MINIO_AUDIT_WEBHOOK_AUTH_TOKEN: { secret: true },
|
||||
MINIO_IDENTITY_LDAP_LOOKUP_BIND_PASSWORD: { secret: true },
|
||||
MINIO_IDENTITY_OPENID_CLIENT_SECRET: { secret: true },
|
||||
MINIO_KMS_SECRET_KEY: { secret: true },
|
||||
MINIO_LOGGER_WEBHOOK_AUTH_TOKEN: { secret: true },
|
||||
MINIO_NOTIFY_ELASTICSEARCH_PASSWORD: { secret: true },
|
||||
MINIO_NOTIFY_KAFKA_SASL_PASSWORD: { secret: true },
|
||||
MINIO_NOTIFY_MQTT_PASSWORD: { secret: true },
|
||||
MINIO_NOTIFY_NATS_PASSWORD: { secret: true },
|
||||
MINIO_NOTIFY_NATS_TOKEN: { secret: true },
|
||||
MINIO_NOTIFY_REDIS_PASSWORD: { secret: true },
|
||||
MINIO_NOTIFY_WEBHOOK_AUTH_TOKEN: { secret: true },
|
||||
MINIO_ROOT_PASSWORD: { secret: true },
|
||||
MINIO_SECRET_KEY: { secret: true },
|
||||
MINIO_SECRET_KEY_OLD: { secret: true },
|
||||
};
|
||||
|
||||
export const MinIOEnvironmentVariables = [
|
||||
"MINIO_ACCESS_KEY",
|
||||
"MINIO_ACCESS_KEY_OLD",
|
||||
|
||||
@@ -0,0 +1,321 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2022 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/>.
|
||||
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import { connect, useSelector } from "react-redux";
|
||||
import { Theme } from "@mui/material/styles";
|
||||
import { DialogContentText, IconButton } from "@mui/material";
|
||||
import AddIcon from "@mui/icons-material/Add";
|
||||
import RemoveIcon from "../../../../icons/RemoveIcon";
|
||||
import createStyles from "@mui/styles/createStyles";
|
||||
import withStyles from "@mui/styles/withStyles";
|
||||
import Grid from "@mui/material/Grid";
|
||||
import {
|
||||
ITenantConfigurationRequest,
|
||||
ITenantConfigurationResponse,
|
||||
LabelKeyPair,
|
||||
} from "../types";
|
||||
import {
|
||||
containerForHeader,
|
||||
createTenantCommon,
|
||||
formFieldStyles,
|
||||
modalBasic,
|
||||
spacingUtils,
|
||||
tenantDetailsStyles,
|
||||
wizardCommon,
|
||||
} from "../../Common/FormComponents/common/styleLibrary";
|
||||
import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
|
||||
import { AppState, useAppDispatch } from "../../../../store";
|
||||
import { ErrorResponseHandler } from "../../../../common/types";
|
||||
import { ConfirmModalIcon } from "../../../../icons";
|
||||
import { setErrorSnackMessage } from "../../../../systemSlice";
|
||||
import api from "../../../../common/api";
|
||||
import ConfirmDialog from "../../Common/ModalWrapper/ConfirmDialog";
|
||||
import Loader from "../../Common/Loader/Loader";
|
||||
import { Button } from "mds";
|
||||
import { MinIOEnvVarsSettings } from "../../../../common/utils";
|
||||
|
||||
interface ITenantConfiguration {
|
||||
classes: any;
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
...tenantDetailsStyles,
|
||||
...spacingUtils,
|
||||
envVarRow: {
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "flex-start",
|
||||
"&:last-child": {
|
||||
borderBottom: 0,
|
||||
},
|
||||
"@media (max-width: 900px)": {
|
||||
flex: 1,
|
||||
|
||||
"& div label": {
|
||||
minWidth: 50,
|
||||
},
|
||||
},
|
||||
},
|
||||
rowActions: {
|
||||
display: "flex",
|
||||
justifyContent: "flex-end",
|
||||
"@media (max-width: 900px)": {
|
||||
flex: 1,
|
||||
},
|
||||
},
|
||||
overlayAction: {
|
||||
marginLeft: 10,
|
||||
"& svg": {
|
||||
width: 15,
|
||||
height: 15,
|
||||
maxWidth: 15,
|
||||
maxHeight: 15,
|
||||
},
|
||||
"& button": {
|
||||
background: "#EAEAEA",
|
||||
},
|
||||
},
|
||||
loaderAlign: {
|
||||
textAlign: "center",
|
||||
},
|
||||
bold: { fontWeight: "bold" },
|
||||
italic: { fontStyle: "italic" },
|
||||
fileItem: {
|
||||
marginRight: 10,
|
||||
display: "flex",
|
||||
"& div label": {
|
||||
minWidth: 50,
|
||||
},
|
||||
|
||||
"@media (max-width: 900px)": {
|
||||
flexFlow: "column",
|
||||
},
|
||||
},
|
||||
...containerForHeader(theme.spacing(4)),
|
||||
...createTenantCommon,
|
||||
...formFieldStyles,
|
||||
...modalBasic,
|
||||
...wizardCommon,
|
||||
});
|
||||
|
||||
const TenantConfiguration = ({ classes }: ITenantConfiguration) => {
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const tenant = useSelector((state: AppState) => state.tenants.tenantInfo);
|
||||
const loadingTenant = useSelector(
|
||||
(state: AppState) => state.tenants.loadingTenant
|
||||
);
|
||||
|
||||
const [isSending, setIsSending] = useState<boolean>(false);
|
||||
const [dialogOpen, setDialogOpen] = useState<boolean>(false);
|
||||
const [envVars, setEnvVars] = useState<LabelKeyPair[]>([]);
|
||||
const [envVarsToBeDeleted, setEnvVarsToBeDeleted] = useState<string[]>([]);
|
||||
|
||||
const getTenantConfigurationInfo = useCallback(() => {
|
||||
api
|
||||
.invoke(
|
||||
"GET",
|
||||
`/api/v1/namespaces/${tenant?.namespace}/tenants/${tenant?.name}/configuration`
|
||||
)
|
||||
.then((res: ITenantConfigurationResponse) => {
|
||||
if (res.environmentVariables) {
|
||||
setEnvVars(res.environmentVariables);
|
||||
}
|
||||
})
|
||||
.catch((err: ErrorResponseHandler) => {
|
||||
dispatch(setErrorSnackMessage(err));
|
||||
});
|
||||
}, [tenant, dispatch]);
|
||||
|
||||
useEffect(() => {
|
||||
if (tenant) {
|
||||
getTenantConfigurationInfo();
|
||||
}
|
||||
}, [tenant, getTenantConfigurationInfo]);
|
||||
|
||||
const updateTenantConfiguration = () => {
|
||||
setIsSending(true);
|
||||
let payload: ITenantConfigurationRequest = {
|
||||
environmentVariables: envVars.filter((env) => env.key !== ""),
|
||||
keysToBeDeleted: envVarsToBeDeleted,
|
||||
};
|
||||
api
|
||||
.invoke(
|
||||
"PATCH",
|
||||
`/api/v1/namespaces/${tenant?.namespace}/tenants/${tenant?.name}/configuration`,
|
||||
payload
|
||||
)
|
||||
.then(() => {
|
||||
setIsSending(false);
|
||||
setDialogOpen(false);
|
||||
getTenantConfigurationInfo();
|
||||
})
|
||||
.catch((err: ErrorResponseHandler) => {
|
||||
dispatch(setErrorSnackMessage(err));
|
||||
setIsSending(false);
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<ConfirmDialog
|
||||
title={"Save and Restart"}
|
||||
confirmText={"Restart"}
|
||||
cancelText="Cancel"
|
||||
titleIcon={<ConfirmModalIcon />}
|
||||
isLoading={isSending}
|
||||
onClose={() => setDialogOpen(false)}
|
||||
isOpen={dialogOpen}
|
||||
onConfirm={updateTenantConfiguration}
|
||||
confirmationContent={
|
||||
<DialogContentText>
|
||||
Are you sure you want to save the changes and restart the service?
|
||||
</DialogContentText>
|
||||
}
|
||||
/>
|
||||
{loadingTenant ? (
|
||||
<div className={classes.loaderAlign}>
|
||||
<Loader />
|
||||
</div>
|
||||
) : (
|
||||
<Grid container spacing={1}>
|
||||
<Grid item xs={12}>
|
||||
<h1 className={classes.sectionTitle}>Configuration</h1>
|
||||
<hr className={classes.hrClass} />
|
||||
</Grid>
|
||||
<Grid container spacing={1}>
|
||||
{envVars.map((envVar, index) => (
|
||||
<Grid
|
||||
item
|
||||
xs={12}
|
||||
className={`${classes.formFieldRow} ${classes.envVarRow}`}
|
||||
key={`tenant-envVar-${index.toString()}`}
|
||||
>
|
||||
<Grid item xs={5} className={classes.fileItem}>
|
||||
<InputBoxWrapper
|
||||
id="env_var_key"
|
||||
name="env_var_key"
|
||||
label="Key"
|
||||
value={envVar.key}
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const existingEnvVars = [...envVars];
|
||||
|
||||
setEnvVars(
|
||||
existingEnvVars.map((keyPair, i) =>
|
||||
i === index
|
||||
? { key: e.target.value, value: keyPair.value }
|
||||
: keyPair
|
||||
)
|
||||
);
|
||||
}}
|
||||
index={index}
|
||||
key={`env_var_key_${index.toString()}`}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={5} className={classes.fileItem}>
|
||||
<InputBoxWrapper
|
||||
id="env_var_value"
|
||||
name="env_var_value"
|
||||
label="Value"
|
||||
value={envVar.value}
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const existingEnvVars = [...envVars];
|
||||
setEnvVars(
|
||||
existingEnvVars.map((keyPair, i) =>
|
||||
i === index
|
||||
? { key: keyPair.key, value: e.target.value }
|
||||
: keyPair
|
||||
)
|
||||
);
|
||||
}}
|
||||
index={index}
|
||||
key={`env_var_value_${index.toString()}`}
|
||||
type={
|
||||
MinIOEnvVarsSettings[envVar.key] &&
|
||||
MinIOEnvVarsSettings[envVar.key].secret
|
||||
? "password"
|
||||
: "text"
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={2} className={classes.rowActions}>
|
||||
<div className={classes.overlayAction}>
|
||||
<IconButton
|
||||
size={"small"}
|
||||
onClick={() => {
|
||||
const existingEnvVars = [...envVars];
|
||||
existingEnvVars.push({ key: "", value: "" });
|
||||
|
||||
setEnvVars(existingEnvVars);
|
||||
}}
|
||||
disabled={index !== envVars.length - 1}
|
||||
>
|
||||
<AddIcon />
|
||||
</IconButton>
|
||||
</div>
|
||||
<div className={classes.overlayAction}>
|
||||
<IconButton
|
||||
size={"small"}
|
||||
onClick={() => {
|
||||
const existingEnvVars = envVars.filter(
|
||||
(item, fIndex) => fIndex !== index
|
||||
);
|
||||
setEnvVars(existingEnvVars);
|
||||
setEnvVarsToBeDeleted([
|
||||
...envVarsToBeDeleted,
|
||||
envVar.key,
|
||||
]);
|
||||
}}
|
||||
disabled={envVars.length <= 1}
|
||||
>
|
||||
<RemoveIcon />
|
||||
</IconButton>
|
||||
</div>
|
||||
</Grid>
|
||||
</Grid>
|
||||
))}
|
||||
</Grid>
|
||||
<Grid
|
||||
item
|
||||
xs={12}
|
||||
sx={{ display: "flex", justifyContent: "flex-end" }}
|
||||
>
|
||||
<Button
|
||||
id={"save-environment-variables"}
|
||||
type="submit"
|
||||
variant="callAction"
|
||||
disabled={dialogOpen || isSending}
|
||||
onClick={() => setDialogOpen(true)}
|
||||
label={"Save"}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
)}
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
const mapState = (state: AppState) => ({
|
||||
loadingTenant: state.tenants.loadingTenant,
|
||||
selectedTenant: state.tenants.currentTenant,
|
||||
tenant: state.tenants.tenantInfo,
|
||||
});
|
||||
|
||||
const connector = connect(mapState, null);
|
||||
|
||||
export default withStyles(styles)(connector(TenantConfiguration));
|
||||
@@ -89,6 +89,9 @@ const PodDetails = withSuspense(React.lazy(() => import("./pods/PodDetails")));
|
||||
const EditTenantMonitoringScreen = withSuspense(
|
||||
React.lazy(() => import("./EditTenantMonitoringScreen"))
|
||||
);
|
||||
const TenantConfiguration = withSuspense(
|
||||
React.lazy(() => import("./TenantConfiguration"))
|
||||
);
|
||||
|
||||
interface ITenantDetailsProps {
|
||||
classes: any;
|
||||
@@ -366,6 +369,10 @@ const TenantDetails = ({ classes }: ITenantDetailsProps) => {
|
||||
<div className={classes.contentSpacer}>
|
||||
<Routes>
|
||||
<Route path={"summary"} element={<TenantSummary />} />
|
||||
<Route
|
||||
path={"configuration"}
|
||||
element={<TenantConfiguration />}
|
||||
/>
|
||||
<Route path={`summary/yaml`} element={<TenantYAML />} />
|
||||
<Route path={"metrics"} element={<TenantMetrics />} />
|
||||
<Route path={"trace"} element={<TenantTrace />} />
|
||||
@@ -408,6 +415,14 @@ const TenantDetails = ({ classes }: ITenantDetailsProps) => {
|
||||
to: getRoutePath("summary"),
|
||||
},
|
||||
}}
|
||||
{{
|
||||
tabConfig: {
|
||||
label: "Configuration",
|
||||
value: "configuration",
|
||||
component: Link,
|
||||
to: getRoutePath("configuration"),
|
||||
},
|
||||
}}
|
||||
{{
|
||||
tabConfig: {
|
||||
label: "Metrics",
|
||||
|
||||
@@ -40,6 +40,15 @@ export interface ICustomCertificates {
|
||||
consoleCAs: ICertificateInfo[];
|
||||
}
|
||||
|
||||
export interface ITenantConfigurationResponse {
|
||||
environmentVariables: LabelKeyPair[];
|
||||
}
|
||||
|
||||
export interface ITenantConfigurationRequest {
|
||||
environmentVariables: LabelKeyPair[];
|
||||
keysToBeDeleted: string[];
|
||||
}
|
||||
|
||||
export interface ITenantSecurityResponse {
|
||||
autoCert: boolean;
|
||||
customCertificates: ICustomCertificates;
|
||||
|
||||
@@ -414,6 +414,57 @@ paths:
|
||||
tags:
|
||||
- OperatorAPI
|
||||
|
||||
/namespaces/{namespace}/tenants/{tenant}/configuration:
|
||||
get:
|
||||
summary: Tenant Configuration
|
||||
operationId: TenantConfiguration
|
||||
parameters:
|
||||
- name: namespace
|
||||
in: path
|
||||
required: true
|
||||
type: string
|
||||
- name: tenant
|
||||
in: path
|
||||
required: true
|
||||
type: string
|
||||
responses:
|
||||
200:
|
||||
description: A successful response.
|
||||
schema:
|
||||
$ref: "#/definitions/tenantConfigurationResponse"
|
||||
default:
|
||||
description: Generic error response.
|
||||
schema:
|
||||
$ref: "#/definitions/error"
|
||||
tags:
|
||||
- OperatorAPI
|
||||
patch:
|
||||
summary: Update Tenant Configuration
|
||||
operationId: UpdateTenantConfiguration
|
||||
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/updateTenantConfigurationRequest"
|
||||
responses:
|
||||
204:
|
||||
description: A successful response.
|
||||
default:
|
||||
description: Generic error response.
|
||||
schema:
|
||||
$ref: "#/definitions/error"
|
||||
tags:
|
||||
- OperatorAPI
|
||||
|
||||
/namespaces/{namespace}/tenants/{tenant}/security:
|
||||
get:
|
||||
summary: Tenant Security
|
||||
@@ -1683,6 +1734,26 @@ definitions:
|
||||
type: integer
|
||||
format: int64
|
||||
|
||||
tenantConfigurationResponse:
|
||||
type: object
|
||||
properties:
|
||||
environmentVariables:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/definitions/environmentVariable"
|
||||
|
||||
updateTenantConfigurationRequest:
|
||||
type: object
|
||||
properties:
|
||||
keysToBeDeleted:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
environmentVariables:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/definitions/environmentVariable"
|
||||
|
||||
tenantSecurityResponse:
|
||||
type: object
|
||||
properties:
|
||||
|
||||
Reference in New Issue
Block a user