Read subnet proxy configuration from minio or env var (#1511)
Signed-off-by: Lenin Alevski <alevsk.8772@gmail.com>
This commit is contained in:
@@ -44,9 +44,6 @@ type SubnetLoginMFARequest struct {
|
|||||||
// Required: true
|
// Required: true
|
||||||
Otp *string `json:"otp"`
|
Otp *string `json:"otp"`
|
||||||
|
|
||||||
// proxy
|
|
||||||
Proxy string `json:"proxy,omitempty"`
|
|
||||||
|
|
||||||
// username
|
// username
|
||||||
// Required: true
|
// Required: true
|
||||||
Username *string `json:"username"`
|
Username *string `json:"username"`
|
||||||
|
|||||||
@@ -40,9 +40,6 @@ type SubnetLoginRequest struct {
|
|||||||
// password
|
// password
|
||||||
Password string `json:"password,omitempty"`
|
Password string `json:"password,omitempty"`
|
||||||
|
|
||||||
// proxy
|
|
||||||
Proxy string `json:"proxy,omitempty"`
|
|
||||||
|
|
||||||
// username
|
// username
|
||||||
Username string `json:"username,omitempty"`
|
Username string `json:"username,omitempty"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,9 +40,6 @@ type SubnetRegisterRequest struct {
|
|||||||
// Required: true
|
// Required: true
|
||||||
AccountID *string `json:"account_id"`
|
AccountID *string `json:"account_id"`
|
||||||
|
|
||||||
// proxy
|
|
||||||
Proxy string `json:"proxy,omitempty"`
|
|
||||||
|
|
||||||
// token
|
// token
|
||||||
// Required: true
|
// Required: true
|
||||||
Token *string `json:"token"`
|
Token *string `json:"token"`
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ func GetOrganizations(client cluster.HTTPClientI, token string) ([]*models.Subne
|
|||||||
type LicenseTokenConfig struct {
|
type LicenseTokenConfig struct {
|
||||||
APIKey string
|
APIKey string
|
||||||
License string
|
License string
|
||||||
|
Proxy string
|
||||||
}
|
}
|
||||||
|
|
||||||
func Register(client cluster.HTTPClientI, admInfo madmin.InfoMessage, apiKey, token, accountID string) (*LicenseTokenConfig, error) {
|
func Register(client cluster.HTTPClientI, admInfo madmin.InfoMessage, apiKey, token, accountID string) (*LicenseTokenConfig, error) {
|
||||||
@@ -115,7 +116,7 @@ func Register(client cluster.HTTPClientI, admInfo madmin.InfoMessage, apiKey, to
|
|||||||
subnetAPIKey := respJSON.Get("api_key").String()
|
subnetAPIKey := respJSON.Get("api_key").String()
|
||||||
licenseJwt := respJSON.Get("license").String()
|
licenseJwt := respJSON.Get("license").String()
|
||||||
|
|
||||||
if subnetAPIKey != "" {
|
if subnetAPIKey != "" || licenseJwt != "" {
|
||||||
return &LicenseTokenConfig{
|
return &LicenseTokenConfig{
|
||||||
APIKey: subnetAPIKey,
|
APIKey: subnetAPIKey,
|
||||||
License: licenseJwt,
|
License: licenseJwt,
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ export interface SubnetLoginRequest {
|
|||||||
export interface SubnetRegisterRequest {
|
export interface SubnetRegisterRequest {
|
||||||
token: string;
|
token: string;
|
||||||
account_id: string;
|
account_id: string;
|
||||||
proxy?: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SubnetOrganization {
|
export interface SubnetOrganization {
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ import React, { Fragment, useCallback, useEffect, useState } from "react";
|
|||||||
import { CopyIcon, DiagnosticsFeatureIcon, UsersIcon } from "../../../icons";
|
import { CopyIcon, DiagnosticsFeatureIcon, UsersIcon } from "../../../icons";
|
||||||
import RemoveRedEyeIcon from "@mui/icons-material/RemoveRedEye";
|
import RemoveRedEyeIcon from "@mui/icons-material/RemoveRedEye";
|
||||||
import VisibilityOffIcon from "@mui/icons-material/VisibilityOff";
|
import VisibilityOffIcon from "@mui/icons-material/VisibilityOff";
|
||||||
import DnsIcon from "@mui/icons-material/Dns";
|
|
||||||
import OnlineRegistrationIcon from "../../../icons/OnlineRegistrationIcon";
|
import OnlineRegistrationIcon from "../../../icons/OnlineRegistrationIcon";
|
||||||
import OfflineRegistrationIcon from "../../../icons/OfflineRegistrationIcon";
|
import OfflineRegistrationIcon from "../../../icons/OfflineRegistrationIcon";
|
||||||
import InputBoxWrapper from "../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
|
import InputBoxWrapper from "../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
|
||||||
@@ -302,7 +301,6 @@ const Register = ({
|
|||||||
const [clusterRegistered, setClusterRegistered] = useState<boolean>(false);
|
const [clusterRegistered, setClusterRegistered] = useState<boolean>(false);
|
||||||
const [initialLicenseLoading, setInitialLicenseLoading] =
|
const [initialLicenseLoading, setInitialLicenseLoading] =
|
||||||
useState<boolean>(true);
|
useState<boolean>(true);
|
||||||
const [subnetProxy, setSubnetProxy] = useState<string>("");
|
|
||||||
const [displaySubnetProxy, setDisplaySubnetProxy] = useState<boolean>(false);
|
const [displaySubnetProxy, setDisplaySubnetProxy] = useState<boolean>(false);
|
||||||
|
|
||||||
const clearForm = () => {
|
const clearForm = () => {
|
||||||
@@ -374,9 +372,6 @@ const Register = ({
|
|||||||
token: token,
|
token: token,
|
||||||
account_id: account_id,
|
account_id: account_id,
|
||||||
};
|
};
|
||||||
if (displaySubnetProxy) {
|
|
||||||
request.proxy = subnetProxy;
|
|
||||||
}
|
|
||||||
api
|
api
|
||||||
.invoke("POST", "/api/v1/subnet/register", request)
|
.invoke("POST", "/api/v1/subnet/register", request)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@@ -409,9 +404,6 @@ const Register = ({
|
|||||||
otp: subnetOTP,
|
otp: subnetOTP,
|
||||||
mfa_token: subnetMFAToken,
|
mfa_token: subnetMFAToken,
|
||||||
};
|
};
|
||||||
if (displaySubnetProxy) {
|
|
||||||
request.proxy = subnetProxy;
|
|
||||||
}
|
|
||||||
api
|
api
|
||||||
.invoke("POST", "/api/v1/subnet/login/mfa", request)
|
.invoke("POST", "/api/v1/subnet/login/mfa", request)
|
||||||
.then((resp: SubnetLoginResponse) => {
|
.then((resp: SubnetLoginResponse) => {
|
||||||
@@ -448,9 +440,6 @@ const Register = ({
|
|||||||
password: subnetPassword,
|
password: subnetPassword,
|
||||||
apiKey: license,
|
apiKey: license,
|
||||||
};
|
};
|
||||||
if (displaySubnetProxy) {
|
|
||||||
request.proxy = subnetProxy;
|
|
||||||
}
|
|
||||||
api
|
api
|
||||||
.invoke("POST", "/api/v1/subnet/login", request)
|
.invoke("POST", "/api/v1/subnet/login", request)
|
||||||
.then((resp: SubnetLoginResponse) => {
|
.then((resp: SubnetLoginResponse) => {
|
||||||
@@ -917,6 +906,9 @@ const Register = ({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const proxyConfigurationCommand =
|
||||||
|
"mc admin config set {alias} subnet proxy={proxy}";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<PageHeader label="Register" />
|
<PageHeader label="Register" />
|
||||||
@@ -1001,21 +993,33 @@ const Register = ({
|
|||||||
fontSize: "14px",
|
fontSize: "14px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
For airgap/firewalled environments it is possible to configure
|
For airgap/firewalled environments it is possible to{" "}
|
||||||
a proxy to connect to SUBNET.
|
<Link
|
||||||
|
className={classes.link}
|
||||||
|
href="https://docs.min.io/docs/minio-server-configuration-guide.html?ref=con"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
configure a proxy
|
||||||
|
</Link>{" "}
|
||||||
|
to connect to SUBNET .
|
||||||
</Box>
|
</Box>
|
||||||
<Box>
|
<Box>
|
||||||
{displaySubnetProxy && (
|
{displaySubnetProxy && (
|
||||||
<InputBoxWrapper
|
<InputBoxWrapper
|
||||||
overlayIcon={<DnsIcon />}
|
disabled
|
||||||
id="subnetProxy"
|
id="subnetProxy"
|
||||||
name="subnetProxy"
|
name="subnetProxy"
|
||||||
onChange={(event: React.ChangeEvent<HTMLInputElement>) =>
|
placeholder=""
|
||||||
setSubnetProxy(event.target.value)
|
onChange={() => {}}
|
||||||
}
|
|
||||||
placeholder="https://192.168.1.3:3128"
|
|
||||||
label=""
|
label=""
|
||||||
value={subnetProxy}
|
value={proxyConfigurationCommand}
|
||||||
|
overlayIcon={<CopyIcon />}
|
||||||
|
extraInputProps={{
|
||||||
|
readOnly: true,
|
||||||
|
}}
|
||||||
|
overlayAction={() =>
|
||||||
|
navigator.clipboard.writeText(proxyConfigurationCommand)
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ func registerSubnetHandlers(api *operations.ConsoleAPI) {
|
|||||||
})
|
})
|
||||||
// Get subnet login with MFA handler
|
// Get subnet login with MFA handler
|
||||||
api.AdminAPISubnetLoginMFAHandler = admin_api.SubnetLoginMFAHandlerFunc(func(params admin_api.SubnetLoginMFAParams, session *models.Principal) middleware.Responder {
|
api.AdminAPISubnetLoginMFAHandler = admin_api.SubnetLoginMFAHandlerFunc(func(params admin_api.SubnetLoginMFAParams, session *models.Principal) middleware.Responder {
|
||||||
resp, err := GetSubnetLoginWithMFAResponse(params)
|
resp, err := GetSubnetLoginWithMFAResponse(session, params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return admin_api.NewSubnetLoginMFADefault(int(err.Code)).WithPayload(err)
|
return admin_api.NewSubnetLoginMFADefault(int(err.Code)).WithPayload(err)
|
||||||
}
|
}
|
||||||
@@ -85,7 +85,12 @@ func SubnetRegisterWithAPIKey(ctx context.Context, minioClient MinioAdmin, apiKe
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
configStr := fmt.Sprintf("subnet license=%s api_key=%s", registerResult.License, registerResult.APIKey)
|
// Keep existing subnet proxy if exists
|
||||||
|
subnetKey, err := GetSubnetKeyFromMinIOConfig(ctx, minioClient)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
configStr := fmt.Sprintf("subnet license=%s api_key=%s proxy=%s", registerResult.License, registerResult.APIKey, subnetKey.Proxy)
|
||||||
_, err = minioClient.setConfigKV(ctx, configStr)
|
_, err = minioClient.setConfigKV(ctx, configStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
@@ -112,15 +117,15 @@ func SubnetLogin(client cluster.HTTPClientI, username, password string) (string,
|
|||||||
|
|
||||||
func GetSubnetLoginResponse(session *models.Principal, params admin_api.SubnetLoginParams) (*models.SubnetLoginResponse, *models.Error) {
|
func GetSubnetLoginResponse(session *models.Principal, params admin_api.SubnetLoginParams) (*models.SubnetLoginResponse, *models.Error) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
subnetHTTPClient, err := GetSubnetHTTPClient(params.Body.Proxy)
|
|
||||||
if err != nil {
|
|
||||||
return nil, prepareError(err)
|
|
||||||
}
|
|
||||||
mAdmin, err := NewMinioAdminClient(session)
|
mAdmin, err := NewMinioAdminClient(session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, prepareError(err)
|
return nil, prepareError(err)
|
||||||
}
|
}
|
||||||
minioClient := AdminClient{Client: mAdmin}
|
minioClient := AdminClient{Client: mAdmin}
|
||||||
|
subnetHTTPClient, err := GetSubnetHTTPClient(ctx, minioClient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, prepareError(err)
|
||||||
|
}
|
||||||
apiKey := params.Body.APIKey
|
apiKey := params.Body.APIKey
|
||||||
if apiKey != "" {
|
if apiKey != "" {
|
||||||
registered, err := SubnetRegisterWithAPIKey(ctx, minioClient, apiKey)
|
registered, err := SubnetRegisterWithAPIKey(ctx, minioClient, apiKey)
|
||||||
@@ -173,8 +178,19 @@ func SubnetLoginWithMFA(client cluster.HTTPClientI, username, mfaToken, otp stri
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetSubnetHTTPClient will return a client with proxy if configured, otherwise will return the default console http client
|
// GetSubnetHTTPClient will return a client with proxy if configured, otherwise will return the default console http client
|
||||||
func GetSubnetHTTPClient(proxy string) (*cluster.HTTPClient, error) {
|
func GetSubnetHTTPClient(ctx context.Context, minioClient MinioAdmin) (*cluster.HTTPClient, error) {
|
||||||
var subnetHTTPClient *http.Client
|
var subnetHTTPClient *http.Client
|
||||||
|
var proxy string
|
||||||
|
envProxy := getSubnetProxy()
|
||||||
|
subnetKey, err := GetSubnetKeyFromMinIOConfig(ctx, minioClient)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if subnetKey.Proxy != "" {
|
||||||
|
proxy = subnetKey.Proxy
|
||||||
|
} else if envProxy != "" {
|
||||||
|
proxy = envProxy
|
||||||
|
}
|
||||||
if proxy != "" {
|
if proxy != "" {
|
||||||
transport := prepareSTSClientTransport(false)
|
transport := prepareSTSClientTransport(false)
|
||||||
subnetHTTPClient = &http.Client{
|
subnetHTTPClient = &http.Client{
|
||||||
@@ -194,8 +210,14 @@ func GetSubnetHTTPClient(proxy string) (*cluster.HTTPClient, error) {
|
|||||||
return clientI, nil
|
return clientI, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetSubnetLoginWithMFAResponse(params admin_api.SubnetLoginMFAParams) (*models.SubnetLoginResponse, *models.Error) {
|
func GetSubnetLoginWithMFAResponse(session *models.Principal, params admin_api.SubnetLoginMFAParams) (*models.SubnetLoginResponse, *models.Error) {
|
||||||
subnetHTTPClient, err := GetSubnetHTTPClient(params.Body.Proxy)
|
ctx := context.Background()
|
||||||
|
mAdmin, err := NewMinioAdminClient(session)
|
||||||
|
if err != nil {
|
||||||
|
return nil, prepareError(err)
|
||||||
|
}
|
||||||
|
minioClient := AdminClient{Client: mAdmin}
|
||||||
|
subnetHTTPClient, err := GetSubnetHTTPClient(ctx, minioClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, prepareError(err)
|
return nil, prepareError(err)
|
||||||
}
|
}
|
||||||
@@ -225,6 +247,8 @@ func GetSubnetKeyFromMinIOConfig(ctx context.Context, minioClient MinioAdmin) (*
|
|||||||
res.APIKey = kv.Value
|
res.APIKey = kv.Value
|
||||||
} else if kv.Key == "license" {
|
} else if kv.Key == "license" {
|
||||||
res.License = kv.Value
|
res.License = kv.Value
|
||||||
|
} else if kv.Key == "proxy" {
|
||||||
|
res.Proxy = kv.Value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return &res, nil
|
return &res, nil
|
||||||
@@ -239,7 +263,12 @@ func GetSubnetRegister(ctx context.Context, minioClient MinioAdmin, httpClient c
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
configStr := fmt.Sprintf("subnet license=%s api_key=%s", registerResult.License, registerResult.APIKey)
|
// Keep existing subnet proxy if exists
|
||||||
|
subnetKey, err := GetSubnetKeyFromMinIOConfig(ctx, minioClient)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
configStr := fmt.Sprintf("subnet license=%s api_key=%s proxy=%s", registerResult.License, registerResult.APIKey, subnetKey.Proxy)
|
||||||
_, err = minioClient.setConfigKV(ctx, configStr)
|
_, err = minioClient.setConfigKV(ctx, configStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -254,7 +283,7 @@ func GetSubnetRegisterResponse(session *models.Principal, params admin_api.Subne
|
|||||||
return prepareError(err)
|
return prepareError(err)
|
||||||
}
|
}
|
||||||
adminClient := AdminClient{Client: mAdmin}
|
adminClient := AdminClient{Client: mAdmin}
|
||||||
subnetHTTPClient, err := GetSubnetHTTPClient(params.Body.Proxy)
|
subnetHTTPClient, err := GetSubnetHTTPClient(ctx, adminClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return prepareError(err)
|
return prepareError(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,6 +50,10 @@ func getMinIOServer() string {
|
|||||||
return strings.TrimSpace(env.Get(ConsoleMinIOServer, "http://localhost:9000"))
|
return strings.TrimSpace(env.Get(ConsoleMinIOServer, "http://localhost:9000"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getSubnetProxy() string {
|
||||||
|
return strings.TrimSpace(env.Get(ConsoleSubnetProxy, ""))
|
||||||
|
}
|
||||||
|
|
||||||
func GetMinIORegion() string {
|
func GetMinIORegion() string {
|
||||||
return strings.TrimSpace(env.Get(ConsoleMinIORegion, ""))
|
return strings.TrimSpace(env.Get(ConsoleMinIORegion, ""))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ package restapi
|
|||||||
const (
|
const (
|
||||||
// Constants for common configuration
|
// Constants for common configuration
|
||||||
ConsoleMinIOServer = "CONSOLE_MINIO_SERVER"
|
ConsoleMinIOServer = "CONSOLE_MINIO_SERVER"
|
||||||
|
ConsoleSubnetProxy = "CONSOLE_SUBNET_PROXY"
|
||||||
ConsoleMinIORegion = "CONSOLE_MINIO_REGION"
|
ConsoleMinIORegion = "CONSOLE_MINIO_REGION"
|
||||||
ConsoleHostname = "CONSOLE_HOSTNAME"
|
ConsoleHostname = "CONSOLE_HOSTNAME"
|
||||||
ConsolePort = "CONSOLE_PORT"
|
ConsolePort = "CONSOLE_PORT"
|
||||||
|
|||||||
@@ -5730,9 +5730,6 @@ func init() {
|
|||||||
"otp": {
|
"otp": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"proxy": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"username": {
|
"username": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
@@ -5747,9 +5744,6 @@ func init() {
|
|||||||
"password": {
|
"password": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"proxy": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"username": {
|
"username": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
@@ -5808,9 +5802,6 @@ func init() {
|
|||||||
"account_id": {
|
"account_id": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"proxy": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"token": {
|
"token": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
@@ -11966,9 +11957,6 @@ func init() {
|
|||||||
"otp": {
|
"otp": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"proxy": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"username": {
|
"username": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
@@ -11983,9 +11971,6 @@ func init() {
|
|||||||
"password": {
|
"password": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"proxy": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"username": {
|
"username": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
@@ -12044,9 +12029,6 @@ func init() {
|
|||||||
"account_id": {
|
"account_id": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"proxy": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"token": {
|
"token": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4138,8 +4138,6 @@ definitions:
|
|||||||
subnetLoginRequest:
|
subnetLoginRequest:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
proxy:
|
|
||||||
type: string
|
|
||||||
username:
|
username:
|
||||||
type: string
|
type: string
|
||||||
password:
|
password:
|
||||||
@@ -4154,8 +4152,6 @@ definitions:
|
|||||||
- otp
|
- otp
|
||||||
- mfa_token
|
- mfa_token
|
||||||
properties:
|
properties:
|
||||||
proxy:
|
|
||||||
type: string
|
|
||||||
username:
|
username:
|
||||||
type: string
|
type: string
|
||||||
otp:
|
otp:
|
||||||
@@ -4169,8 +4165,6 @@ definitions:
|
|||||||
- token
|
- token
|
||||||
- account_id
|
- account_id
|
||||||
properties:
|
properties:
|
||||||
proxy:
|
|
||||||
type: string
|
|
||||||
token:
|
token:
|
||||||
type: string
|
type: string
|
||||||
account_id:
|
account_id:
|
||||||
|
|||||||
Reference in New Issue
Block a user