Fix Hop hiding menu (#1621)
* Fix Hop hiding menu Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com> * Fix Menu Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
This commit is contained in:
@@ -140,7 +140,7 @@ func AuthenticationMiddleware(next http.Handler) http.Handler {
|
||||
// proxyMiddleware adds the proxy capability
|
||||
func proxyMiddleware(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if strings.HasPrefix(r.URL.Path, "/api/proxy") {
|
||||
if strings.HasPrefix(r.URL.Path, "/api/proxy") || strings.HasPrefix(r.URL.Path, "/api/hop") {
|
||||
serveProxy(w, r)
|
||||
} else {
|
||||
next.ServeHTTP(w, r)
|
||||
|
||||
@@ -18,6 +18,8 @@ package operatorapi
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
@@ -174,6 +176,8 @@ func getLoginOperatorResponse(lmr *models.LoginOperatorRequest) (*models.LoginRe
|
||||
return nil, prepareError(err)
|
||||
}
|
||||
consoleCreds := restapi.ConsoleCredentials{ConsoleCredentials: creds}
|
||||
// Set a random as access key as session identifier
|
||||
consoleCreds.AccountAccessKey = fmt.Sprintf("%d", rand.Intn(100000-10000)+10000)
|
||||
token, err := login(consoleCreds)
|
||||
if err != nil {
|
||||
return nil, prepareError(errInvalidCredentials, nil, err)
|
||||
|
||||
@@ -41,6 +41,8 @@ import (
|
||||
|
||||
func serveProxy(responseWriter http.ResponseWriter, req *http.Request) {
|
||||
urlParts := strings.Split(req.URL.Path, "/")
|
||||
// Either proxy or hop, will decide the type of session
|
||||
proxyMethod := urlParts[2]
|
||||
|
||||
if len(urlParts) < 5 {
|
||||
log.Println(len(urlParts))
|
||||
@@ -99,7 +101,7 @@ func serveProxy(responseWriter http.ResponseWriter, req *http.Request) {
|
||||
|
||||
h := sha1.New()
|
||||
h.Write([]byte(nsTenant))
|
||||
tenantCookieName := fmt.Sprintf("token-%x", string(h.Sum(nil)))
|
||||
tenantCookieName := fmt.Sprintf("token-%s-%s-%x", proxyMethod, claims.AccountAccessKey, string(h.Sum(nil)))
|
||||
tenantCookie, err := req.Cookie(tenantCookieName)
|
||||
if err != nil {
|
||||
// login to tenantName
|
||||
@@ -126,9 +128,12 @@ func serveProxy(responseWriter http.ResponseWriter, req *http.Request) {
|
||||
data := map[string]interface{}{
|
||||
"accessKey": tenantConfiguration["accesskey"],
|
||||
"secretKey": tenantConfiguration["secretkey"],
|
||||
"features": map[string]bool{
|
||||
}
|
||||
// if this a proxy request hide the menu
|
||||
if proxyMethod == "proxy" {
|
||||
data["features"] = map[string]bool{
|
||||
"hide_menu": true,
|
||||
},
|
||||
}
|
||||
}
|
||||
payload, _ := json.Marshal(data)
|
||||
|
||||
@@ -188,7 +193,7 @@ func serveProxy(responseWriter http.ResponseWriter, req *http.Request) {
|
||||
responseWriter.WriteHeader(500)
|
||||
return
|
||||
}
|
||||
tenantBase := fmt.Sprintf("/api/proxy/%s/%s", tenant.Namespace, tenant.Name)
|
||||
tenantBase := fmt.Sprintf("/api/%s/%s/%s", proxyMethod, tenant.Namespace, tenant.Name)
|
||||
targetURL.Path = strings.Replace(req.URL.Path, tenantBase, "", -1)
|
||||
|
||||
proxiedCookie := &http.Cookie{
|
||||
|
||||
@@ -18,20 +18,23 @@ import * as React from "react";
|
||||
import { SVGProps } from "react";
|
||||
|
||||
const BackCaretIcon = (props: SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className={`min-icon`}
|
||||
fill={"currentcolor"}
|
||||
viewBox="0 0 256 256"
|
||||
{...props}
|
||||
>
|
||||
<g id="noun_chevron_2320228" transform="translate(5.595 10) rotate(180)">
|
||||
<path id="Path_6842" d="M-178.01,7.8c-3.9-0.03-7.62-1.63-10.34-4.43c-5.81-5.68-5.92-15-0.25-20.81
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className={`min-icon`}
|
||||
fill={"currentcolor"}
|
||||
viewBox="0 0 256 256"
|
||||
{...props}
|
||||
>
|
||||
<g id="noun_chevron_2320228" transform="translate(5.595 10) rotate(180)">
|
||||
<path
|
||||
id="Path_6842"
|
||||
d="M-178.01,7.8c-3.9-0.03-7.62-1.63-10.34-4.43c-5.81-5.68-5.92-15-0.25-20.81
|
||||
c0.08-0.08,0.16-0.16,0.25-0.25l100.13-100.13l-100.13-100.48c-5.81-5.68-5.92-15-0.25-20.81c0.08-0.08,0.16-0.16,0.25-0.25
|
||||
c5.68-5.81,15-5.92,20.81-0.25c0.08,0.08,0.16,0.16,0.25,0.25l110.82,110.82c2.8,2.72,4.39,6.44,4.43,10.34
|
||||
c0.11,3.93-1.51,7.71-4.43,10.34L-167.29,2.99C-170.07,5.97-173.93,7.71-178.01,7.8z"/>
|
||||
</g>
|
||||
</svg>
|
||||
c0.11,3.93-1.51,7.71-4.43,10.34L-167.29,2.99C-170.07,5.97-173.93,7.71-178.01,7.8z"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export default BackCaretIcon;
|
||||
|
||||
@@ -26,10 +26,12 @@ const FolderIcon = (props: SVGProps<SVGSVGElement>) => (
|
||||
{...props}
|
||||
>
|
||||
<g>
|
||||
<path d="M235.3,72.5c-0.2-15.5-12.8-27.9-28.3-27.9h-78l-1.1-1.5c-5.1-9.3-14.5-15.5-25.1-16.6h-50c-15.6,0-28.3,12.6-28.3,28.3
|
||||
<path
|
||||
d="M235.3,72.5c-0.2-15.5-12.8-27.9-28.3-27.9h-78l-1.1-1.5c-5.1-9.3-14.5-15.5-25.1-16.6h-50c-15.6,0-28.3,12.6-28.3,28.3
|
||||
c0,1,0.1,2,0.2,3v12.9c-11.6,3.9-19.4,14.8-19.4,27c0,0.6,0,1.2,0.1,1.7L14.8,202c0.6,15.4,13.2,27.5,28.6,27.5h168.9
|
||||
c15.4,0,28-12.1,28.6-27.5l9.5-102.5c0-0.6,0.1-1.2,0.1-1.8C250.6,87.1,244.7,77.4,235.3,72.5z M32.5,88.4c11.7-3.3,12-11,12-11
|
||||
h172c0.2,4.6,2.9,8.8,6.9,11H32.5z"/>
|
||||
h172c0.2,4.6,2.9,8.8,6.9,11H32.5z"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
|
||||
@@ -107,7 +107,7 @@ const CreateFolderModal = ({
|
||||
};
|
||||
|
||||
const keyPressed = (e: any) => {
|
||||
if(e.code === "Enter" && pathUrl !== "") {
|
||||
if (e.code === "Enter" && pathUrl !== "") {
|
||||
createProcess();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -178,7 +178,7 @@ const styles = (theme: Theme) =>
|
||||
"& .min-icon": {
|
||||
width: 20,
|
||||
height: 20,
|
||||
}
|
||||
},
|
||||
},
|
||||
...objectBrowserCommon,
|
||||
...containerForHeader(theme.spacing(4)),
|
||||
@@ -666,8 +666,6 @@ const ListObjects = ({
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
const handleUploadButton = (e: any) => {
|
||||
if (
|
||||
e === null ||
|
||||
@@ -1270,7 +1268,7 @@ const ListObjects = ({
|
||||
variant="dot"
|
||||
invisible={!rewindEnabled}
|
||||
className={classes.badgeOverlap}
|
||||
sx={{height: 12}}
|
||||
sx={{ height: 12 }}
|
||||
>
|
||||
<HistoryIcon />
|
||||
</Badge>
|
||||
@@ -1336,9 +1334,9 @@ const ListObjects = ({
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<BrowserBreadcrumbs
|
||||
bucketName={bucketName}
|
||||
internalPaths={pageTitle}
|
||||
existingFiles={records || []}
|
||||
bucketName={bucketName}
|
||||
internalPaths={pageTitle}
|
||||
existingFiles={records || []}
|
||||
/>
|
||||
</Grid>
|
||||
<div
|
||||
|
||||
@@ -381,7 +381,7 @@ export const objectBrowserCommon = {
|
||||
"& .min-icon": {
|
||||
width: 14,
|
||||
minWidth: 14,
|
||||
}
|
||||
},
|
||||
},
|
||||
smallLabel: {
|
||||
color: "#9C9C9C",
|
||||
@@ -414,7 +414,7 @@ export const selectorsCommon = {
|
||||
},
|
||||
};
|
||||
|
||||
export const settingsCommon:any = {
|
||||
export const settingsCommon: any = {
|
||||
customTitle: {
|
||||
fontSize: 18,
|
||||
color: "#000",
|
||||
@@ -1152,7 +1152,7 @@ export const spacingUtils: any = {
|
||||
},
|
||||
};
|
||||
|
||||
export const formFieldStyles:any = {
|
||||
export const formFieldStyles: any = {
|
||||
formFieldRow: {
|
||||
marginBottom: ".8rem",
|
||||
"& .MuiInputLabel-root": {
|
||||
|
||||
@@ -84,6 +84,7 @@ const ConsoleKBar = ({
|
||||
operatorMode: boolean;
|
||||
features: string[] | null;
|
||||
}) => {
|
||||
// if we are hiding the menu also disable the k-bar so just return console
|
||||
if (features?.includes("hide-menu")) {
|
||||
return <Console />;
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ import { AppState } from "../../../../store";
|
||||
import { setTenantDetailsLoad } from "../actions";
|
||||
import { ErrorResponseHandler } from "../../../../common/types";
|
||||
import DeletePod from "./DeletePod";
|
||||
import {Grid, InputAdornment, TextField} from "@mui/material";
|
||||
import { Grid, InputAdornment, TextField } from "@mui/material";
|
||||
import SearchIcon from "../../../../icons/SearchIcon";
|
||||
|
||||
interface IPodsSummary {
|
||||
@@ -137,22 +137,22 @@ const PodsSummary = ({
|
||||
<h1 className={classes.sectionTitle}>Pods</h1>
|
||||
<Grid item xs={12} className={classes.actionsTray}>
|
||||
<TextField
|
||||
placeholder="Search Pods"
|
||||
className={classes.searchField}
|
||||
id="search-resource"
|
||||
label=""
|
||||
InputProps={{
|
||||
disableUnderline: true,
|
||||
startAdornment: (
|
||||
<InputAdornment position="start">
|
||||
<SearchIcon />
|
||||
</InputAdornment>
|
||||
),
|
||||
}}
|
||||
onChange={(e) => {
|
||||
setFilter(e.target.value);
|
||||
}}
|
||||
variant="standard"
|
||||
placeholder="Search Pods"
|
||||
className={classes.searchField}
|
||||
id="search-resource"
|
||||
label=""
|
||||
InputProps={{
|
||||
disableUnderline: true,
|
||||
startAdornment: (
|
||||
<InputAdornment position="start">
|
||||
<SearchIcon />
|
||||
</InputAdornment>
|
||||
),
|
||||
}}
|
||||
onChange={(e) => {
|
||||
setFilter(e.target.value);
|
||||
}}
|
||||
variant="standard"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.tableBlock}>
|
||||
|
||||
@@ -23,7 +23,8 @@ import withStyles from "@mui/styles/withStyles";
|
||||
import { Grid, InputAdornment, TextField } from "@mui/material";
|
||||
import {
|
||||
containerForHeader,
|
||||
tableStyles, tenantDetailsStyles,
|
||||
tableStyles,
|
||||
tenantDetailsStyles,
|
||||
} from "../../Common/FormComponents/common/styleLibrary";
|
||||
import { IStoragePVCs } from "../../Storage/types";
|
||||
import { setErrorSnackMessage } from "../../../../actions";
|
||||
@@ -48,11 +49,11 @@ interface ITenantVolumesProps {
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
...tenantDetailsStyles,
|
||||
...tableStyles,
|
||||
...containerForHeader(theme.spacing(4)),
|
||||
});
|
||||
createStyles({
|
||||
...tenantDetailsStyles,
|
||||
...tableStyles,
|
||||
...containerForHeader(theme.spacing(4)),
|
||||
});
|
||||
|
||||
const TenantVolumes = ({
|
||||
classes,
|
||||
|
||||
@@ -151,7 +151,7 @@ const Hop = ({ classes, match }: IHopSimple) => {
|
||||
ref={consoleFrame}
|
||||
className={classes.iframeStyle}
|
||||
title={"metrics"}
|
||||
src={`/api/proxy/${tenantNamespace}/${tenantName}/?cp=y`}
|
||||
src={`/api/hop/${tenantNamespace}/${tenantName}/?cp=y`}
|
||||
onLoad={(val) => {
|
||||
setLoading(false);
|
||||
}}
|
||||
|
||||
@@ -15,25 +15,27 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { diagnosticsElement, supportElement } from "../utils/elements-menu";
|
||||
import { Selector } from 'testcafe';
|
||||
|
||||
import { Selector } from "testcafe";
|
||||
|
||||
fixture("For user with default permissions").page("http://localhost:9090");
|
||||
|
||||
test("Create Tenant and List Tenants", async (t) => {
|
||||
const osCount = Selector(
|
||||
`#root > div > main > div[class] > div > div > div > div:nth-child(1) > div > div > div`
|
||||
).count;
|
||||
|
||||
const osCount = Selector(`#root > div > main > div[class] > div > div > div > div:nth-child(1) > div > div > div`).count;
|
||||
|
||||
await t
|
||||
.navigateTo("http://localhost:9090/login")
|
||||
.typeText("#jwt","anyrandompasswordwillwork")
|
||||
.click("button.MuiButton-root")
|
||||
.click(Selector('button[tabindex="0"][type="button"]').withText('Create Tenant'))
|
||||
.typeText("#tenant-name","thufeb1754epm")
|
||||
.typeText("#namespace","default")
|
||||
.wait(2000)
|
||||
.click("button[tabindex=\"0\"]:nth-of-type(2)")
|
||||
.click(Selector('button[tabindex="0"][type="button"]').withText('Done'))
|
||||
.expect(osCount).eql(2);
|
||||
|
||||
await t
|
||||
.navigateTo("http://localhost:9090/login")
|
||||
.typeText("#jwt", "anyrandompasswordwillwork")
|
||||
.click("button.MuiButton-root")
|
||||
.click(
|
||||
Selector('button[tabindex="0"][type="button"]').withText("Create Tenant")
|
||||
)
|
||||
.typeText("#tenant-name", "thufeb1754epm")
|
||||
.typeText("#namespace", "default")
|
||||
.wait(2000)
|
||||
.click('button[tabindex="0"]:nth-of-type(2)')
|
||||
.click(Selector('button[tabindex="0"][type="button"]').withText("Done"))
|
||||
.expect(osCount)
|
||||
.eql(2);
|
||||
});
|
||||
|
||||
@@ -2,21 +2,15 @@
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Action": [
|
||||
"admin:*"
|
||||
],
|
||||
"Action": ["admin:*"],
|
||||
"Effect": "Allow",
|
||||
"Sid": "Allow_Admin_Actions"
|
||||
},
|
||||
{
|
||||
"Action": [
|
||||
"s3:*"
|
||||
],
|
||||
"Action": ["s3:*"],
|
||||
"Effect": "Allow",
|
||||
"Resource": [
|
||||
"arn:aws:s3:::*"
|
||||
],
|
||||
"Resource": ["arn:aws:s3:::*"],
|
||||
"Sid": "Allow_S3_Actions"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,21 +2,15 @@
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Action": [
|
||||
"admin:*"
|
||||
],
|
||||
"Action": ["admin:*"],
|
||||
"Effect": "Deny",
|
||||
"Sid": "Deny_Admin_Actions"
|
||||
},
|
||||
{
|
||||
"Action": [
|
||||
"s3:*"
|
||||
],
|
||||
"Action": ["s3:*"],
|
||||
"Effect": "Allow",
|
||||
"Resource": [
|
||||
"arn:aws:s3:::*"
|
||||
],
|
||||
"Resource": ["arn:aws:s3:::*"],
|
||||
"Sid": "Allow_S3_Actions"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user