diff --git a/models/admin_info_response.go b/models/admin_info_response.go
index 87481b60c..c221669e5 100644
--- a/models/admin_info_response.go
+++ b/models/admin_info_response.go
@@ -42,6 +42,9 @@ type AdminInfoResponse struct {
// objects
Objects int64 `json:"objects,omitempty"`
+ // servers
+ Servers []*ServerProperties `json:"servers"`
+
// usage
Usage int64 `json:"usage,omitempty"`
@@ -53,6 +56,10 @@ type AdminInfoResponse struct {
func (m *AdminInfoResponse) Validate(formats strfmt.Registry) error {
var res []error
+ if err := m.validateServers(formats); err != nil {
+ res = append(res, err)
+ }
+
if err := m.validateWidgets(formats); err != nil {
res = append(res, err)
}
@@ -63,6 +70,30 @@ func (m *AdminInfoResponse) Validate(formats strfmt.Registry) error {
return nil
}
+func (m *AdminInfoResponse) validateServers(formats strfmt.Registry) error {
+ if swag.IsZero(m.Servers) { // not required
+ return nil
+ }
+
+ for i := 0; i < len(m.Servers); i++ {
+ if swag.IsZero(m.Servers[i]) { // not required
+ continue
+ }
+
+ if m.Servers[i] != nil {
+ if err := m.Servers[i].Validate(formats); err != nil {
+ if ve, ok := err.(*errors.Validation); ok {
+ return ve.ValidateName("servers" + "." + strconv.Itoa(i))
+ }
+ return err
+ }
+ }
+
+ }
+
+ return nil
+}
+
func (m *AdminInfoResponse) validateWidgets(formats strfmt.Registry) error {
if swag.IsZero(m.Widgets) { // not required
return nil
@@ -91,6 +122,10 @@ func (m *AdminInfoResponse) validateWidgets(formats strfmt.Registry) error {
func (m *AdminInfoResponse) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
var res []error
+ if err := m.contextValidateServers(ctx, formats); err != nil {
+ res = append(res, err)
+ }
+
if err := m.contextValidateWidgets(ctx, formats); err != nil {
res = append(res, err)
}
@@ -101,6 +136,24 @@ func (m *AdminInfoResponse) ContextValidate(ctx context.Context, formats strfmt.
return nil
}
+func (m *AdminInfoResponse) contextValidateServers(ctx context.Context, formats strfmt.Registry) error {
+
+ for i := 0; i < len(m.Servers); i++ {
+
+ if m.Servers[i] != nil {
+ if err := m.Servers[i].ContextValidate(ctx, formats); err != nil {
+ if ve, ok := err.(*errors.Validation); ok {
+ return ve.ValidateName("servers" + "." + strconv.Itoa(i))
+ }
+ return err
+ }
+ }
+
+ }
+
+ return nil
+}
+
func (m *AdminInfoResponse) contextValidateWidgets(ctx context.Context, formats strfmt.Registry) error {
for i := 0; i < len(m.Widgets); i++ {
diff --git a/models/server_properties.go b/models/server_properties.go
new file mode 100644
index 000000000..d119b9b24
--- /dev/null
+++ b/models/server_properties.go
@@ -0,0 +1,82 @@
+// 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 (
+ "context"
+
+ "github.com/go-openapi/strfmt"
+ "github.com/go-openapi/swag"
+)
+
+// ServerProperties server properties
+//
+// swagger:model serverProperties
+type ServerProperties struct {
+
+ // commit ID
+ CommitID string `json:"commitID,omitempty"`
+
+ // endpoint
+ Endpoint string `json:"endpoint,omitempty"`
+
+ // pool number
+ PoolNumber int64 `json:"poolNumber,omitempty"`
+
+ // state
+ State string `json:"state,omitempty"`
+
+ // uptime
+ Uptime string `json:"uptime,omitempty"`
+
+ // version
+ Version string `json:"version,omitempty"`
+}
+
+// Validate validates this server properties
+func (m *ServerProperties) Validate(formats strfmt.Registry) error {
+ return nil
+}
+
+// ContextValidate validates this server properties based on context it is used
+func (m *ServerProperties) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
+ return nil
+}
+
+// MarshalBinary interface implementation
+func (m *ServerProperties) MarshalBinary() ([]byte, error) {
+ if m == nil {
+ return nil, nil
+ }
+ return swag.WriteJSON(m)
+}
+
+// UnmarshalBinary interface implementation
+func (m *ServerProperties) UnmarshalBinary(b []byte) error {
+ var res ServerProperties
+ if err := swag.ReadJSON(b, &res); err != nil {
+ return err
+ }
+ *m = res
+ return nil
+}
diff --git a/portal-ui/src/screens/Console/Dashboard/BasicDashboard/BasicDashboard.tsx b/portal-ui/src/screens/Console/Dashboard/BasicDashboard/BasicDashboard.tsx
index ced1ba662..e975a39e4 100644
--- a/portal-ui/src/screens/Console/Dashboard/BasicDashboard/BasicDashboard.tsx
+++ b/portal-ui/src/screens/Console/Dashboard/BasicDashboard/BasicDashboard.tsx
@@ -14,17 +14,20 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
-import React, { Fragment } from "react";
+import React, { Fragment, useState } from "react";
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
import clsx from "clsx";
import Grid from "@material-ui/core/Grid";
import Paper from "@material-ui/core/Paper";
import Typography from "@material-ui/core/Typography";
-import { Usage } from "../types";
-import { niceBytes } from "../../../../common/utils";
+import { Usage, ServerInfo } from "../types";
+import { niceBytes, niceDays } from "../../../../common/utils";
import AllBucketsIcon from "../../../../icons/AllBucketsIcon";
import UsageIcon from "../../../../icons/UsageIcon";
+import DnsIcon from "@material-ui/icons/Dns";
import EgressIcon from "../../../../icons/EgressIcon";
+import TableWrapper from "../../Common/TableWrapper/TableWrapper";
+import { TableContainer } from "@material-ui/core";
const styles = (theme: Theme) =>
createStyles({
@@ -57,6 +60,7 @@ const styles = (theme: Theme) =>
},
notationContainer: {
display: "flex",
+ flexWrap: "wrap",
},
dashboardBG: {
width: 390,
@@ -120,6 +124,45 @@ const BasicDashboard = ({ classes, usage }: IDashboardProps) => {
return usage.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
};
+ const serverColumns = [
+ {
+ label: "Endpoint",
+ elementKey: "endpoint",
+ },
+ {
+ label: "Status",
+ elementKey: "state",
+ },
+ {
+ label: "Uptime",
+ elementKey: "uptime",
+ },
+ {
+ label: "Version",
+ elementKey: "version",
+ },
+ ];
+
+ const makeServerArray = (usage: Usage | null) => {
+ if (usage != null) {
+ usage.servers.forEach(s => s.uptime = niceDays(s.uptime))
+ return usage.servers.sort(function (a, b) {
+ var nameA = a.endpoint.toUpperCase();
+ var nameB = b.endpoint.toUpperCase();
+ if (nameA < nameB) {
+ return -1;
+ }
+ if (nameA > nameB) {
+ return 1;
+ }
+ return 0;
+ });
+ }
+ else return [];
+ };
+
+ const serverArray = makeServerArray(usage);
+
return (
@@ -172,6 +215,24 @@ const BasicDashboard = ({ classes, usage }: IDashboardProps) => {
{usage ? prettyNumber(usage.objects) : 0}
+
+
+
+
+
+
+ {" "}
+ Servers
+
+
+
+
diff --git a/portal-ui/src/screens/Console/Dashboard/types.tsx b/portal-ui/src/screens/Console/Dashboard/types.tsx
index d76075e62..69c314e6a 100644
--- a/portal-ui/src/screens/Console/Dashboard/types.tsx
+++ b/portal-ui/src/screens/Console/Dashboard/types.tsx
@@ -19,4 +19,14 @@ export interface Usage {
buckets: number;
objects: number;
widgets?: any;
+ servers: ServerInfo[];
+}
+
+export interface ServerInfo {
+ state: string;
+ endpoint: string;
+ uptime: string;
+ version: string;
+ commitID: string;
+ poolNumber: number;
}
diff --git a/restapi/admin_info.go b/restapi/admin_info.go
index e7aebd4ed..7aa781f77 100644
--- a/restapi/admin_info.go
+++ b/restapi/admin_info.go
@@ -24,6 +24,7 @@ import (
"net/http"
"net/url"
"regexp"
+ "strconv"
"strings"
"time"
@@ -62,6 +63,7 @@ type UsageInfo struct {
Objects int64
Usage int64
DisksUsage int64
+ Servers []*models.ServerProperties
}
// GetAdminInfo invokes admin info and returns a parsed `UsageInfo` structure
@@ -80,11 +82,27 @@ func GetAdminInfo(ctx context.Context, client MinioAdmin) (*UsageInfo, error) {
}
}
+ //serverArray contains the serverProperties which describe the servers in the network
+ var serverArray []*models.ServerProperties
+ for _, serv := range serverInfo.Servers {
+ var newServer = &models.ServerProperties{
+ State: serv.State,
+ Endpoint: serv.Endpoint,
+ Uptime: strconv.Itoa(int(serv.Uptime)),
+ Version: serv.Version,
+ CommitID: serv.CommitID,
+ PoolNumber: int64(serv.PoolNumber),
+ }
+
+ serverArray = append(serverArray, newServer)
+ }
+
return &UsageInfo{
Buckets: int64(serverInfo.Buckets.Count),
Objects: int64(serverInfo.Objects.Count),
Usage: int64(serverInfo.Usage.Size),
DisksUsage: usedSpace,
+ Servers: serverArray,
}, nil
}
@@ -820,6 +838,7 @@ func getUsageWidgetsForDeployment(prometheusURL string, mAdmin *madmin.AdminClie
Buckets: usage.Buckets,
Objects: usage.Objects,
Usage: usage.Usage,
+ Servers: usage.Servers,
}
return sessionResp, nil
}
diff --git a/restapi/embedded_spec.go b/restapi/embedded_spec.go
index 4e3ceb9cf..b920accd2 100644
--- a/restapi/embedded_spec.go
+++ b/restapi/embedded_spec.go
@@ -3517,6 +3517,12 @@ func init() {
"objects": {
"type": "integer"
},
+ "servers": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/serverProperties"
+ }
+ },
"usage": {
"type": "integer"
},
@@ -4855,6 +4861,29 @@ func init() {
}
}
},
+ "serverProperties": {
+ "type": "object",
+ "properties": {
+ "commitID": {
+ "type": "string"
+ },
+ "endpoint": {
+ "type": "string"
+ },
+ "poolNumber": {
+ "type": "integer"
+ },
+ "state": {
+ "type": "string"
+ },
+ "uptime": {
+ "type": "string"
+ },
+ "version": {
+ "type": "string"
+ }
+ }
+ },
"serviceAccountCreds": {
"type": "object",
"properties": {
@@ -8935,6 +8964,12 @@ func init() {
"objects": {
"type": "integer"
},
+ "servers": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/serverProperties"
+ }
+ },
"usage": {
"type": "integer"
},
@@ -10273,6 +10308,29 @@ func init() {
}
}
},
+ "serverProperties": {
+ "type": "object",
+ "properties": {
+ "commitID": {
+ "type": "string"
+ },
+ "endpoint": {
+ "type": "string"
+ },
+ "poolNumber": {
+ "type": "integer"
+ },
+ "state": {
+ "type": "string"
+ },
+ "uptime": {
+ "type": "string"
+ },
+ "version": {
+ "type": "string"
+ }
+ }
+ },
"serviceAccountCreds": {
"type": "object",
"properties": {
diff --git a/swagger-console.yml b/swagger-console.yml
index a4b415e9d..2763e0dd4 100644
--- a/swagger-console.yml
+++ b/swagger-console.yml
@@ -389,7 +389,7 @@ paths:
schema:
type: array
items:
- $ref: "#/definitions/deleteFile"
+ $ref: "#/definitions/deleteFile"
responses:
200:
description: A successful response.
@@ -1046,7 +1046,7 @@ paths:
$ref: "#/definitions/error"
tags:
- UserAPI
-
+
/buckets/{bucket_name}/rewind/{date}:
get:
summary: Get objects in a bucket for a rewind date
@@ -1074,7 +1074,7 @@ paths:
schema:
$ref: "#/definitions/error"
tags:
- - UserAPI
+ - UserAPI
/service-accounts:
get:
@@ -1935,7 +1935,6 @@ paths:
tags:
- AdminAPI
-
/admin/info:
get:
summary: Returns information about the deployment
@@ -3085,6 +3084,25 @@ definitions:
type: array
items:
$ref: "#/definitions/widget"
+ servers:
+ type: array
+ items:
+ $ref: "#/definitions/serverProperties"
+ serverProperties:
+ type: object
+ properties:
+ state:
+ type: string
+ endpoint:
+ type: string
+ uptime:
+ type: string
+ version:
+ type: string
+ commitID:
+ type: string
+ poolNumber:
+ type: integer
arnsResponse:
type: object
properties:
@@ -3300,7 +3318,6 @@ definitions:
object_locking_enabled:
type: boolean
-
logSearchResponse:
type: object
properties:
@@ -3308,8 +3325,6 @@ definitions:
type: object
title: list of log search responses
-
-
objectLegalHoldStatus:
type: string
enum:
@@ -3559,7 +3574,6 @@ definitions:
items:
$ref: "#/definitions/permissionAction"
-
tier_s3:
type: object
properties:
@@ -3679,7 +3693,7 @@ definitions:
type: string
name:
type: string
-
+
rewindResponse:
type: object
properties: