Pod Events (#807)

* Pod Events

* restoring files

* restoring files

* make assets

Co-authored-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
Co-authored-by: Adam Stafford <adam@minio.io>
Co-authored-by: Alex <33497058+bexsoft@users.noreply.github.com>
This commit is contained in:
adfost
2021-06-17 16:24:22 -07:00
committed by GitHub
parent 34b05bd426
commit 09503ed0c8
31 changed files with 1051 additions and 152 deletions

View File

@@ -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 <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"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
)
// EventListElement event list element
//
// swagger:model eventListElement
type EventListElement struct {
// event type
EventType string `json:"event_type,omitempty"`
// last seen
LastSeen int64 `json:"last_seen,omitempty"`
// message
Message string `json:"message,omitempty"`
// namespace
Namespace string `json:"namespace,omitempty"`
// object
Object string `json:"object,omitempty"`
// reason
Reason string `json:"reason,omitempty"`
}
// Validate validates this event list element
func (m *EventListElement) Validate(formats strfmt.Registry) error {
return nil
}
// ContextValidate validates this event list element based on context it is used
func (m *EventListElement) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *EventListElement) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *EventListElement) UnmarshalBinary(b []byte) error {
var res EventListElement
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View File

@@ -0,0 +1,86 @@
// 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 <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"
)
// EventListWrapper event list wrapper
//
// swagger:model eventListWrapper
type EventListWrapper []*EventListElement
// Validate validates this event list wrapper
func (m EventListWrapper) Validate(formats strfmt.Registry) error {
var res []error
for i := 0; i < len(m); i++ {
if swag.IsZero(m[i]) { // not required
continue
}
if m[i] != nil {
if err := m[i].Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName(strconv.Itoa(i))
}
return err
}
}
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
// ContextValidate validate this event list wrapper based on the context it is used
func (m EventListWrapper) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
var res []error
for i := 0; i < len(m); i++ {
if m[i] != nil {
if err := m[i].ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName(strconv.Itoa(i))
}
return err
}
}
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

6
node_modules/.yarn-integrity generated vendored
View File

@@ -1,6 +1,8 @@
{
"systemParams": "darwin-x64-88",
"modulesFolders": [],
"systemParams": "darwin-x64-93",
"modulesFolders": [
"node_modules"
],
"flags": [],
"linkedModules": [],
"topLevelPatterns": [],

View File

@@ -1,15 +1,11 @@
{
"name": "consoleTestUserAddOnly",
"Statement": [
{
"Action": [
"admin:CreateUser"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::*"
]
}
],
"version": "2012-10-17"
"name": "consoleTestUserAddOnly",
"Statement": [
{
"Action": ["admin:CreateUser"],
"Effect": "Allow",
"Resource": ["arn:aws:s3:::*"]
}
],
"version": "2012-10-17"
}

View File

@@ -1,25 +1,25 @@
{
"files": {
"main.css": "/static/css/main.8cfac526.chunk.css",
"main.js": "/static/js/main.f0be6105.chunk.js",
"main.js.map": "/static/js/main.f0be6105.chunk.js.map",
"main.js": "/static/js/main.03b04a1b.chunk.js",
"main.js.map": "/static/js/main.03b04a1b.chunk.js.map",
"runtime-main.js": "/static/js/runtime-main.43a31377.js",
"runtime-main.js.map": "/static/js/runtime-main.43a31377.js.map",
"static/css/2.c5a51b70.chunk.css": "/static/css/2.c5a51b70.chunk.css",
"static/js/2.8df217ff.chunk.js": "/static/js/2.8df217ff.chunk.js",
"static/js/2.8df217ff.chunk.js.map": "/static/js/2.8df217ff.chunk.js.map",
"static/css/2.60e04a19.chunk.css": "/static/css/2.60e04a19.chunk.css",
"static/js/2.d609c10f.chunk.js": "/static/js/2.d609c10f.chunk.js",
"static/js/2.d609c10f.chunk.js.map": "/static/js/2.d609c10f.chunk.js.map",
"index.html": "/index.html",
"static/css/2.c5a51b70.chunk.css.map": "/static/css/2.c5a51b70.chunk.css.map",
"static/css/2.60e04a19.chunk.css.map": "/static/css/2.60e04a19.chunk.css.map",
"static/css/main.8cfac526.chunk.css.map": "/static/css/main.8cfac526.chunk.css.map",
"static/js/2.8df217ff.chunk.js.LICENSE.txt": "/static/js/2.8df217ff.chunk.js.LICENSE.txt",
"static/js/2.d609c10f.chunk.js.LICENSE.txt": "/static/js/2.d609c10f.chunk.js.LICENSE.txt",
"static/media/minio_console_logo.0837460e.svg": "/static/media/minio_console_logo.0837460e.svg",
"static/media/minio_operator_logo.1312b7c9.svg": "/static/media/minio_operator_logo.1312b7c9.svg"
},
"entrypoints": [
"static/js/runtime-main.43a31377.js",
"static/css/2.c5a51b70.chunk.css",
"static/js/2.8df217ff.chunk.js",
"static/css/2.60e04a19.chunk.css",
"static/js/2.d609c10f.chunk.js",
"static/css/main.8cfac526.chunk.css",
"static/js/main.f0be6105.chunk.js"
"static/js/main.03b04a1b.chunk.js"
]
}

View File

@@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="MinIO Console"/><link href="https://fonts.googleapis.com/css2?family=Lato:wght@400;500;700;900&display=swap" rel="stylesheet"/><link rel="apple-touch-icon" sizes="180x180" href="/apple-icon-180x180.png"/><link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"/><link rel="icon" type="image/png" sizes="96x96" href="/favicon-96x96.png"/><link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"/><link rel="manifest" href="/manifest.json"/><link rel="mask-icon" href="/safari-pinned-tab.svg" color="#3a4e54"/><title>MinIO Console</title><link href="/static/css/2.c5a51b70.chunk.css" rel="stylesheet"><link href="/static/css/main.8cfac526.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function r(r){for(var n,l,i=r[0],a=r[1],p=r[2],c=0,s=[];c<i.length;c++)l=i[c],Object.prototype.hasOwnProperty.call(o,l)&&o[l]&&s.push(o[l][0]),o[l]=0;for(n in a)Object.prototype.hasOwnProperty.call(a,n)&&(e[n]=a[n]);for(f&&f(r);s.length;)s.shift()();return u.push.apply(u,p||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,i=1;i<t.length;i++){var a=t[i];0!==o[a]&&(n=!1)}n&&(u.splice(r--,1),e=l(l.s=t[0]))}return e}var n={},o={1:0},u=[];function l(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,l),t.l=!0,t.exports}l.m=e,l.c=n,l.d=function(e,r,t){l.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},l.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},l.t=function(e,r){if(1&r&&(e=l(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(l.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)l.d(t,n,function(r){return e[r]}.bind(null,n));return t},l.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return l.d(r,"a",r),r},l.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},l.p="/";var i=this["webpackJsonpportal-ui"]=this["webpackJsonpportal-ui"]||[],a=i.push.bind(i);i.push=r,i=i.slice();for(var p=0;p<i.length;p++)r(i[p]);var f=a;t()}([])</script><script src="/static/js/2.8df217ff.chunk.js"></script><script src="/static/js/main.f0be6105.chunk.js"></script></body></html>
<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="MinIO Console"/><link href="https://fonts.googleapis.com/css2?family=Lato:wght@400;500;700;900&display=swap" rel="stylesheet"/><link rel="apple-touch-icon" sizes="180x180" href="/apple-icon-180x180.png"/><link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"/><link rel="icon" type="image/png" sizes="96x96" href="/favicon-96x96.png"/><link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"/><link rel="manifest" href="/manifest.json"/><link rel="mask-icon" href="/safari-pinned-tab.svg" color="#3a4e54"/><title>MinIO Console</title><link href="/static/css/2.60e04a19.chunk.css" rel="stylesheet"><link href="/static/css/main.8cfac526.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function r(r){for(var n,l,i=r[0],a=r[1],p=r[2],c=0,s=[];c<i.length;c++)l=i[c],Object.prototype.hasOwnProperty.call(o,l)&&o[l]&&s.push(o[l][0]),o[l]=0;for(n in a)Object.prototype.hasOwnProperty.call(a,n)&&(e[n]=a[n]);for(f&&f(r);s.length;)s.shift()();return u.push.apply(u,p||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,i=1;i<t.length;i++){var a=t[i];0!==o[a]&&(n=!1)}n&&(u.splice(r--,1),e=l(l.s=t[0]))}return e}var n={},o={1:0},u=[];function l(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,l),t.l=!0,t.exports}l.m=e,l.c=n,l.d=function(e,r,t){l.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},l.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},l.t=function(e,r){if(1&r&&(e=l(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(l.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)l.d(t,n,function(r){return e[r]}.bind(null,n));return t},l.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return l.d(r,"a",r),r},l.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},l.p="/";var i=this["webpackJsonpportal-ui"]=this["webpackJsonpportal-ui"]||[],a=i.push.bind(i);i.push=r,i=i.slice();for(var p=0;p<i.length;p++)r(i[p]);var f=a;t()}([])</script><script src="/static/js/2.d609c10f.chunk.js"></script><script src="/static/js/main.03b04a1b.chunk.js"></script></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -711,4 +711,4 @@ export const inlineCheckboxes = {
display: "flex",
justifyContent: "flex-start",
},
}
};

View File

@@ -29,7 +29,7 @@ import {
actionsTray,
containerForHeader,
searchField,
inlineCheckboxes
inlineCheckboxes,
} from "../Common/FormComponents/common/styleLibrary";
import CheckboxWrapper from "../Common/FormComponents/CheckboxWrapper/CheckboxWrapper";
import PageHeader from "../Common/PageHeader/PageHeader";

View File

@@ -17,8 +17,13 @@
import { LicenseInfo } from "../../License/types";
import { IAffinityModel } from "../../../../common/types";
export interface ILog {
log: string;
export interface IEvent {
namespace: string;
last_seen: number;
seen: string;
message: string;
event_type: string;
reason: string;
}
export interface IPool {

View File

@@ -27,13 +27,18 @@ import {
} from "../../Common/FormComponents/common/styleLibrary";
import Grid from "@material-ui/core/Grid";
import { TextField } from "@material-ui/core";
import Tabs from "@material-ui/core/Tabs";
import Tab from "@material-ui/core/Tab";
import TableWrapper from "../../Common/TableWrapper/TableWrapper";
import Paper from "@material-ui/core/Paper";
import api from "../../../../common/api";
import PageHeader from "../../Common/PageHeader/PageHeader";
import { IEvent } from "../ListTenants/types";
import { Link } from "react-router-dom";
import { setErrorSnackMessage } from "../../../../actions";
import InputAdornment from "@material-ui/core/InputAdornment";
import SearchIcon from "@material-ui/icons/Search";
import { niceDays } from "../../../../common/utils";
interface ITenantDetailsProps {
classes: any;
@@ -148,6 +153,8 @@ const TenantDetails = ({
match,
setErrorSnackMessage,
}: ITenantDetailsProps) => {
const [event, setEvent] = useState<IEvent[]>([]);
const [curTab, setCurTab] = useState<number>(0);
const [highlight, setHighlight] = useState<string>("");
const [logLines, setLogLines] = useState<string[]>([]);
const tenantNamespace = match.params["tenantNamespace"];
@@ -199,6 +206,13 @@ const TenantDetails = ({
return renderLog(m, i);
});
function a11yProps(index: any) {
return {
id: `simple-tab-${index}`,
"aria-controls": `simple-tabpanel-${index}`,
};
}
useEffect(() => {
api
.invoke(
@@ -211,7 +225,23 @@ const TenantDetails = ({
.catch((err) => {
setErrorSnackMessage(err);
});
}, [tenantNamespace, tenantName, podName, setErrorSnackMessage]);
api
.invoke(
"GET",
`/api/v1/namespaces/${tenantNamespace}/tenants/${tenantName}/pods/${podName}/events`
)
.then((res: IEvent[]) => {
for (let i = 0; i < res.length; i++) {
let currentTime = (Date.now() / 1000) | 0;
res[i].seen = niceDays((currentTime - res[i].last_seen).toString());
}
setEvent(res);
})
.catch((err) => {
setErrorSnackMessage(err);
});
}, [podName, tenantName, tenantNamespace, setErrorSnackMessage]);
return (
<React.Fragment>
@@ -234,33 +264,71 @@ const TenantDetails = ({
/>
<Grid item xs={12} className={classes.container} />
<Grid container>
<Grid item xs={12} className={classes.actionsTray}>
<TextField
placeholder="Highlight Line"
className={classes.searchField}
id="search-resource"
label=""
onChange={(val) => {
setHighlight(val.target.value);
<Grid item xs={9}>
<Tabs
value={curTab}
onChange={(e: React.ChangeEvent<{}>, newValue: number) => {
setCurTab(newValue);
}}
InputProps={{
disableUnderline: true,
startAdornment: (
<InputAdornment position="start">
<SearchIcon />
</InputAdornment>
),
}}
/>
</Grid>
<Grid item xs={12}>
<br />
</Grid>
<Grid item xs={12}>
<Paper>
<div className={classes.logList}>{renderLines}</div>
</Paper>
indicatorColor="primary"
textColor="primary"
aria-label="cluster-tabs"
variant="scrollable"
scrollButtons="auto"
>
<Tab label="Logs" {...a11yProps(0)} />
<Tab label="Events" {...a11yProps(1)} />
</Tabs>
</Grid>
{curTab === 0 && (
<Fragment>
<Grid item xs={12} className={classes.actionsTray}>
<TextField
placeholder="Highlight Line"
className={classes.searchField}
id="search-resource"
label=""
onChange={(val) => {
setHighlight(val.target.value);
}}
InputProps={{
disableUnderline: true,
startAdornment: (
<InputAdornment position="start">
<SearchIcon />
</InputAdornment>
),
}}
/>
</Grid>
<Grid item xs={12}>
<br />
</Grid>
<Grid item xs={12}>
<Paper>
<div className={classes.logList}>{renderLines}</div>
</Paper>
</Grid>
</Fragment>
)}
{curTab === 1 && (
<Grid item xs={12} className={classes.actionsTray}>
<TableWrapper
itemActions={[]}
columns={[
{ label: "Namespace", elementKey: "namespace" },
{ label: "Last Seen", elementKey: "seen" },
{ label: "Message", elementKey: "message" },
{ label: "Event Type", elementKey: "event_type" },
{ label: "Reason", elementKey: "reason" },
]}
isLoading={false}
records={event}
entityName="Events"
idField="event"
/>
</Grid>
)}
</Grid>
</React.Fragment>
);

View File

@@ -62,7 +62,7 @@ const PodsSummary = ({ match, history }: IPodsSummary) => {
)
.then((result: IPodListElement[]) => {
for (let i = 0; i < result.length; i++) {
let currentTime = new Date().getSeconds();
let currentTime = (Date.now() / 1000) | 0;
result[i].time = niceDays(
(currentTime - parseInt(result[i].timeCreated)).toString()
);

View File

@@ -19,7 +19,11 @@ import { Grid, Button, TextField } from "@material-ui/core";
import { IMessageEvent, w3cwebsocket as W3CWebSocket } from "websocket";
import { AppState } from "../../../store";
import { connect } from "react-redux";
import { traceMessageReceived, traceResetMessages, setTraceStarted } from "./actions";
import {
traceMessageReceived,
traceResetMessages,
setTraceStarted,
} from "./actions";
import { TraceMessage } from "./types";
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
import { niceBytes, timeFromDate } from "../../../common/utils";

View File

@@ -55,6 +55,6 @@ export function traceResetMessages() {
export function setTraceStarted(status: boolean) {
return {
type: TRACE_SET_STARTED,
status
status,
};
}

View File

@@ -51,7 +51,7 @@ export function traceReducer(
return {
...state,
traceStarted: action.status,
}
};
default:
return state;
}

View File

@@ -26,6 +26,7 @@ import (
"net"
"net/http"
"os"
"sort"
"strconv"
"strings"
"time"
@@ -153,6 +154,14 @@ func registerTenantHandlers(api *operations.ConsoleAPI) {
return admin_api.NewGetPodLogsOK().WithPayload(payload)
})
api.AdminAPIGetPodEventsHandler = admin_api.GetPodEventsHandlerFunc(func(params admin_api.GetPodEventsParams, session *models.Principal) middleware.Responder {
payload, err := getPodEventsResponse(session, params)
if err != nil {
return admin_api.NewGetPodEventsDefault(int(err.Code)).WithPayload(err)
}
return admin_api.NewGetPodEventsOK().WithPayload(payload)
})
// Update Tenant Pools
api.AdminAPITenantUpdatePoolsHandler = admin_api.TenantUpdatePoolsHandlerFunc(func(params admin_api.TenantUpdatePoolsParams, session *models.Principal) middleware.Responder {
resp, err := getTenantUpdatePoolResponse(session, params)
@@ -1436,7 +1445,6 @@ func getPodLogsResponse(session *models.Principal, params admin_api.GetPodLogsPa
ctx := context.Background()
clientset, err := cluster.K8sClient(session.STSSessionToken)
if err != nil {
LogError("%v", err)
return "", prepareError(err)
}
listOpts := &corev1.PodLogOptions{}
@@ -1448,6 +1456,36 @@ func getPodLogsResponse(session *models.Principal, params admin_api.GetPodLogsPa
return string(buff), nil
}
func getPodEventsResponse(session *models.Principal, params admin_api.GetPodEventsParams) (models.EventListWrapper, *models.Error) {
ctx := context.Background()
clientset, err := cluster.K8sClient(session.STSSessionToken)
if err != nil {
return nil, prepareError(err)
}
pod, err := clientset.CoreV1().Pods(params.Namespace).Get(ctx, params.PodName, metav1.GetOptions{})
if err != nil {
return nil, prepareError(err)
}
events, err := clientset.CoreV1().Events(params.Namespace).List(ctx, metav1.ListOptions{FieldSelector: fmt.Sprintf("involvedObject.uid=%s", pod.UID)})
if err != nil {
return nil, prepareError(err)
}
retval := models.EventListWrapper{}
for i := 0; i < len(events.Items); i++ {
retval = append(retval, &models.EventListElement{
Namespace: events.Items[i].Namespace,
LastSeen: events.Items[i].LastTimestamp.Unix(),
Message: events.Items[i].Message,
EventType: events.Items[i].Type,
Reason: events.Items[i].Reason,
})
}
sort.SliceStable(retval, func(i int, j int) bool {
return retval[i].LastSeen < retval[j].LastSeen
})
return retval, nil
}
// parseTenantPoolRequest parse pool request and returns the equivalent
// miniov2.Pool object
func parseTenantPoolRequest(poolParams *models.Pool) (*miniov2.Pool, error) {

View File

@@ -2440,36 +2440,6 @@ func init() {
}
}
},
"/namespace": {
"post": {
"tags": [
"AdminAPI"
],
"summary": "Creates a new Namespace with given information",
"operationId": "CreateNamespace",
"parameters": [
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/namespace"
}
}
],
"responses": {
"201": {
"description": "A successful response."
},
"default": {
"description": "Generic error response.",
"schema": {
"$ref": "#/definitions/error"
}
}
}
}
},
"/namespaces/{namespace}/resourcequotas/{resource-quota-name}": {
"get": {
"tags": [
@@ -2935,6 +2905,49 @@ func init() {
}
}
},
"/namespaces/{namespace}/tenants/{tenant}/pods/{podName}/events": {
"get": {
"tags": [
"AdminAPI"
],
"summary": "Get Events for Pod",
"operationId": "GetPodEvents",
"parameters": [
{
"type": "string",
"name": "namespace",
"in": "path",
"required": true
},
{
"type": "string",
"name": "tenant",
"in": "path",
"required": true
},
{
"type": "string",
"name": "podName",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/eventListWrapper"
}
},
"default": {
"description": "Generic error response.",
"schema": {
"$ref": "#/definitions/error"
}
}
}
}
},
"/namespaces/{namespace}/tenants/{tenant}/pools": {
"put": {
"tags": [
@@ -4981,6 +4994,36 @@ func init() {
}
}
},
"eventListElement": {
"type": "object",
"properties": {
"event_type": {
"type": "string"
},
"last_seen": {
"type": "integer",
"format": "int64"
},
"message": {
"type": "string"
},
"namespace": {
"type": "string"
},
"object": {
"type": "string"
},
"reason": {
"type": "string"
}
}
},
"eventListWrapper": {
"type": "array",
"items": {
"$ref": "#/definitions/eventListElement"
}
},
"expirationResponse": {
"type": "object",
"properties": {
@@ -5772,17 +5815,6 @@ func init() {
}
}
},
"namespace": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string"
}
}
},
"nodeLabels": {
"type": "object",
"additionalProperties": {
@@ -9902,36 +9934,6 @@ func init() {
}
}
},
"/namespace": {
"post": {
"tags": [
"AdminAPI"
],
"summary": "Creates a new Namespace with given information",
"operationId": "CreateNamespace",
"parameters": [
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/namespace"
}
}
],
"responses": {
"201": {
"description": "A successful response."
},
"default": {
"description": "Generic error response.",
"schema": {
"$ref": "#/definitions/error"
}
}
}
}
},
"/namespaces/{namespace}/resourcequotas/{resource-quota-name}": {
"get": {
"tags": [
@@ -10397,6 +10399,49 @@ func init() {
}
}
},
"/namespaces/{namespace}/tenants/{tenant}/pods/{podName}/events": {
"get": {
"tags": [
"AdminAPI"
],
"summary": "Get Events for Pod",
"operationId": "GetPodEvents",
"parameters": [
{
"type": "string",
"name": "namespace",
"in": "path",
"required": true
},
{
"type": "string",
"name": "tenant",
"in": "path",
"required": true
},
{
"type": "string",
"name": "podName",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/eventListWrapper"
}
},
"default": {
"description": "Generic error response.",
"schema": {
"$ref": "#/definitions/error"
}
}
}
}
},
"/namespaces/{namespace}/tenants/{tenant}/pools": {
"put": {
"tags": [
@@ -13083,6 +13128,36 @@ func init() {
}
}
},
"eventListElement": {
"type": "object",
"properties": {
"event_type": {
"type": "string"
},
"last_seen": {
"type": "integer",
"format": "int64"
},
"message": {
"type": "string"
},
"namespace": {
"type": "string"
},
"object": {
"type": "string"
},
"reason": {
"type": "string"
}
}
},
"eventListWrapper": {
"type": "array",
"items": {
"$ref": "#/definitions/eventListElement"
}
},
"expirationResponse": {
"type": "object",
"properties": {
@@ -13862,17 +13937,6 @@ func init() {
}
}
},
"namespace": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string"
}
}
},
"nodeLabels": {
"type": "object",
"additionalProperties": {

View File

@@ -0,0 +1,88 @@
// 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 <http://www.gnu.org/licenses/>.
//
package admin_api
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the generate command
import (
"net/http"
"github.com/go-openapi/runtime/middleware"
"github.com/minio/console/models"
)
// GetPodEventsHandlerFunc turns a function with the right signature into a get pod events handler
type GetPodEventsHandlerFunc func(GetPodEventsParams, *models.Principal) middleware.Responder
// Handle executing the request and returning a response
func (fn GetPodEventsHandlerFunc) Handle(params GetPodEventsParams, principal *models.Principal) middleware.Responder {
return fn(params, principal)
}
// GetPodEventsHandler interface for that can handle valid get pod events params
type GetPodEventsHandler interface {
Handle(GetPodEventsParams, *models.Principal) middleware.Responder
}
// NewGetPodEvents creates a new http.Handler for the get pod events operation
func NewGetPodEvents(ctx *middleware.Context, handler GetPodEventsHandler) *GetPodEvents {
return &GetPodEvents{Context: ctx, Handler: handler}
}
/* GetPodEvents swagger:route GET /namespaces/{namespace}/tenants/{tenant}/pods/{podName}/events AdminAPI getPodEvents
Get Events for Pod
*/
type GetPodEvents struct {
Context *middleware.Context
Handler GetPodEventsHandler
}
func (o *GetPodEvents) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
route, rCtx, _ := o.Context.RouteInfo(r)
if rCtx != nil {
*r = *rCtx
}
var Params = NewGetPodEventsParams()
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)
}

View File

@@ -0,0 +1,136 @@
// 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 <http://www.gnu.org/licenses/>.
//
package admin_api
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"net/http"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime/middleware"
"github.com/go-openapi/strfmt"
)
// NewGetPodEventsParams creates a new GetPodEventsParams object
//
// There are no default values defined in the spec.
func NewGetPodEventsParams() GetPodEventsParams {
return GetPodEventsParams{}
}
// GetPodEventsParams contains all the bound params for the get pod events operation
// typically these are obtained from a http.Request
//
// swagger:parameters GetPodEvents
type GetPodEventsParams struct {
// HTTP Request Object
HTTPRequest *http.Request `json:"-"`
/*
Required: true
In: path
*/
Namespace string
/*
Required: true
In: path
*/
PodName 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 NewGetPodEventsParams() beforehand.
func (o *GetPodEventsParams) 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)
}
rPodName, rhkPodName, _ := route.Params.GetOK("podName")
if err := o.bindPodName(rPodName, rhkPodName, 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 *GetPodEventsParams) 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
}
// bindPodName binds and validates parameter PodName from path.
func (o *GetPodEventsParams) bindPodName(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.PodName = raw
return nil
}
// bindTenant binds and validates parameter Tenant from path.
func (o *GetPodEventsParams) 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
}

View File

@@ -0,0 +1,136 @@
// 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 <http://www.gnu.org/licenses/>.
//
package admin_api
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"net/http"
"github.com/go-openapi/runtime"
"github.com/minio/console/models"
)
// GetPodEventsOKCode is the HTTP code returned for type GetPodEventsOK
const GetPodEventsOKCode int = 200
/*GetPodEventsOK A successful response.
swagger:response getPodEventsOK
*/
type GetPodEventsOK struct {
/*
In: Body
*/
Payload models.EventListWrapper `json:"body,omitempty"`
}
// NewGetPodEventsOK creates GetPodEventsOK with default headers values
func NewGetPodEventsOK() *GetPodEventsOK {
return &GetPodEventsOK{}
}
// WithPayload adds the payload to the get pod events o k response
func (o *GetPodEventsOK) WithPayload(payload models.EventListWrapper) *GetPodEventsOK {
o.Payload = payload
return o
}
// SetPayload sets the payload to the get pod events o k response
func (o *GetPodEventsOK) SetPayload(payload models.EventListWrapper) {
o.Payload = payload
}
// WriteResponse to the client
func (o *GetPodEventsOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(200)
payload := o.Payload
if payload == nil {
// return empty array
payload = models.EventListWrapper{}
}
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}
/*GetPodEventsDefault Generic error response.
swagger:response getPodEventsDefault
*/
type GetPodEventsDefault struct {
_statusCode int
/*
In: Body
*/
Payload *models.Error `json:"body,omitempty"`
}
// NewGetPodEventsDefault creates GetPodEventsDefault with default headers values
func NewGetPodEventsDefault(code int) *GetPodEventsDefault {
if code <= 0 {
code = 500
}
return &GetPodEventsDefault{
_statusCode: code,
}
}
// WithStatusCode adds the status to the get pod events default response
func (o *GetPodEventsDefault) WithStatusCode(code int) *GetPodEventsDefault {
o._statusCode = code
return o
}
// SetStatusCode sets the status to the get pod events default response
func (o *GetPodEventsDefault) SetStatusCode(code int) {
o._statusCode = code
}
// WithPayload adds the payload to the get pod events default response
func (o *GetPodEventsDefault) WithPayload(payload *models.Error) *GetPodEventsDefault {
o.Payload = payload
return o
}
// SetPayload sets the payload to the get pod events default response
func (o *GetPodEventsDefault) SetPayload(payload *models.Error) {
o.Payload = payload
}
// WriteResponse to the client
func (o *GetPodEventsDefault) 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
}
}
}

View File

@@ -0,0 +1,132 @@
// 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 <http://www.gnu.org/licenses/>.
//
package admin_api
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the generate command
import (
"errors"
"net/url"
golangswaggerpaths "path"
"strings"
)
// GetPodEventsURL generates an URL for the get pod events operation
type GetPodEventsURL struct {
Namespace string
PodName 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 *GetPodEventsURL) WithBasePath(bp string) *GetPodEventsURL {
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 *GetPodEventsURL) SetBasePath(bp string) {
o._basePath = bp
}
// Build a url path and query string
func (o *GetPodEventsURL) Build() (*url.URL, error) {
var _result url.URL
var _path = "/namespaces/{namespace}/tenants/{tenant}/pods/{podName}/events"
namespace := o.Namespace
if namespace != "" {
_path = strings.Replace(_path, "{namespace}", namespace, -1)
} else {
return nil, errors.New("namespace is required on GetPodEventsURL")
}
podName := o.PodName
if podName != "" {
_path = strings.Replace(_path, "{podName}", podName, -1)
} else {
return nil, errors.New("podName is required on GetPodEventsURL")
}
tenant := o.Tenant
if tenant != "" {
_path = strings.Replace(_path, "{tenant}", tenant, -1)
} else {
return nil, errors.New("tenant is required on GetPodEventsURL")
}
_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 *GetPodEventsURL) 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 *GetPodEventsURL) String() string {
return o.Must(o.Build()).String()
}
// BuildFull builds a full url with scheme, host, path and query string
func (o *GetPodEventsURL) BuildFull(scheme, host string) (*url.URL, error) {
if scheme == "" {
return nil, errors.New("scheme is required for a full url on GetPodEventsURL")
}
if host == "" {
return nil, errors.New("host is required for a full url on GetPodEventsURL")
}
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 *GetPodEventsURL) StringFull(scheme, host string) string {
return o.Must(o.BuildFull(scheme, host)).String()
}

View File

@@ -198,6 +198,9 @@ func NewConsoleAPI(spec *loads.Document) *ConsoleAPI {
AdminAPIGetParityHandler: admin_api.GetParityHandlerFunc(func(params admin_api.GetParityParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation admin_api.GetParity has not yet been implemented")
}),
AdminAPIGetPodEventsHandler: admin_api.GetPodEventsHandlerFunc(func(params admin_api.GetPodEventsParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation admin_api.GetPodEvents has not yet been implemented")
}),
AdminAPIGetPodLogsHandler: admin_api.GetPodLogsHandlerFunc(func(params admin_api.GetPodLogsParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation admin_api.GetPodLogs has not yet been implemented")
}),
@@ -563,6 +566,8 @@ type ConsoleAPI struct {
AdminAPIGetMaxAllocatableMemHandler admin_api.GetMaxAllocatableMemHandler
// AdminAPIGetParityHandler sets the operation handler for the get parity operation
AdminAPIGetParityHandler admin_api.GetParityHandler
// AdminAPIGetPodEventsHandler sets the operation handler for the get pod events operation
AdminAPIGetPodEventsHandler admin_api.GetPodEventsHandler
// AdminAPIGetPodLogsHandler sets the operation handler for the get pod logs operation
AdminAPIGetPodLogsHandler admin_api.GetPodLogsHandler
// AdminAPIGetResourceQuotaHandler sets the operation handler for the get resource quota operation
@@ -930,6 +935,9 @@ func (o *ConsoleAPI) Validate() error {
if o.AdminAPIGetParityHandler == nil {
unregistered = append(unregistered, "admin_api.GetParityHandler")
}
if o.AdminAPIGetPodEventsHandler == nil {
unregistered = append(unregistered, "admin_api.GetPodEventsHandler")
}
if o.AdminAPIGetPodLogsHandler == nil {
unregistered = append(unregistered, "admin_api.GetPodLogsHandler")
}
@@ -1433,6 +1441,10 @@ func (o *ConsoleAPI) initHandlerCache() {
if o.handlers["GET"] == nil {
o.handlers["GET"] = make(map[string]http.Handler)
}
o.handlers["GET"]["/namespaces/{namespace}/tenants/{tenant}/pods/{podName}/events"] = admin_api.NewGetPodEvents(o.context, o.AdminAPIGetPodEventsHandler)
if o.handlers["GET"] == nil {
o.handlers["GET"] = make(map[string]http.Handler)
}
o.handlers["GET"]["/namespaces/{namespace}/tenants/{tenant}/pods/{podName}"] = admin_api.NewGetPodLogs(o.context, o.AdminAPIGetPodLogsHandler)
if o.handlers["GET"] == nil {
o.handlers["GET"] = make(map[string]http.Handler)

View File

@@ -2505,6 +2505,35 @@ paths:
tags:
- AdminAPI
/namespaces/{namespace}/tenants/{tenant}/pods/{podName}/events:
get:
summary: Get Events for Pod
operationId: GetPodEvents
parameters:
- name: namespace
in: path
required: true
type: string
- name: tenant
in: path
required: true
type: string
- name: podName
in: path
required: true
type: string
responses:
200:
description: A successful response.
schema:
$ref: "#/definitions/eventListWrapper"
default:
description: Generic error response.
schema:
$ref: "#/definitions/error"
tags:
- AdminAPI
/namespaces/{namespace}/tenants/{tenant}/certificates:
put:
summary: Tenant Update Certificates
@@ -5311,3 +5340,24 @@ definitions:
name:
type: string
eventListWrapper:
type: array
items:
$ref: "#/definitions/eventListElement"
eventListElement:
type: object
properties:
namespace:
type: string
last_seen:
type: integer
format: int64
event_type:
type: string
reason:
type: string
object:
type: string
message:
type: string