diff --git a/models/create_tenant_response.go b/models/create_tenant_response.go
index cfc51e13b..44ecb9462 100644
--- a/models/create_tenant_response.go
+++ b/models/create_tenant_response.go
@@ -23,6 +23,8 @@ package models
// Editing this file might prove futile when you re-run the swagger generate command
import (
+ "strconv"
+
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
@@ -34,7 +36,7 @@ import (
type CreateTenantResponse struct {
// console
- Console *CreateTenantResponseConsole `json:"console,omitempty"`
+ Console []*TenantResponseItem `json:"console"`
}
// Validate validates this create tenant response
@@ -57,13 +59,20 @@ func (m *CreateTenantResponse) validateConsole(formats strfmt.Registry) error {
return nil
}
- if m.Console != nil {
- if err := m.Console.Validate(formats); err != nil {
- if ve, ok := err.(*errors.Validation); ok {
- return ve.ValidateName("console")
- }
- return err
+ for i := 0; i < len(m.Console); i++ {
+ if swag.IsZero(m.Console[i]) { // not required
+ continue
}
+
+ if m.Console[i] != nil {
+ if err := m.Console[i].Validate(formats); err != nil {
+ if ve, ok := err.(*errors.Validation); ok {
+ return ve.ValidateName("console" + "." + strconv.Itoa(i))
+ }
+ return err
+ }
+ }
+
}
return nil
@@ -86,38 +95,3 @@ func (m *CreateTenantResponse) UnmarshalBinary(b []byte) error {
*m = res
return nil
}
-
-// CreateTenantResponseConsole create tenant response console
-//
-// swagger:model CreateTenantResponseConsole
-type CreateTenantResponseConsole struct {
-
- // access key
- AccessKey string `json:"access_key,omitempty"`
-
- // secret key
- SecretKey string `json:"secret_key,omitempty"`
-}
-
-// Validate validates this create tenant response console
-func (m *CreateTenantResponseConsole) Validate(formats strfmt.Registry) error {
- return nil
-}
-
-// MarshalBinary interface implementation
-func (m *CreateTenantResponseConsole) MarshalBinary() ([]byte, error) {
- if m == nil {
- return nil, nil
- }
- return swag.WriteJSON(m)
-}
-
-// UnmarshalBinary interface implementation
-func (m *CreateTenantResponseConsole) UnmarshalBinary(b []byte) error {
- var res CreateTenantResponseConsole
- if err := swag.ReadJSON(b, &res); err != nil {
- return err
- }
- *m = res
- return nil
-}
diff --git a/models/tenant_response_item.go b/models/tenant_response_item.go
new file mode 100644
index 000000000..a0f1a9b27
--- /dev/null
+++ b/models/tenant_response_item.go
@@ -0,0 +1,63 @@
+// Code generated by go-swagger; DO NOT EDIT.
+
+// This file is part of MinIO Console Server
+// Copyright (c) 2021 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 .
+//
+
+package models
+
+// This file was generated by the swagger tool.
+// Editing this file might prove futile when you re-run the swagger generate command
+
+import (
+ "github.com/go-openapi/strfmt"
+ "github.com/go-openapi/swag"
+)
+
+// TenantResponseItem tenant response item
+//
+// swagger:model tenantResponseItem
+type TenantResponseItem struct {
+
+ // access key
+ AccessKey string `json:"access_key,omitempty"`
+
+ // secret key
+ SecretKey string `json:"secret_key,omitempty"`
+}
+
+// Validate validates this tenant response item
+func (m *TenantResponseItem) Validate(formats strfmt.Registry) error {
+ return nil
+}
+
+// MarshalBinary interface implementation
+func (m *TenantResponseItem) MarshalBinary() ([]byte, error) {
+ if m == nil {
+ return nil, nil
+ }
+ return swag.WriteJSON(m)
+}
+
+// UnmarshalBinary interface implementation
+func (m *TenantResponseItem) UnmarshalBinary(b []byte) error {
+ var res TenantResponseItem
+ if err := swag.ReadJSON(b, &res); err != nil {
+ return err
+ }
+ *m = res
+ return nil
+}
diff --git a/portal-ui/src/screens/Console/Common/CredentialsPrompt/CredentialsPrompt.tsx b/portal-ui/src/screens/Console/Common/CredentialsPrompt/CredentialsPrompt.tsx
index bf0ebabce..55b27be71 100644
--- a/portal-ui/src/screens/Console/Common/CredentialsPrompt/CredentialsPrompt.tsx
+++ b/portal-ui/src/screens/Console/Common/CredentialsPrompt/CredentialsPrompt.tsx
@@ -31,6 +31,10 @@ const styles = (theme: Theme) =>
buttonContainer: {
textAlign: "right",
},
+ credentialsPanel: {
+ overflowY: "auto",
+ maxHeight: 350,
+ }
});
interface ICredentialsPromptProps {
@@ -84,16 +88,31 @@ const CredentialsPrompt = ({
A new {entity} has been created with the following details:
{consoleCreds && (
-
+
Console Credentials
-
- -
- Access Key: {consoleCreds.accessKey}
-
- -
- Secret Key: {consoleCreds.secretKey}
-
-
+ {Array.isArray(consoleCreds) &&
+ consoleCreds.map((credentialsPair, index) => {
+ return (
+
+ -
+ Access Key: {credentialsPair.accessKey}
+
+ -
+ Secret Key: {credentialsPair.secretKey}
+
+
+ );
+ })}
+ {!Array.isArray(consoleCreds) && (
+
+ -
+ Access Key: {consoleCreds.accessKey}
+
+ -
+ Secret Key: {consoleCreds.secretKey}
+
+
+ )}
)}
@@ -112,12 +131,27 @@ const CredentialsPrompt = ({
let consoleExtras = {};
if (consoleCreds) {
- consoleExtras = {
- console: {
- access_key: consoleCreds.accessKey,
- secret_key: consoleCreds.secretKey,
- },
- };
+ if (!Array.isArray(consoleCreds)) {
+ consoleExtras = {
+ console: [
+ {
+ access_key: consoleCreds.accessKey,
+ secret_key: consoleCreds.secretKey,
+ },
+ ],
+ };
+ } else {
+ const cCreds = consoleCreds.map((itemMap) => {
+ return {
+ access_key: itemMap.accessKey,
+ secret_key: itemMap.secretKey,
+ }
+ });
+
+ consoleExtras = {
+ console: [...cCreds],
+ };
+ }
}
download(
diff --git a/portal-ui/src/screens/Console/Common/CredentialsPrompt/types.ts b/portal-ui/src/screens/Console/Common/CredentialsPrompt/types.ts
index 7ae8729cf..46193ae55 100644
--- a/portal-ui/src/screens/Console/Common/CredentialsPrompt/types.ts
+++ b/portal-ui/src/screens/Console/Common/CredentialsPrompt/types.ts
@@ -15,7 +15,7 @@
// along with this program. If not, see .
export interface NewServiceAccount {
- console?: ConsoleSA;
+ console?: ConsoleSA | ConsoleSA[];
accessKey?: string;
secretKey?: string;
}
diff --git a/portal-ui/src/screens/Console/Tenants/AddTenant/AddTenant.tsx b/portal-ui/src/screens/Console/Tenants/AddTenant/AddTenant.tsx
index e18590f8a..974d4dcc4 100644
--- a/portal-ui/src/screens/Console/Tenants/AddTenant/AddTenant.tsx
+++ b/portal-ui/src/screens/Console/Tenants/AddTenant/AddTenant.tsx
@@ -15,6 +15,7 @@
// along with this program. If not, see .
import React, { Fragment, useEffect, useState } from "react";
+import get from "lodash/get";
import { connect } from "react-redux";
import Grid from "@material-ui/core/Grid";
import { LinearProgress } from "@material-ui/core";
@@ -512,13 +513,30 @@ const AddTenant = ({
api
.invoke("POST", `/api/v1/tenants`, dataSend)
.then((res) => {
- const newSrvAcc: NewServiceAccount = {
- console: {
- accessKey: res.console.access_key,
- secretKey: res.console.secret_key,
- },
+ const consoleSAList = get(res, "console", []);
+
+ let newSrvAcc: NewServiceAccount = {
+ console: [],
};
+ if (consoleSAList && Array.isArray(consoleSAList)) {
+ const consoleItem = consoleSAList.map((consoleKey) => {
+ return {
+ accessKey: consoleKey.access_key,
+ secretKey: consoleKey.secret_key,
+ };
+ });
+
+ newSrvAcc.console = consoleItem;
+ } else {
+ newSrvAcc = {
+ console: {
+ accessKey: res.console.access_key,
+ secretKey: res.console.secret_key,
+ },
+ };
+ }
+
setAddSending(false);
setShowNewCredentials(true);
diff --git a/restapi/admin_tenants.go b/restapi/admin_tenants.go
index f4a5d6968..4e22d8f44 100644
--- a/restapi/admin_tenants.go
+++ b/restapi/admin_tenants.go
@@ -767,6 +767,7 @@ func getTenantCreatedResponse(session *models.Principal, params admin_api.Create
// optionals are set below
var tenantUserAccessKey string
var tenantUserSecretKey string
+ keyElementEmpty := len(tenantReq.Idp.Keys) == 1 && (*tenantReq.Idp.Keys[0].AccessKey == "" && *tenantReq.Idp.Keys[0].SecretKey == "")
enableConsole := true
if tenantReq.EnableConsole != nil && *tenantReq.EnableConsole {
@@ -775,7 +776,7 @@ func getTenantCreatedResponse(session *models.Principal, params admin_api.Create
if enableConsole {
// provision initial user for tenant
- if !(len(tenantReq.Idp.Keys) > 0) {
+ if len(tenantReq.Idp.Keys) == 0 || keyElementEmpty {
tenantUserAccessKey = RandomCharString(16)
tenantUserSecretKey = RandomCharString(32)
consoleUserSecretName := fmt.Sprintf("%s-user-secret", tenantName)
@@ -1055,10 +1056,17 @@ func getTenantCreatedResponse(session *models.Principal, params admin_api.Create
response = &models.CreateTenantResponse{}
// Attach Console Credentials
if enableConsole {
- response.Console = &models.CreateTenantResponseConsole{
- AccessKey: tenantUserAccessKey,
- SecretKey: tenantUserSecretKey,
+ var itemsToReturn []*models.TenantResponseItem
+
+ if len(tenantReq.Idp.Keys) == 0 || keyElementEmpty {
+ itemsToReturn = append(itemsToReturn, &models.TenantResponseItem{AccessKey: tenantUserAccessKey, SecretKey: tenantUserSecretKey})
+ } else { // IDP Keys
+ for _, item := range tenantReq.Idp.Keys {
+ itemsToReturn = append(itemsToReturn, &models.TenantResponseItem{AccessKey: *item.AccessKey, SecretKey: *item.SecretKey})
+ }
}
+
+ response.Console = itemsToReturn
}
return response, nil
}
diff --git a/restapi/embedded_spec.go b/restapi/embedded_spec.go
index 1ca74dfdf..ee1745d23 100644
--- a/restapi/embedded_spec.go
+++ b/restapi/embedded_spec.go
@@ -4330,14 +4330,9 @@ func init() {
"type": "object",
"properties": {
"console": {
- "type": "object",
- "properties": {
- "access_key": {
- "type": "string"
- },
- "secret_key": {
- "type": "string"
- }
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/tenantResponseItem"
}
}
}
@@ -6337,6 +6332,17 @@ func init() {
}
}
},
+ "tenantResponseItem": {
+ "type": "object",
+ "properties": {
+ "access_key": {
+ "type": "string"
+ },
+ "secret_key": {
+ "type": "string"
+ }
+ }
+ },
"tenantUsage": {
"type": "object",
"properties": {
@@ -10463,17 +10469,6 @@ func init() {
}
}
},
- "CreateTenantResponseConsole": {
- "type": "object",
- "properties": {
- "access_key": {
- "type": "string"
- },
- "secret_key": {
- "type": "string"
- }
- }
- },
"GcpConfigurationSecretmanager": {
"type": "object",
"required": [
@@ -11668,14 +11663,9 @@ func init() {
"type": "object",
"properties": {
"console": {
- "type": "object",
- "properties": {
- "access_key": {
- "type": "string"
- },
- "secret_key": {
- "type": "string"
- }
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/tenantResponseItem"
}
}
}
@@ -13528,6 +13518,17 @@ func init() {
}
}
},
+ "tenantResponseItem": {
+ "type": "object",
+ "properties": {
+ "access_key": {
+ "type": "string"
+ },
+ "secret_key": {
+ "type": "string"
+ }
+ }
+ },
"tenantUsage": {
"type": "object",
"properties": {
diff --git a/swagger.yml b/swagger.yml
index ea4dff4c7..cb348d938 100644
--- a/swagger.yml
+++ b/swagger.yml
@@ -3851,12 +3851,18 @@ definitions:
type: object
properties:
console:
- type: object
- properties:
- access_key:
- type: string
- secret_key:
- type: string
+ type: array
+ items:
+ $ref: "#/definitions/tenantResponseItem"
+
+ tenantResponseItem:
+ type: object
+ properties:
+ access_key:
+ type: string
+ secret_key:
+ type: string
+
pool:
type: object
required: