Pod Details (#789)

* Introduce dropdowns for node selector screen on affinity

Fixes https://github.com/miniohq/engineering/issues/138

Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>

* pod logs

* fixing test cases

* adding paper

* style for pod logs

* dealing with style errors

* Delete logs.log

* using new Affinity.tsx

* moving loadinfo

* moving loadinfo and adding dependencies

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-07 18:56:05 -07:00
committed by GitHub
parent 69055c492e
commit ecab89f7fb
19 changed files with 1240 additions and 5 deletions

View File

@@ -43,6 +43,7 @@ var (
changePassword = "/account/change-password"
tenants = "/tenants"
tenantsDetail = "/namespaces/:tenantNamespace/tenants/:tenantName"
podsDetail = "/namespaces/:tenantNamespace/tenants/:tenantName/pods/:podName"
storage = "/storage"
storageVolumes = "/storage/volumes"
storageDrives = "/storage/drives"
@@ -319,6 +320,7 @@ var endpointRules = map[string]ConfigurationActionSet{
var operatorRules = map[string]ConfigurationActionSet{
tenants: tenantsActionSet,
tenantsDetail: tenantsActionSet,
podsDetail: tenantsActionSet,
storage: storageActionSet,
storageDrives: storageActionSet,
storageVolumes: storageActionSet,

View File

@@ -116,7 +116,7 @@ func TestOperatorOnlyEndpoints(t *testing.T) {
"admin:*",
},
},
want: 6,
want: 7,
},
{
name: "Operator Only - all s3 endpoints",
@@ -125,7 +125,7 @@ func TestOperatorOnlyEndpoints(t *testing.T) {
"s3:*",
},
},
want: 6,
want: 7,
},
{
name: "Operator Only - all admin and s3 endpoints",
@@ -135,14 +135,14 @@ func TestOperatorOnlyEndpoints(t *testing.T) {
"s3:*",
},
},
want: 6,
want: 7,
},
{
name: "Operator Only - default endpoints",
args: args{
[]string{},
},
want: 6,
want: 7,
},
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,271 @@
/*
object-assign
(c) Sindre Sorhus
@license MIT
*/
/*!
Copyright (c) 2017 Jed Watson.
Licensed under the MIT License (MIT), see
http://jedwatson.github.io/classnames
*/
/*!
* Chart.js v2.9.4
* https://www.chartjs.org
* (c) 2020 Chart.js Contributors
* Released under the MIT License
*/
/*!
* cookie
* Copyright(c) 2012-2014 Roman Shtylman
* Copyright(c) 2015 Douglas Christopher Wilson
* MIT Licensed
*/
/*! Conditions:: INITIAL */
/*! Moment Duration Format v2.2.2
* https://github.com/jsmreese/moment-duration-format
* Date: 2018-02-16
*
* Duration format plugin function for the Moment.js library
* http://momentjs.com/
*
* Copyright 2018 John Madhavan-Reese
* Released under the MIT license
*/
/*! Production:: $accept : expression $end */
/*! Production:: css_value : ANGLE */
/*! Production:: css_value : CHS */
/*! Production:: css_value : EMS */
/*! Production:: css_value : EXS */
/*! Production:: css_value : FREQ */
/*! Production:: css_value : LENGTH */
/*! Production:: css_value : PERCENTAGE */
/*! Production:: css_value : REMS */
/*! Production:: css_value : RES */
/*! Production:: css_value : SUB css_value */
/*! Production:: css_value : TIME */
/*! Production:: css_value : VHS */
/*! Production:: css_value : VMAXS */
/*! Production:: css_value : VMINS */
/*! Production:: css_value : VWS */
/*! Production:: css_variable : CSS_VAR LPAREN CSS_CPROP COMMA math_expression RPAREN */
/*! Production:: css_variable : CSS_VAR LPAREN CSS_CPROP RPAREN */
/*! Production:: expression : math_expression EOF */
/*! Production:: math_expression : LPAREN math_expression RPAREN */
/*! Production:: math_expression : NESTED_CALC LPAREN math_expression RPAREN */
/*! Production:: math_expression : SUB PREFIX SUB NESTED_CALC LPAREN math_expression RPAREN */
/*! Production:: math_expression : css_value */
/*! Production:: math_expression : css_variable */
/*! Production:: math_expression : math_expression ADD math_expression */
/*! Production:: math_expression : math_expression DIV math_expression */
/*! Production:: math_expression : math_expression MUL math_expression */
/*! Production:: math_expression : math_expression SUB math_expression */
/*! Production:: math_expression : value */
/*! Production:: value : NUMBER */
/*! Production:: value : SUB NUMBER */
/*! Rule:: $ */
/*! Rule:: (--[0-9a-z-A-Z-]*) */
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)% */
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)Hz\b */
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)\b */
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)ch\b */
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)cm\b */
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)deg\b */
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)dpcm\b */
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)dpi\b */
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)dppx\b */
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)em\b */
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)ex\b */
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)grad\b */
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)in\b */
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)kHz\b */
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)mm\b */
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)ms\b */
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)pc\b */
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)pt\b */
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)px\b */
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)rad\b */
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)rem\b */
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)s\b */
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)turn\b */
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)vh\b */
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)vmax\b */
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)vmin\b */
/*! Rule:: ([0-9]+(\.[0-9]*)?|\.[0-9]+)vw\b */
/*! Rule:: ([a-z]+) */
/*! Rule:: (calc) */
/*! Rule:: (var) */
/*! Rule:: , */
/*! Rule:: - */
/*! Rule:: \( */
/*! Rule:: \) */
/*! Rule:: \* */
/*! Rule:: \+ */
/*! Rule:: \/ */
/*! Rule:: \s+ */
/*! decimal.js-light v2.5.1 https://github.com/MikeMcl/decimal.js-light/LICENCE */
/**
* A better abstraction over CSS.
*
* @copyright Oleg Isonen (Slobodskoi) / Isonen 2014-present
* @website https://github.com/cssinjs/jss
* @license MIT
*/
/** @license React v0.20.1
* scheduler.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/** @license React v16.13.1
* react-is.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/** @license React v17.0.1
* react-dom.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/** @license React v17.0.1
* react-is.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/** @license React v17.0.1
* react-jsx-runtime.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/** @license React v17.0.1
* react.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**!
* @fileOverview Kickass library to create and place poppers near their reference elements.
* @version 1.16.1-lts
* @license
* Copyright (c) 2016 Federico Zivolo and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
//! moment.js

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

@@ -56,6 +56,7 @@ import Heal from "./Heal/Heal";
import Watch from "./Watch/Watch";
import HealthInfo from "./HealthInfo/HealthInfo";
import Storage from "./Storage/Storage";
import PodDetails from "./Tenants/TenantDetails/PodDetails";
const drawerWidth = 245;
@@ -353,6 +354,10 @@ const Console = ({
component: TenantDetails,
path: "/namespaces/:tenantNamespace/tenants/:tenantName",
},
{
component: PodDetails,
path: "/namespaces/:tenantNamespace/tenants/:tenantName/pods/:podName",
},
{
component: License,
path: "/license",

View File

@@ -17,6 +17,10 @@
import { LicenseInfo } from "../../License/types";
import { IAffinityModel } from "../../../../common/types";
export interface ILog {
log: string
}
export interface IPool {
name: string;
servers: number;

View File

@@ -0,0 +1,293 @@
// 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/>.
import React, { Fragment, useEffect, useState } from "react";
import { connect } from "react-redux";
import get from "lodash/get";
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
import {
actionsTray,
buttonsStyles,
containerForHeader,
hrClass,
modalBasic,
searchField,
} from "../../Common/FormComponents/common/styleLibrary";
import Grid from "@material-ui/core/Grid";
import {
Button,
IconButton,
Menu,
MenuItem,
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 { ILog, ITenant } from "../ListTenants/types";
import { LicenseInfo } from "../../License/types";
import { Link } from "react-router-dom";
import { setErrorSnackMessage } from "../../../../actions";
import MoreVertIcon from "@material-ui/icons/MoreVert";
import TenantYAML from "./TenantYAML";
import SubnetLicenseTenant from "./SubnetLicenseTenant";
import InputAdornment from "@material-ui/core/InputAdornment";
import SearchIcon from "@material-ui/icons/Search";
import history from "../../../../history";
import { LogMessage } from "../../Logs/types";
interface ITenantDetailsProps {
classes: any;
match: any;
setErrorSnackMessage: typeof setErrorSnackMessage;
}
const styles = (theme: Theme) =>
createStyles({
logList: {
background: "#fff",
minHeight: 400,
height: "calc(100vh - 304px)",
overflow: "auto",
fontSize: 13,
padding: "25px 45px 0",
border: "1px solid #EAEDEE",
borderRadius: 4,
},
buttonContainer: {
textAlign: "right",
},
multiContainer: {
display: "flex",
alignItems: "center" as const,
justifyContent: "flex-start" as const,
},
sizeFactorContainer: {
marginLeft: 8,
},
containerHeader: {
display: "flex",
justifyContent: "space-between",
},
paperContainer: {
padding: "15px 15px 15px 50px",
},
infoGrid: {
display: "grid",
gridTemplateColumns: "auto auto auto auto",
gridGap: 8,
"& div": {
display: "flex",
alignItems: "center",
},
"& div:nth-child(odd)": {
justifyContent: "flex-end",
fontWeight: 700,
},
"& div:nth-child(2n)": {
paddingRight: 35,
},
},
masterActions: {
width: "25%",
minWidth: "120px",
"& div": {
margin: "5px 0px",
},
},
updateButton: {
backgroundColor: "transparent",
border: 0,
padding: "0 6px",
cursor: "pointer",
"&:focus, &:active": {
outline: "none",
},
"& svg": {
height: 12,
},
},
poolLabel: {
color: "#666666",
},
titleCol: {
fontWeight: "bold",
},
breadcrumLink: {
textDecoration: "none",
color: "black",
},
...modalBasic,
...actionsTray,
...buttonsStyles,
...searchField,
...hrClass,
actionsTray: {
...actionsTray.actionsTray,
padding: "15px 0 0",
},
logerror: {
color: "#A52A2A",
},
logerror_tab: {
color: "#A52A2A",
paddingLeft: 25,
},
ansidefault: {
color: "#000",
},
highlight: {
"& span": {
backgroundColor: "#082F5238",
},
},
...containerForHeader(theme.spacing(4)),
});
const TenantDetails = ({
classes,
match,
setErrorSnackMessage,
}: ITenantDetailsProps) => {
const [selectedTab, setSelectedTab] = useState<number>(0);
const [log, setLog] = useState<string>("");
const [highlight, setHighlight] = useState<string>("");
const [logLines, setLogLines] = useState<string[]>([]);
const tenantNamespace = match.params["tenantNamespace"];
const tenantName = match.params["tenantName"];
const podName = match.params["podName"];
const renderLog = (logMessage: string, index: number) => {
// remove any non ascii characters, exclude any control codes
logMessage = logMessage.replace(/([^\x20-\x7F])/g, "");
// regex for terminal colors like e.g. `[31;4m `
const tColorRegex = /((\[[0-9;]+m))/g;
// get substring if there was a match for to split what
// is going to be colored and what not, here we add color
// only to the first match.
let substr = logMessage.replace(tColorRegex, "");
// in case highlight is set, we select the line that contains the requested string
let highlightedLine =
highlight !== ""
? logMessage.toLowerCase().includes(highlight.toLowerCase())
: false;
// if starts with multiple spaces add padding
if (substr.startsWith(" ")) {
return (
<div
key={index}
className={`${highlightedLine ? classes.highlight : ""}`}
>
<span className={classes.tab}>{substr}</span>
</div>
);
} else {
// for all remaining set default class
return (
<div
key={index}
className={`${highlightedLine ? classes.highlight : ""}`}
>
<span className={classes.ansidefault}>{substr}</span>
</div>
);
}
};
const renderLines = logLines.map((m, i) => {
return renderLog(m, i);
});
useEffect(() => {
api
.invoke(
"GET",
`/api/v1/namespaces/${tenantNamespace}/tenants/${tenantName}/pods/${podName}`
)
.then((res: string) => {
setLog(res);
setLogLines(res.split("\n"));
})
.catch((err) => {
setErrorSnackMessage(err);
});
}, [tenantNamespace, tenantName, podName]);
return (
<React.Fragment>
<PageHeader
label={
<Fragment>
<Link to={"/tenants"} className={classes.breadcrumLink}>
Tenants
</Link>
{" > "}
<Link
to={`/namespaces/${tenantNamespace}/tenants/${tenantName}`}
className={classes.breadcrumLink}
>
{tenantName}
</Link>
{` > Pods > ${podName}`}
</Fragment>
}
/>
<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);
}}
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>
</Grid>
</React.Fragment>
);
};
const connector = connect(null, {
setErrorSnackMessage,
});
export default withStyles(styles)(connector(TenantDetails));

View File

@@ -56,6 +56,7 @@ import TenantYAML from "./TenantYAML";
import SubnetLicenseTenant from "./SubnetLicenseTenant";
import InputAdornment from "@material-ui/core/InputAdornment";
import SearchIcon from "@material-ui/icons/Search";
import history from "../../../../history";
interface ITenantDetailsProps {
classes: any;
@@ -347,6 +348,14 @@ const TenantDetails = ({
const [anchorEl, setAnchorEl] = React.useState(null);
const podViewAction = (pod: IPodListElement) => {
history.push(
`/namespaces/${tenantNamespace}/tenants/${tenantName}/pods/${pod.name}`
);
return;
};
const podTableActions = [{ type: "view", onClick: podViewAction }];
const handleTenantMenu = (event: any) => {
setAnchorEl(event.currentTarget);
};
@@ -738,6 +747,7 @@ const TenantDetails = ({
<React.Fragment>
<br />
<TableWrapper
itemActions={podTableActions}
columns={[
{ label: "Name", elementKey: "name" },
{ label: "Status", elementKey: "status" },

View File

@@ -145,6 +145,14 @@ func registerTenantHandlers(api *operations.ConsoleAPI) {
return admin_api.NewGetTenantPodsOK().WithPayload(payload)
})
api.AdminAPIGetPodLogsHandler = admin_api.GetPodLogsHandlerFunc(func(params admin_api.GetPodLogsParams, session *models.Principal) middleware.Responder {
payload, err := getPodLogsResponse(session, params)
if err != nil {
return admin_api.NewGetPodLogsDefault(int(err.Code)).WithPayload(err)
}
return admin_api.NewGetPodLogsOK().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)
@@ -1404,7 +1412,8 @@ func getTenantPodsResponse(session *models.Principal, params admin_api.GetTenant
if len(pod.Status.ContainerStatuses) > 0 {
restarts = int64(pod.Status.ContainerStatuses[0].RestartCount)
}
retval = append(retval, &models.TenantPod{Name: &pod.ObjectMeta.Name,
retval = append(retval, &models.TenantPod{
Name: swag.String(pod.Name),
Status: string(pod.Status.Phase),
TimeCreated: pod.CreationTimestamp.Unix(),
PodIP: pod.Status.PodIP,
@@ -1414,6 +1423,21 @@ func getTenantPodsResponse(session *models.Principal, params admin_api.GetTenant
return retval, nil
}
func getPodLogsResponse(session *models.Principal, params admin_api.GetPodLogsParams) (string, *models.Error) {
ctx := context.Background()
clientset, err := cluster.K8sClient(session.STSSessionToken)
if err != nil {
return "", prepareError(err)
}
listOpts := &corev1.PodLogOptions{}
logs := clientset.CoreV1().Pods(params.Namespace).GetLogs(params.PodName, listOpts)
buff, err := logs.DoRaw(ctx)
if err != nil {
return "", prepareError(err)
}
return string(buff), nil
}
// parseTenantPoolRequest parse pool request and returns the equivalent
// miniov2.Pool object
func parseTenantPoolRequest(poolParams *models.Pool) (*miniov2.Pool, error) {

View File

@@ -2765,6 +2765,49 @@ func init() {
}
}
},
"/namespaces/{namespace}/tenants/{tenant}/pods/{podName}": {
"get": {
"tags": [
"AdminAPI"
],
"summary": "Get Logs for Pod",
"operationId": "GetPodLogs",
"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": {
"type": "string"
}
},
"default": {
"description": "Generic error response.",
"schema": {
"$ref": "#/definitions/error"
}
}
}
}
},
"/namespaces/{namespace}/tenants/{tenant}/pools": {
"put": {
"tags": [
@@ -10046,6 +10089,49 @@ func init() {
}
}
},
"/namespaces/{namespace}/tenants/{tenant}/pods/{podName}": {
"get": {
"tags": [
"AdminAPI"
],
"summary": "Get Logs for Pod",
"operationId": "GetPodLogs",
"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": {
"type": "string"
}
},
"default": {
"description": "Generic error response.",
"schema": {
"$ref": "#/definitions/error"
}
}
}
}
},
"/namespaces/{namespace}/tenants/{tenant}/pools": {
"put": {
"tags": [

View File

@@ -0,0 +1,90 @@
// 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"
)
// GetPodLogsHandlerFunc turns a function with the right signature into a get pod logs handler
type GetPodLogsHandlerFunc func(GetPodLogsParams, *models.Principal) middleware.Responder
// Handle executing the request and returning a response
func (fn GetPodLogsHandlerFunc) Handle(params GetPodLogsParams, principal *models.Principal) middleware.Responder {
return fn(params, principal)
}
// GetPodLogsHandler interface for that can handle valid get pod logs params
type GetPodLogsHandler interface {
Handle(GetPodLogsParams, *models.Principal) middleware.Responder
}
// NewGetPodLogs creates a new http.Handler for the get pod logs operation
func NewGetPodLogs(ctx *middleware.Context, handler GetPodLogsHandler) *GetPodLogs {
return &GetPodLogs{Context: ctx, Handler: handler}
}
/*GetPodLogs swagger:route GET /namespaces/{namespace}/tenants/{tenant}/pods/{podName} AdminAPI getPodLogs
Get Logs for Pod
*/
type GetPodLogs struct {
Context *middleware.Context
Handler GetPodLogsHandler
}
func (o *GetPodLogs) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
route, rCtx, _ := o.Context.RouteInfo(r)
if rCtx != nil {
r = rCtx
}
var Params = NewGetPodLogsParams()
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,139 @@
// 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"
)
// NewGetPodLogsParams creates a new GetPodLogsParams object
// no default values defined in spec.
func NewGetPodLogsParams() GetPodLogsParams {
return GetPodLogsParams{}
}
// GetPodLogsParams contains all the bound params for the get pod logs operation
// typically these are obtained from a http.Request
//
// swagger:parameters GetPodLogs
type GetPodLogsParams 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 NewGetPodLogsParams() beforehand.
func (o *GetPodLogsParams) 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 *GetPodLogsParams) 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 *GetPodLogsParams) 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 *GetPodLogsParams) 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,131 @@
// 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"
)
// GetPodLogsOKCode is the HTTP code returned for type GetPodLogsOK
const GetPodLogsOKCode int = 200
/*GetPodLogsOK A successful response.
swagger:response getPodLogsOK
*/
type GetPodLogsOK struct {
/*
In: Body
*/
Payload string `json:"body,omitempty"`
}
// NewGetPodLogsOK creates GetPodLogsOK with default headers values
func NewGetPodLogsOK() *GetPodLogsOK {
return &GetPodLogsOK{}
}
// WithPayload adds the payload to the get pod logs o k response
func (o *GetPodLogsOK) WithPayload(payload string) *GetPodLogsOK {
o.Payload = payload
return o
}
// SetPayload sets the payload to the get pod logs o k response
func (o *GetPodLogsOK) SetPayload(payload string) {
o.Payload = payload
}
// WriteResponse to the client
func (o *GetPodLogsOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(200)
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}
/*GetPodLogsDefault Generic error response.
swagger:response getPodLogsDefault
*/
type GetPodLogsDefault struct {
_statusCode int
/*
In: Body
*/
Payload *models.Error `json:"body,omitempty"`
}
// NewGetPodLogsDefault creates GetPodLogsDefault with default headers values
func NewGetPodLogsDefault(code int) *GetPodLogsDefault {
if code <= 0 {
code = 500
}
return &GetPodLogsDefault{
_statusCode: code,
}
}
// WithStatusCode adds the status to the get pod logs default response
func (o *GetPodLogsDefault) WithStatusCode(code int) *GetPodLogsDefault {
o._statusCode = code
return o
}
// SetStatusCode sets the status to the get pod logs default response
func (o *GetPodLogsDefault) SetStatusCode(code int) {
o._statusCode = code
}
// WithPayload adds the payload to the get pod logs default response
func (o *GetPodLogsDefault) WithPayload(payload *models.Error) *GetPodLogsDefault {
o.Payload = payload
return o
}
// SetPayload sets the payload to the get pod logs default response
func (o *GetPodLogsDefault) SetPayload(payload *models.Error) {
o.Payload = payload
}
// WriteResponse to the client
func (o *GetPodLogsDefault) 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"
)
// GetPodLogsURL generates an URL for the get pod logs operation
type GetPodLogsURL 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 *GetPodLogsURL) WithBasePath(bp string) *GetPodLogsURL {
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 *GetPodLogsURL) SetBasePath(bp string) {
o._basePath = bp
}
// Build a url path and query string
func (o *GetPodLogsURL) Build() (*url.URL, error) {
var _result url.URL
var _path = "/namespaces/{namespace}/tenants/{tenant}/pods/{podName}"
namespace := o.Namespace
if namespace != "" {
_path = strings.Replace(_path, "{namespace}", namespace, -1)
} else {
return nil, errors.New("namespace is required on GetPodLogsURL")
}
podName := o.PodName
if podName != "" {
_path = strings.Replace(_path, "{podName}", podName, -1)
} else {
return nil, errors.New("podName is required on GetPodLogsURL")
}
tenant := o.Tenant
if tenant != "" {
_path = strings.Replace(_path, "{tenant}", tenant, -1)
} else {
return nil, errors.New("tenant is required on GetPodLogsURL")
}
_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 *GetPodLogsURL) 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 *GetPodLogsURL) String() string {
return o.Must(o.Build()).String()
}
// BuildFull builds a full url with scheme, host, path and query string
func (o *GetPodLogsURL) BuildFull(scheme, host string) (*url.URL, error) {
if scheme == "" {
return nil, errors.New("scheme is required for a full url on GetPodLogsURL")
}
if host == "" {
return nil, errors.New("host is required for a full url on GetPodLogsURL")
}
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 *GetPodLogsURL) StringFull(scheme, host string) string {
return o.Must(o.BuildFull(scheme, host)).String()
}

View File

@@ -194,6 +194,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")
}),
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")
}),
AdminAPIGetResourceQuotaHandler: admin_api.GetResourceQuotaHandlerFunc(func(params admin_api.GetResourceQuotaParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation admin_api.GetResourceQuota has not yet been implemented")
}),
@@ -545,6 +548,8 @@ type ConsoleAPI struct {
AdminAPIGetMaxAllocatableMemHandler admin_api.GetMaxAllocatableMemHandler
// AdminAPIGetParityHandler sets the operation handler for the get parity operation
AdminAPIGetParityHandler admin_api.GetParityHandler
// 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
AdminAPIGetResourceQuotaHandler admin_api.GetResourceQuotaHandler
// AdminAPIGetTenantPodsHandler sets the operation handler for the get tenant pods operation
@@ -892,6 +897,9 @@ func (o *ConsoleAPI) Validate() error {
if o.AdminAPIGetParityHandler == nil {
unregistered = append(unregistered, "admin_api.GetParityHandler")
}
if o.AdminAPIGetPodLogsHandler == nil {
unregistered = append(unregistered, "admin_api.GetPodLogsHandler")
}
if o.AdminAPIGetResourceQuotaHandler == nil {
unregistered = append(unregistered, "admin_api.GetResourceQuotaHandler")
}
@@ -1382,6 +1390,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}"] = admin_api.NewGetPodLogs(o.context, o.AdminAPIGetPodLogsHandler)
if o.handlers["GET"] == nil {
o.handlers["GET"] = make(map[string]http.Handler)
}
o.handlers["GET"]["/namespaces/{namespace}/resourcequotas/{resource-quota-name}"] = admin_api.NewGetResourceQuota(o.context, o.AdminAPIGetResourceQuotaHandler)
if o.handlers["GET"] == nil {
o.handlers["GET"] = make(map[string]http.Handler)

View File

@@ -2392,6 +2392,35 @@ paths:
tags:
- AdminAPI
/namespaces/{namespace}/tenants/{tenant}/pods/{podName}:
get:
summary: Get Logs for Pod
operationId: GetPodLogs
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:
type: string
default:
description: Generic error response.
schema:
$ref: "#/definitions/error"
tags:
- AdminAPI
/namespaces/{namespace}/tenants/{tenant}/certificates:
put:
summary: Tenant Update Certificates