Move Create Tenant to Thunk (#2043)
Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
This commit is contained in:
@@ -103,6 +103,9 @@ const WizardPage = ({
|
||||
>
|
||||
<div className={classes.buttonInnerContainer}>
|
||||
{page.buttons.map((btn) => {
|
||||
if (btn.componentRender) {
|
||||
return btn.componentRender;
|
||||
}
|
||||
return (
|
||||
<Button
|
||||
id={"wizard-button-" + btn.label}
|
||||
|
||||
@@ -15,11 +15,12 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export interface IWizardButton {
|
||||
label: string;
|
||||
type: string;
|
||||
label?: string;
|
||||
type?: string;
|
||||
action?: (nextFunction: (to: string | number) => void) => void;
|
||||
enabled?: boolean;
|
||||
toPage?: number;
|
||||
componentRender?: React.ReactNode;
|
||||
}
|
||||
|
||||
export interface IWizardElement {
|
||||
|
||||
@@ -27,15 +27,11 @@ import {
|
||||
settingsCommon,
|
||||
wizardCommon,
|
||||
} from "../../Common/FormComponents/common/styleLibrary";
|
||||
import api from "../../../../common/api";
|
||||
import { generatePoolName, getBytes } from "../../../../common/utils";
|
||||
import GenericWizard from "../../Common/GenericWizard/GenericWizard";
|
||||
import { IWizardElement } from "../../Common/GenericWizard/types";
|
||||
import { NewServiceAccount } from "../../Common/CredentialsPrompt/types";
|
||||
import { ErrorResponseHandler, ITenantCreator } from "../../../../common/types";
|
||||
import { KeyPair } from "../ListTenants/utils";
|
||||
|
||||
import { getDefaultAffinity, getNodeSelector } from "../TenantDetails/utils";
|
||||
import {
|
||||
IWizardButton,
|
||||
IWizardElement,
|
||||
} from "../../Common/GenericWizard/types";
|
||||
import CredentialsPrompt from "../../Common/CredentialsPrompt/CredentialsPrompt";
|
||||
import { AppState } from "../../../../store";
|
||||
import Configure from "./Steps/Configure";
|
||||
@@ -57,10 +53,10 @@ import {
|
||||
} from "./Steps/TenantResources/utils";
|
||||
import HelpBox from "../../../../common/HelpBox";
|
||||
import { StorageIcon } from "../../../../icons";
|
||||
import { setErrorSnackMessage } from "../../../../systemSlice";
|
||||
import { selFeatures } from "../../consoleSlice";
|
||||
import makeStyles from "@mui/styles/makeStyles";
|
||||
import { resetAddTenantForm } from "./createTenantSlice";
|
||||
import CreateTenantButton from "./CreateTenantButton";
|
||||
|
||||
const useStyles = makeStyles((theme: Theme) =>
|
||||
createStyles({
|
||||
@@ -77,32 +73,20 @@ const AddTenant = () => {
|
||||
const dispatch = useDispatch();
|
||||
const classes = useStyles();
|
||||
|
||||
const namespace = useSelector(
|
||||
(state: AppState) => state.createTenant.fields.nameTenant.namespace
|
||||
);
|
||||
const validPages = useSelector(
|
||||
(state: AppState) => state.createTenant.validPages
|
||||
);
|
||||
const fields = useSelector((state: AppState) => state.createTenant.fields);
|
||||
const certificates = useSelector(
|
||||
(state: AppState) => state.createTenant.certificates
|
||||
);
|
||||
const selectedStorageClass = useSelector(
|
||||
(state: AppState) =>
|
||||
state.createTenant.fields.nameTenant.selectedStorageClass
|
||||
);
|
||||
const features = useSelector(selFeatures);
|
||||
const tolerations = useSelector(
|
||||
(state: AppState) => state.createTenant.tolerations
|
||||
);
|
||||
|
||||
// Modals
|
||||
const [showNewCredentials, setShowNewCredentials] = useState<boolean>(false);
|
||||
const [createdAccount, setCreatedAccount] =
|
||||
useState<NewServiceAccount | null>(null);
|
||||
const showNewCredentials = useSelector(
|
||||
(state: AppState) => state.createTenant.showNewCredentials
|
||||
);
|
||||
const createdAccount = useSelector(
|
||||
(state: AppState) => state.createTenant.createdAccount
|
||||
);
|
||||
|
||||
// Fields
|
||||
const [addSending, setAddSending] = useState<boolean>(false);
|
||||
const addSending = useSelector(
|
||||
(state: AppState) => state.createTenant.addingTenant
|
||||
);
|
||||
const [formRender, setFormRender] = useState<IMkEnvs | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -125,596 +109,6 @@ const AddTenant = () => {
|
||||
setFormRender(setConfiguration);
|
||||
}, [features]);
|
||||
|
||||
/* Send Information to backend */
|
||||
useEffect(() => {
|
||||
const tenantName = fields.nameTenant.tenantName;
|
||||
const selectedStorageClass = fields.nameTenant.selectedStorageClass;
|
||||
const imageName = fields.configure.imageName;
|
||||
const customDockerhub = fields.configure.customDockerhub;
|
||||
const imageRegistry = fields.configure.imageRegistry;
|
||||
const imageRegistryUsername = fields.configure.imageRegistryUsername;
|
||||
const imageRegistryPassword = fields.configure.imageRegistryPassword;
|
||||
const exposeMinIO = fields.configure.exposeMinIO;
|
||||
const exposeConsole = fields.configure.exposeConsole;
|
||||
const idpSelection = fields.identityProvider.idpSelection;
|
||||
const openIDConfigurationURL =
|
||||
fields.identityProvider.openIDConfigurationURL;
|
||||
const openIDClientID = fields.identityProvider.openIDClientID;
|
||||
const openIDClaimName = fields.identityProvider.openIDClaimName;
|
||||
const openIDCallbackURL = fields.identityProvider.openIDCallbackURL;
|
||||
const openIDScopes = fields.identityProvider.openIDScopes;
|
||||
const openIDSecretID = fields.identityProvider.openIDSecretID;
|
||||
const ADURL = fields.identityProvider.ADURL;
|
||||
const ADSkipTLS = fields.identityProvider.ADSkipTLS;
|
||||
const ADServerInsecure = fields.identityProvider.ADServerInsecure;
|
||||
const ADGroupSearchBaseDN = fields.identityProvider.ADGroupSearchBaseDN;
|
||||
const ADGroupSearchFilter = fields.identityProvider.ADGroupSearchFilter;
|
||||
const ADUserDNs = fields.identityProvider.ADUserDNs;
|
||||
const ADLookupBindDN = fields.identityProvider.ADLookupBindDN;
|
||||
const ADLookupBindPassword = fields.identityProvider.ADLookupBindPassword;
|
||||
const ADUserDNSearchBaseDN = fields.identityProvider.ADUserDNSearchBaseDN;
|
||||
const ADUserDNSearchFilter = fields.identityProvider.ADUserDNSearchFilter;
|
||||
const ADServerStartTLS = fields.identityProvider.ADServerStartTLS;
|
||||
const accessKeys = fields.identityProvider.accessKeys;
|
||||
const secretKeys = fields.identityProvider.secretKeys;
|
||||
const minioCertificates = certificates.minioCertificates;
|
||||
const caCertificates = certificates.caCertificates;
|
||||
const consoleCaCertificates = certificates.consoleCaCertificates;
|
||||
const consoleCertificate = certificates.consoleCertificate;
|
||||
const serverCertificate = certificates.serverCertificate;
|
||||
const clientCertificate = certificates.clientCertificate;
|
||||
const vaultCertificate = certificates.vaultCertificate;
|
||||
const vaultCA = certificates.vaultCA;
|
||||
const gemaltoCA = certificates.gemaltoCA;
|
||||
const enableEncryption = fields.encryption.enableEncryption;
|
||||
const encryptionType = fields.encryption.encryptionType;
|
||||
const gemaltoEndpoint = fields.encryption.gemaltoEndpoint;
|
||||
const gemaltoToken = fields.encryption.gemaltoToken;
|
||||
const gemaltoDomain = fields.encryption.gemaltoDomain;
|
||||
const gemaltoRetry = fields.encryption.gemaltoRetry;
|
||||
const awsEndpoint = fields.encryption.awsEndpoint;
|
||||
const awsRegion = fields.encryption.awsRegion;
|
||||
const awsKMSKey = fields.encryption.awsKMSKey;
|
||||
const awsAccessKey = fields.encryption.awsAccessKey;
|
||||
const awsSecretKey = fields.encryption.awsSecretKey;
|
||||
const awsToken = fields.encryption.awsToken;
|
||||
const vaultEndpoint = fields.encryption.vaultEndpoint;
|
||||
const vaultEngine = fields.encryption.vaultEngine;
|
||||
const vaultNamespace = fields.encryption.vaultNamespace;
|
||||
const vaultPrefix = fields.encryption.vaultPrefix;
|
||||
const vaultAppRoleEngine = fields.encryption.vaultAppRoleEngine;
|
||||
const vaultId = fields.encryption.vaultId;
|
||||
const vaultSecret = fields.encryption.vaultSecret;
|
||||
const vaultRetry = fields.encryption.vaultRetry;
|
||||
const vaultPing = fields.encryption.vaultPing;
|
||||
const azureEndpoint = fields.encryption.azureEndpoint;
|
||||
const azureTenantID = fields.encryption.azureTenantID;
|
||||
const azureClientID = fields.encryption.azureClientID;
|
||||
const azureClientSecret = fields.encryption.azureClientSecret;
|
||||
const gcpProjectID = fields.encryption.gcpProjectID;
|
||||
const gcpEndpoint = fields.encryption.gcpEndpoint;
|
||||
const gcpClientEmail = fields.encryption.gcpClientEmail;
|
||||
const gcpClientID = fields.encryption.gcpClientID;
|
||||
const gcpPrivateKeyID = fields.encryption.gcpPrivateKeyID;
|
||||
const gcpPrivateKey = fields.encryption.gcpPrivateKey;
|
||||
const enableAutoCert = fields.security.enableAutoCert;
|
||||
const enableTLS = fields.security.enableTLS;
|
||||
const ecParity = fields.tenantSize.ecParity;
|
||||
const distribution = fields.tenantSize.distribution;
|
||||
const tenantCustom = fields.configure.tenantCustom;
|
||||
const logSearchEnabled = fields.configure.logSearchEnabled;
|
||||
const prometheusEnabled = fields.configure.prometheusEnabled;
|
||||
const logSearchVolumeSize = fields.configure.logSearchVolumeSize;
|
||||
const logSearchSelectedStorageClass =
|
||||
fields.configure.logSearchSelectedStorageClass;
|
||||
const logSearchImage = fields.configure.logSearchImage;
|
||||
const kesImage = fields.configure.kesImage;
|
||||
const logSearchPostgresImage = fields.configure.logSearchPostgresImage;
|
||||
const logSearchPostgresInitImage =
|
||||
fields.configure.logSearchPostgresInitImage;
|
||||
const prometheusImage = fields.configure.prometheusImage;
|
||||
const prometheusSidecarImage = fields.configure.prometheusSidecarImage;
|
||||
const prometheusInitImage = fields.configure.prometheusInitImage;
|
||||
const prometheusSelectedStorageClass =
|
||||
fields.configure.prometheusSelectedStorageClass;
|
||||
const prometheusVolumeSize = fields.configure.prometheusVolumeSize;
|
||||
const affinityType = fields.affinity.podAffinity;
|
||||
const nodeSelectorLabels = fields.affinity.nodeSelectorLabels;
|
||||
const withPodAntiAffinity = fields.affinity.withPodAntiAffinity;
|
||||
|
||||
const tenantSecurityContext = fields.configure.tenantSecurityContext;
|
||||
const logSearchSecurityContext = fields.configure.logSearchSecurityContext;
|
||||
const logSearchPostgresSecurityContext =
|
||||
fields.configure.logSearchPostgresSecurityContext;
|
||||
const prometheusSecurityContext =
|
||||
fields.configure.prometheusSecurityContext;
|
||||
const kesSecurityContext = fields.encryption.kesSecurityContext;
|
||||
const kesReplicas = fields.encryption.replicas;
|
||||
const setDomains = fields.configure.setDomains;
|
||||
const minioDomains = fields.configure.minioDomains;
|
||||
const consoleDomain = fields.configure.consoleDomain;
|
||||
|
||||
if (addSending) {
|
||||
const tolerationValues = tolerations.filter(
|
||||
(toleration) => toleration.key.trim() !== ""
|
||||
);
|
||||
|
||||
const poolName = generatePoolName([]);
|
||||
|
||||
let affinityObject = {};
|
||||
|
||||
switch (affinityType) {
|
||||
case "default":
|
||||
affinityObject = {
|
||||
affinity: getDefaultAffinity(tenantName, poolName),
|
||||
};
|
||||
break;
|
||||
case "nodeSelector":
|
||||
affinityObject = {
|
||||
affinity: getNodeSelector(
|
||||
nodeSelectorLabels,
|
||||
withPodAntiAffinity,
|
||||
tenantName,
|
||||
poolName
|
||||
),
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
const erasureCode = ecParity.split(":")[1];
|
||||
|
||||
let dataSend: ITenantCreator = {
|
||||
name: tenantName,
|
||||
namespace: namespace,
|
||||
access_key: "",
|
||||
secret_key: "",
|
||||
access_keys: [],
|
||||
secret_keys: [],
|
||||
enable_tls: enableTLS && enableAutoCert,
|
||||
enable_console: true,
|
||||
enable_prometheus: true,
|
||||
service_name: "",
|
||||
image: imageName,
|
||||
expose_minio: exposeMinIO,
|
||||
expose_console: exposeConsole,
|
||||
pools: [
|
||||
{
|
||||
name: poolName,
|
||||
servers: distribution.nodes,
|
||||
volumes_per_server: distribution.disks,
|
||||
volume_configuration: {
|
||||
size: distribution.pvSize,
|
||||
storage_class_name: selectedStorageClass,
|
||||
},
|
||||
securityContext: tenantCustom ? tenantSecurityContext : null,
|
||||
...affinityObject,
|
||||
tolerations: tolerationValues,
|
||||
},
|
||||
],
|
||||
erasureCodingParity: parseInt(erasureCode, 10),
|
||||
};
|
||||
|
||||
// Set Resources
|
||||
if (
|
||||
fields.tenantSize.resourcesCPURequest !== "" ||
|
||||
fields.tenantSize.resourcesCPULimit !== "" ||
|
||||
fields.tenantSize.resourcesMemoryRequest !== "" ||
|
||||
fields.tenantSize.resourcesMemoryLimit !== ""
|
||||
) {
|
||||
dataSend.pools[0].resources = {};
|
||||
// requests
|
||||
if (
|
||||
fields.tenantSize.resourcesCPURequest !== "" ||
|
||||
fields.tenantSize.resourcesMemoryRequest !== ""
|
||||
) {
|
||||
dataSend.pools[0].resources.requests = {};
|
||||
if (fields.tenantSize.resourcesCPURequest !== "") {
|
||||
dataSend.pools[0].resources.requests.cpu = parseInt(
|
||||
fields.tenantSize.resourcesCPURequest
|
||||
);
|
||||
}
|
||||
if (fields.tenantSize.resourcesMemoryRequest !== "") {
|
||||
dataSend.pools[0].resources.requests.memory = parseInt(
|
||||
getBytes(fields.tenantSize.resourcesMemoryRequest, "Gi", true)
|
||||
);
|
||||
}
|
||||
}
|
||||
// limits
|
||||
if (
|
||||
fields.tenantSize.resourcesCPULimit !== "" ||
|
||||
fields.tenantSize.resourcesMemoryLimit !== ""
|
||||
) {
|
||||
dataSend.pools[0].resources.limits = {};
|
||||
if (fields.tenantSize.resourcesCPULimit !== "") {
|
||||
dataSend.pools[0].resources.limits.cpu = parseInt(
|
||||
fields.tenantSize.resourcesCPULimit
|
||||
);
|
||||
}
|
||||
if (fields.tenantSize.resourcesMemoryLimit !== "") {
|
||||
dataSend.pools[0].resources.limits.memory = parseInt(
|
||||
getBytes(fields.tenantSize.resourcesMemoryLimit, "Gi", true)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (customDockerhub) {
|
||||
dataSend = {
|
||||
...dataSend,
|
||||
image_registry: {
|
||||
registry: imageRegistry,
|
||||
username: imageRegistryUsername,
|
||||
password: imageRegistryPassword,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
if (logSearchEnabled) {
|
||||
dataSend = {
|
||||
...dataSend,
|
||||
logSearchConfiguration: {
|
||||
storageClass:
|
||||
logSearchSelectedStorageClass === "default"
|
||||
? ""
|
||||
: logSearchSelectedStorageClass,
|
||||
storageSize: parseInt(logSearchVolumeSize),
|
||||
image: logSearchImage,
|
||||
postgres_image: logSearchPostgresImage,
|
||||
postgres_init_image: logSearchPostgresInitImage,
|
||||
securityContext: logSearchSecurityContext,
|
||||
postgres_securityContext: logSearchPostgresSecurityContext,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
if (prometheusEnabled) {
|
||||
dataSend = {
|
||||
...dataSend,
|
||||
prometheusConfiguration: {
|
||||
storageClass:
|
||||
prometheusSelectedStorageClass === "default"
|
||||
? ""
|
||||
: prometheusSelectedStorageClass,
|
||||
storageSize: parseInt(prometheusVolumeSize),
|
||||
image: prometheusImage,
|
||||
sidecar_image: prometheusSidecarImage,
|
||||
init_image: prometheusInitImage,
|
||||
securityContext: prometheusSecurityContext,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
let tenantCerts: any = null;
|
||||
let consoleCerts: any = null;
|
||||
let caCerts: any = null;
|
||||
let consoleCaCerts: any = null;
|
||||
|
||||
if (caCertificates.length > 0) {
|
||||
caCerts = {
|
||||
ca_certificates: caCertificates
|
||||
.map((keyPair: KeyPair) => keyPair.encoded_cert)
|
||||
.filter((keyPair) => keyPair),
|
||||
};
|
||||
}
|
||||
|
||||
if (consoleCaCertificates.length > 0) {
|
||||
consoleCaCerts = {
|
||||
console_ca_certificates: consoleCaCertificates
|
||||
.map((keyPair: KeyPair) => keyPair.encoded_cert)
|
||||
.filter((keyPair) => keyPair),
|
||||
};
|
||||
}
|
||||
|
||||
if (enableTLS && minioCertificates.length > 0) {
|
||||
tenantCerts = {
|
||||
minio: minioCertificates
|
||||
.map((keyPair: KeyPair) => ({
|
||||
crt: keyPair.encoded_cert,
|
||||
key: keyPair.encoded_key,
|
||||
}))
|
||||
.filter((keyPair) => keyPair.crt && keyPair.key),
|
||||
};
|
||||
}
|
||||
|
||||
if (
|
||||
enableTLS &&
|
||||
consoleCertificate.encoded_cert !== "" &&
|
||||
consoleCertificate.encoded_key !== ""
|
||||
) {
|
||||
consoleCerts = {
|
||||
console: {
|
||||
crt: consoleCertificate.encoded_cert,
|
||||
key: consoleCertificate.encoded_key,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
if (tenantCerts || consoleCerts || caCerts || consoleCaCerts) {
|
||||
dataSend = {
|
||||
...dataSend,
|
||||
tls: {
|
||||
...tenantCerts,
|
||||
...consoleCerts,
|
||||
...caCerts,
|
||||
...consoleCaCerts,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
if (enableEncryption) {
|
||||
let insertEncrypt = {};
|
||||
|
||||
switch (encryptionType) {
|
||||
case "gemalto":
|
||||
let gemaltoCAIntroduce = {};
|
||||
|
||||
if (gemaltoCA.encoded_cert !== "") {
|
||||
gemaltoCAIntroduce = {
|
||||
ca: gemaltoCA.encoded_cert,
|
||||
};
|
||||
}
|
||||
insertEncrypt = {
|
||||
gemalto: {
|
||||
keysecure: {
|
||||
endpoint: gemaltoEndpoint,
|
||||
credentials: {
|
||||
token: gemaltoToken,
|
||||
domain: gemaltoDomain,
|
||||
retry: parseInt(gemaltoRetry),
|
||||
},
|
||||
tls: {
|
||||
...gemaltoCAIntroduce,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
break;
|
||||
case "aws":
|
||||
insertEncrypt = {
|
||||
aws: {
|
||||
secretsmanager: {
|
||||
endpoint: awsEndpoint,
|
||||
region: awsRegion,
|
||||
kmskey: awsKMSKey,
|
||||
credentials: {
|
||||
accesskey: awsAccessKey,
|
||||
secretkey: awsSecretKey,
|
||||
token: awsToken,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
break;
|
||||
case "azure":
|
||||
insertEncrypt = {
|
||||
azure: {
|
||||
keyvault: {
|
||||
endpoint: azureEndpoint,
|
||||
credentials: {
|
||||
tenant_id: azureTenantID,
|
||||
client_id: azureClientID,
|
||||
client_secret: azureClientSecret,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
break;
|
||||
case "gcp":
|
||||
insertEncrypt = {
|
||||
gcp: {
|
||||
secretmanager: {
|
||||
project_id: gcpProjectID,
|
||||
endpoint: gcpEndpoint,
|
||||
credentials: {
|
||||
client_email: gcpClientEmail,
|
||||
client_id: gcpClientID,
|
||||
private_key_id: gcpPrivateKeyID,
|
||||
private_key: gcpPrivateKey,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
break;
|
||||
case "vault":
|
||||
let vaultKeyPair = null;
|
||||
let vaultCAInsert = null;
|
||||
if (
|
||||
vaultCertificate.encoded_key !== "" &&
|
||||
vaultCertificate.encoded_cert !== ""
|
||||
) {
|
||||
vaultKeyPair = {
|
||||
key: vaultCertificate.encoded_key,
|
||||
crt: vaultCertificate.encoded_cert,
|
||||
};
|
||||
}
|
||||
if (vaultCA.encoded_cert !== "") {
|
||||
vaultCAInsert = {
|
||||
ca: vaultCA.encoded_cert,
|
||||
};
|
||||
}
|
||||
let vaultTLS = null;
|
||||
if (vaultKeyPair || vaultCAInsert) {
|
||||
vaultTLS = {
|
||||
tls: {
|
||||
...vaultKeyPair,
|
||||
...vaultCAInsert,
|
||||
},
|
||||
};
|
||||
}
|
||||
insertEncrypt = {
|
||||
vault: {
|
||||
endpoint: vaultEndpoint,
|
||||
engine: vaultEngine,
|
||||
namespace: vaultNamespace,
|
||||
prefix: vaultPrefix,
|
||||
approle: {
|
||||
engine: vaultAppRoleEngine,
|
||||
id: vaultId,
|
||||
secret: vaultSecret,
|
||||
retry: parseInt(vaultRetry),
|
||||
},
|
||||
...vaultTLS,
|
||||
status: {
|
||||
ping: parseInt(vaultPing),
|
||||
},
|
||||
},
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
let encryptionServerKeyPair: any = {};
|
||||
let encryptionClientKeyPair: any = {};
|
||||
|
||||
if (
|
||||
clientCertificate.encoded_key !== "" &&
|
||||
clientCertificate.encoded_cert !== ""
|
||||
) {
|
||||
encryptionClientKeyPair = {
|
||||
client: {
|
||||
key: clientCertificate.encoded_key,
|
||||
crt: clientCertificate.encoded_cert,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
if (
|
||||
serverCertificate.encoded_key !== "" &&
|
||||
serverCertificate.encoded_cert !== ""
|
||||
) {
|
||||
encryptionServerKeyPair = {
|
||||
server: {
|
||||
key: serverCertificate.encoded_key,
|
||||
crt: serverCertificate.encoded_cert,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
dataSend = {
|
||||
...dataSend,
|
||||
encryption: {
|
||||
replicas: kesReplicas,
|
||||
securityContext: kesSecurityContext,
|
||||
image: kesImage,
|
||||
...encryptionClientKeyPair,
|
||||
...encryptionServerKeyPair,
|
||||
...insertEncrypt,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
let dataIDP: any = {};
|
||||
switch (idpSelection) {
|
||||
case "Built-in":
|
||||
let keyarray = [];
|
||||
for (let i = 0; i < accessKeys.length; i++) {
|
||||
keyarray.push({
|
||||
access_key: accessKeys[i],
|
||||
secret_key: secretKeys[i],
|
||||
});
|
||||
}
|
||||
dataIDP = {
|
||||
keys: keyarray,
|
||||
};
|
||||
break;
|
||||
case "OpenID":
|
||||
dataIDP = {
|
||||
oidc: {
|
||||
configuration_url: openIDConfigurationURL,
|
||||
client_id: openIDClientID,
|
||||
secret_id: openIDSecretID,
|
||||
claim_name: openIDClaimName,
|
||||
callback_url: openIDCallbackURL,
|
||||
scopes: openIDScopes,
|
||||
},
|
||||
};
|
||||
break;
|
||||
case "AD":
|
||||
dataIDP = {
|
||||
active_directory: {
|
||||
url: ADURL,
|
||||
skip_tls_verification: ADSkipTLS,
|
||||
server_insecure: ADServerInsecure,
|
||||
group_search_base_dn: ADGroupSearchBaseDN,
|
||||
group_search_filter: ADGroupSearchFilter,
|
||||
user_dns: ADUserDNs,
|
||||
lookup_bind_dn: ADLookupBindDN,
|
||||
lookup_bind_password: ADLookupBindPassword,
|
||||
user_dn_search_base_dn: ADUserDNSearchBaseDN,
|
||||
user_dn_search_filter: ADUserDNSearchFilter,
|
||||
server_start_tls: ADServerStartTLS,
|
||||
},
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
let domains: any = {};
|
||||
let sendDomain: any = {};
|
||||
|
||||
if (setDomains) {
|
||||
if (consoleDomain !== "") {
|
||||
domains.console = consoleDomain;
|
||||
}
|
||||
|
||||
const filteredDomains = minioDomains.filter((dom) => dom.trim() !== "");
|
||||
|
||||
if (filteredDomains.length > 0) {
|
||||
domains.minio = filteredDomains;
|
||||
}
|
||||
|
||||
if (Object.keys(domains).length > 0) {
|
||||
sendDomain.domains = domains;
|
||||
}
|
||||
}
|
||||
|
||||
dataSend = {
|
||||
...dataSend,
|
||||
...sendDomain,
|
||||
idp: { ...dataIDP },
|
||||
};
|
||||
api
|
||||
.invoke("POST", `/api/v1/tenants`, dataSend)
|
||||
.then((res) => {
|
||||
const consoleSAList = get(res, "console", []);
|
||||
|
||||
let newSrvAcc: NewServiceAccount = {
|
||||
idp: get(res, "externalIDP", false),
|
||||
console: [],
|
||||
};
|
||||
|
||||
if (consoleSAList) {
|
||||
if (Array.isArray(consoleSAList)) {
|
||||
const consoleItem = consoleSAList.map((consoleKey) => {
|
||||
return {
|
||||
accessKey: consoleKey.access_key,
|
||||
secretKey: consoleKey.secret_key,
|
||||
api: "s3v4",
|
||||
path: "auto",
|
||||
url: consoleKey.url,
|
||||
};
|
||||
});
|
||||
|
||||
newSrvAcc.console = consoleItem;
|
||||
} else {
|
||||
newSrvAcc = {
|
||||
console: {
|
||||
accessKey: res.console.access_key,
|
||||
secretKey: res.console.secret_key,
|
||||
url: res.console.url,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
setAddSending(false);
|
||||
setShowNewCredentials(true);
|
||||
setCreatedAccount(newSrvAcc);
|
||||
})
|
||||
.catch((err: ErrorResponseHandler) => {
|
||||
setAddSending(false);
|
||||
dispatch(setErrorSnackMessage(err));
|
||||
});
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [addSending]);
|
||||
|
||||
const cancelButton = {
|
||||
label: "Cancel",
|
||||
type: "other",
|
||||
@@ -724,25 +118,9 @@ const AddTenant = () => {
|
||||
history.push("/tenants");
|
||||
},
|
||||
};
|
||||
const requiredPages = [
|
||||
"nameTenant",
|
||||
"tenantSize",
|
||||
"configure",
|
||||
"affinity",
|
||||
"identityProvider",
|
||||
"security",
|
||||
"encryption",
|
||||
];
|
||||
const createButton = {
|
||||
label: "Create",
|
||||
type: "submit",
|
||||
enabled:
|
||||
!addSending &&
|
||||
selectedStorageClass !== "" &&
|
||||
requiredPages.every((v) => validPages.includes(v)),
|
||||
action: () => {
|
||||
setAddSending(true);
|
||||
},
|
||||
|
||||
const createButton: IWizardButton = {
|
||||
componentRender: <CreateTenantButton />,
|
||||
};
|
||||
|
||||
const wizardSteps: IWizardElement[] = [
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2022 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 { Button } from "@mui/material";
|
||||
import React from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { AppState } from "../../../../store";
|
||||
import { requiredPages } from "./common";
|
||||
import { createTenantAsync } from "./thunks/createTenantThunk";
|
||||
|
||||
const CreateTenantButton = () => {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const addSending = useSelector(
|
||||
(state: AppState) => state.createTenant.addingTenant
|
||||
);
|
||||
|
||||
const validPages = useSelector(
|
||||
(state: AppState) => state.createTenant.validPages
|
||||
);
|
||||
|
||||
const selectedStorageClass = useSelector(
|
||||
(state: AppState) =>
|
||||
state.createTenant.fields.nameTenant.selectedStorageClass
|
||||
);
|
||||
|
||||
const enabled =
|
||||
!addSending &&
|
||||
selectedStorageClass !== "" &&
|
||||
requiredPages.every((v) => validPages.includes(v));
|
||||
|
||||
return (
|
||||
<Button
|
||||
id={"wizard-button-Create"}
|
||||
variant="contained"
|
||||
color="primary"
|
||||
size="small"
|
||||
onClick={() => {
|
||||
dispatch(createTenantAsync());
|
||||
}}
|
||||
disabled={!enabled}
|
||||
key={`button-AddTenant-Create`}
|
||||
>
|
||||
Create
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
|
||||
export default CreateTenantButton;
|
||||
@@ -48,12 +48,6 @@ const AWSKMSAdd = () => {
|
||||
const dispatch = useDispatch();
|
||||
const classes = useStyles();
|
||||
|
||||
const enableEncryption = useSelector(
|
||||
(state: AppState) => state.createTenant.fields.encryption.enableEncryption
|
||||
);
|
||||
const encryptionType = useSelector(
|
||||
(state: AppState) => state.createTenant.fields.encryption.encryptionType
|
||||
);
|
||||
const awsEndpoint = useSelector(
|
||||
(state: AppState) => state.createTenant.fields.encryption.awsEndpoint
|
||||
);
|
||||
@@ -78,33 +72,29 @@ const AWSKMSAdd = () => {
|
||||
useEffect(() => {
|
||||
let encryptionValidation: IValidation[] = [];
|
||||
|
||||
if (enableEncryption) {
|
||||
if (encryptionType === "aws") {
|
||||
encryptionValidation = [
|
||||
...encryptionValidation,
|
||||
{
|
||||
fieldKey: "aws_endpoint",
|
||||
required: true,
|
||||
value: awsEndpoint,
|
||||
},
|
||||
{
|
||||
fieldKey: "aws_region",
|
||||
required: true,
|
||||
value: awsRegion,
|
||||
},
|
||||
{
|
||||
fieldKey: "aws_accessKey",
|
||||
required: true,
|
||||
value: awsAccessKey,
|
||||
},
|
||||
{
|
||||
fieldKey: "aws_secretKey",
|
||||
required: true,
|
||||
value: awsSecretKey,
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
encryptionValidation = [
|
||||
...encryptionValidation,
|
||||
{
|
||||
fieldKey: "aws_endpoint",
|
||||
required: true,
|
||||
value: awsEndpoint,
|
||||
},
|
||||
{
|
||||
fieldKey: "aws_region",
|
||||
required: true,
|
||||
value: awsRegion,
|
||||
},
|
||||
{
|
||||
fieldKey: "aws_accessKey",
|
||||
required: true,
|
||||
value: awsAccessKey,
|
||||
},
|
||||
{
|
||||
fieldKey: "aws_secretKey",
|
||||
required: true,
|
||||
value: awsSecretKey,
|
||||
},
|
||||
];
|
||||
|
||||
const commonVal = commonFormValidation(encryptionValidation);
|
||||
|
||||
@@ -116,15 +106,7 @@ const AWSKMSAdd = () => {
|
||||
);
|
||||
|
||||
setValidationErrors(commonVal);
|
||||
}, [
|
||||
enableEncryption,
|
||||
encryptionType,
|
||||
awsEndpoint,
|
||||
awsRegion,
|
||||
awsSecretKey,
|
||||
awsAccessKey,
|
||||
dispatch,
|
||||
]);
|
||||
}, [awsEndpoint, awsRegion, awsSecretKey, awsAccessKey, dispatch]);
|
||||
|
||||
// Common
|
||||
const updateField = useCallback(
|
||||
|
||||
@@ -48,13 +48,6 @@ const AzureKMSAdd = () => {
|
||||
const dispatch = useDispatch();
|
||||
const classes = useStyles();
|
||||
|
||||
const enableEncryption = useSelector(
|
||||
(state: AppState) => state.createTenant.fields.encryption.enableEncryption
|
||||
);
|
||||
const encryptionType = useSelector(
|
||||
(state: AppState) => state.createTenant.fields.encryption.encryptionType
|
||||
);
|
||||
|
||||
const azureEndpoint = useSelector(
|
||||
(state: AppState) => state.createTenant.fields.encryption.azureEndpoint
|
||||
);
|
||||
@@ -74,33 +67,29 @@ const AzureKMSAdd = () => {
|
||||
useEffect(() => {
|
||||
let encryptionValidation: IValidation[] = [];
|
||||
|
||||
if (enableEncryption) {
|
||||
if (encryptionType === "azure") {
|
||||
encryptionValidation = [
|
||||
...encryptionValidation,
|
||||
{
|
||||
fieldKey: "azure_endpoint",
|
||||
required: true,
|
||||
value: azureEndpoint,
|
||||
},
|
||||
{
|
||||
fieldKey: "azure_tenant_id",
|
||||
required: true,
|
||||
value: azureTenantID,
|
||||
},
|
||||
{
|
||||
fieldKey: "azure_client_id",
|
||||
required: true,
|
||||
value: azureClientID,
|
||||
},
|
||||
{
|
||||
fieldKey: "azure_client_secret",
|
||||
required: true,
|
||||
value: azureClientSecret,
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
encryptionValidation = [
|
||||
...encryptionValidation,
|
||||
{
|
||||
fieldKey: "azure_endpoint",
|
||||
required: true,
|
||||
value: azureEndpoint,
|
||||
},
|
||||
{
|
||||
fieldKey: "azure_tenant_id",
|
||||
required: true,
|
||||
value: azureTenantID,
|
||||
},
|
||||
{
|
||||
fieldKey: "azure_client_id",
|
||||
required: true,
|
||||
value: azureClientID,
|
||||
},
|
||||
{
|
||||
fieldKey: "azure_client_secret",
|
||||
required: true,
|
||||
value: azureClientSecret,
|
||||
},
|
||||
];
|
||||
|
||||
const commonVal = commonFormValidation(encryptionValidation);
|
||||
|
||||
@@ -113,8 +102,6 @@ const AzureKMSAdd = () => {
|
||||
|
||||
setValidationErrors(commonVal);
|
||||
}, [
|
||||
enableEncryption,
|
||||
encryptionType,
|
||||
azureEndpoint,
|
||||
azureTenantID,
|
||||
azureClientID,
|
||||
|
||||
@@ -53,12 +53,6 @@ const GemaltoKMSAdd = () => {
|
||||
const dispatch = useDispatch();
|
||||
const classes = useStyles();
|
||||
|
||||
const enableEncryption = useSelector(
|
||||
(state: AppState) => state.createTenant.fields.encryption.enableEncryption
|
||||
);
|
||||
const encryptionType = useSelector(
|
||||
(state: AppState) => state.createTenant.fields.encryption.encryptionType
|
||||
);
|
||||
const gemaltoCA = useSelector(
|
||||
(state: AppState) => state.createTenant.certificates.gemaltoCA
|
||||
);
|
||||
@@ -81,35 +75,31 @@ const GemaltoKMSAdd = () => {
|
||||
useEffect(() => {
|
||||
let encryptionValidation: IValidation[] = [];
|
||||
|
||||
if (enableEncryption) {
|
||||
if (encryptionType === "gemalto") {
|
||||
encryptionValidation = [
|
||||
...encryptionValidation,
|
||||
{
|
||||
fieldKey: "gemalto_endpoint",
|
||||
required: true,
|
||||
value: gemaltoEndpoint,
|
||||
},
|
||||
{
|
||||
fieldKey: "gemalto_token",
|
||||
required: true,
|
||||
value: gemaltoToken,
|
||||
},
|
||||
{
|
||||
fieldKey: "gemalto_domain",
|
||||
required: true,
|
||||
value: gemaltoDomain,
|
||||
},
|
||||
{
|
||||
fieldKey: "gemalto_retry",
|
||||
required: false,
|
||||
value: gemaltoRetry,
|
||||
customValidation: parseInt(gemaltoRetry) < 0,
|
||||
customValidationMessage: "Value needs to be 0 or greater",
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
encryptionValidation = [
|
||||
...encryptionValidation,
|
||||
{
|
||||
fieldKey: "gemalto_endpoint",
|
||||
required: true,
|
||||
value: gemaltoEndpoint,
|
||||
},
|
||||
{
|
||||
fieldKey: "gemalto_token",
|
||||
required: true,
|
||||
value: gemaltoToken,
|
||||
},
|
||||
{
|
||||
fieldKey: "gemalto_domain",
|
||||
required: true,
|
||||
value: gemaltoDomain,
|
||||
},
|
||||
{
|
||||
fieldKey: "gemalto_retry",
|
||||
required: false,
|
||||
value: gemaltoRetry,
|
||||
customValidation: parseInt(gemaltoRetry) < 0,
|
||||
customValidationMessage: "Value needs to be 0 or greater",
|
||||
},
|
||||
];
|
||||
|
||||
const commonVal = commonFormValidation(encryptionValidation);
|
||||
|
||||
@@ -121,15 +111,7 @@ const GemaltoKMSAdd = () => {
|
||||
);
|
||||
|
||||
setValidationErrors(commonVal);
|
||||
}, [
|
||||
enableEncryption,
|
||||
encryptionType,
|
||||
gemaltoEndpoint,
|
||||
gemaltoToken,
|
||||
gemaltoDomain,
|
||||
gemaltoRetry,
|
||||
dispatch,
|
||||
]);
|
||||
}, [gemaltoEndpoint, gemaltoToken, gemaltoDomain, gemaltoRetry, dispatch]);
|
||||
|
||||
// Common
|
||||
const updateField = useCallback(
|
||||
|
||||
@@ -55,13 +55,6 @@ const VaultKMSAdd = () => {
|
||||
const dispatch = useDispatch();
|
||||
const classes = useStyles();
|
||||
|
||||
const enableEncryption = useSelector(
|
||||
(state: AppState) => state.createTenant.fields.encryption.enableEncryption
|
||||
);
|
||||
const encryptionType = useSelector(
|
||||
(state: AppState) => state.createTenant.fields.encryption.encryptionType
|
||||
);
|
||||
|
||||
const vaultEndpoint = useSelector(
|
||||
(state: AppState) => state.createTenant.fields.encryption.vaultEndpoint
|
||||
);
|
||||
@@ -102,42 +95,38 @@ const VaultKMSAdd = () => {
|
||||
useEffect(() => {
|
||||
let encryptionValidation: IValidation[] = [];
|
||||
|
||||
if (enableEncryption) {
|
||||
if (encryptionType === "vault") {
|
||||
encryptionValidation = [
|
||||
...encryptionValidation,
|
||||
{
|
||||
fieldKey: "vault_endpoint",
|
||||
required: true,
|
||||
value: vaultEndpoint,
|
||||
},
|
||||
{
|
||||
fieldKey: "vault_id",
|
||||
required: true,
|
||||
value: vaultId,
|
||||
},
|
||||
{
|
||||
fieldKey: "vault_secret",
|
||||
required: true,
|
||||
value: vaultSecret,
|
||||
},
|
||||
{
|
||||
fieldKey: "vault_ping",
|
||||
required: false,
|
||||
value: vaultPing,
|
||||
customValidation: parseInt(vaultPing) < 0,
|
||||
customValidationMessage: "Value needs to be 0 or greater",
|
||||
},
|
||||
{
|
||||
fieldKey: "vault_retry",
|
||||
required: false,
|
||||
value: vaultRetry,
|
||||
customValidation: parseInt(vaultRetry) < 0,
|
||||
customValidationMessage: "Value needs to be 0 or greater",
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
encryptionValidation = [
|
||||
...encryptionValidation,
|
||||
{
|
||||
fieldKey: "vault_endpoint",
|
||||
required: true,
|
||||
value: vaultEndpoint,
|
||||
},
|
||||
{
|
||||
fieldKey: "vault_id",
|
||||
required: true,
|
||||
value: vaultId,
|
||||
},
|
||||
{
|
||||
fieldKey: "vault_secret",
|
||||
required: true,
|
||||
value: vaultSecret,
|
||||
},
|
||||
{
|
||||
fieldKey: "vault_ping",
|
||||
required: false,
|
||||
value: vaultPing,
|
||||
customValidation: parseInt(vaultPing) < 0,
|
||||
customValidationMessage: "Value needs to be 0 or greater",
|
||||
},
|
||||
{
|
||||
fieldKey: "vault_retry",
|
||||
required: false,
|
||||
value: vaultRetry,
|
||||
customValidation: parseInt(vaultRetry) < 0,
|
||||
customValidationMessage: "Value needs to be 0 or greater",
|
||||
},
|
||||
];
|
||||
|
||||
const commonVal = commonFormValidation(encryptionValidation);
|
||||
|
||||
@@ -150,8 +139,6 @@ const VaultKMSAdd = () => {
|
||||
|
||||
setValidationErrors(commonVal);
|
||||
}, [
|
||||
enableEncryption,
|
||||
encryptionType,
|
||||
vaultEndpoint,
|
||||
vaultEngine,
|
||||
vaultId,
|
||||
|
||||
@@ -58,6 +58,7 @@ import {
|
||||
setLimitSize,
|
||||
setStorageClassesList,
|
||||
setStorageType,
|
||||
setTenantName,
|
||||
updateAddField,
|
||||
} from "../../createTenantSlice";
|
||||
import { selFeatures } from "../../../../consoleSlice";
|
||||
@@ -76,6 +77,31 @@ const styles = (theme: Theme) =>
|
||||
...wizardCommon,
|
||||
});
|
||||
|
||||
const NameTenantField = () => {
|
||||
const dispatch = useDispatch();
|
||||
const tenantName = useSelector(
|
||||
(state: AppState) => state.createTenant.fields.nameTenant.tenantName
|
||||
);
|
||||
|
||||
const tenantNameError = useSelector(
|
||||
(state: AppState) => state.createTenant.validationErrors["tenant-name"]
|
||||
);
|
||||
|
||||
return (
|
||||
<InputBoxWrapper
|
||||
id="tenant-name"
|
||||
name="tenant-name"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
dispatch(setTenantName(e.target.value));
|
||||
}}
|
||||
label="Name"
|
||||
value={tenantName}
|
||||
required
|
||||
error={tenantNameError || ""}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
interface INameTenantMainScreen {
|
||||
classes: any;
|
||||
formToRender?: IMkEnvs;
|
||||
@@ -84,9 +110,6 @@ interface INameTenantMainScreen {
|
||||
const NameTenantMain = ({ classes, formToRender }: INameTenantMainScreen) => {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const tenantName = useSelector(
|
||||
(state: AppState) => state.createTenant.fields.nameTenant.tenantName
|
||||
);
|
||||
const namespace = useSelector(
|
||||
(state: AppState) => state.createTenant.fields.nameTenant.namespace
|
||||
);
|
||||
@@ -219,14 +242,6 @@ const NameTenantMain = ({ classes, formToRender }: INameTenantMainScreen) => {
|
||||
}
|
||||
|
||||
const commonValidation = commonFormValidation([
|
||||
{
|
||||
fieldKey: "tenant-name",
|
||||
required: true,
|
||||
pattern: /^[a-z0-9-]{3,63}$/,
|
||||
customPatternMessage:
|
||||
"Name only can contain lowercase letters, numbers and '-'. Min. Length: 3",
|
||||
value: tenantName,
|
||||
},
|
||||
{
|
||||
fieldKey: "namespace",
|
||||
required: true,
|
||||
@@ -237,7 +252,6 @@ const NameTenantMain = ({ classes, formToRender }: INameTenantMainScreen) => {
|
||||
]);
|
||||
|
||||
const isValid =
|
||||
!("tenant-name" in commonValidation) &&
|
||||
!("namespace" in commonValidation) &&
|
||||
((formToRender === IMkEnvs.default && storageClasses.length > 0) ||
|
||||
(formToRender !== IMkEnvs.default && selectedStorageType !== ""));
|
||||
@@ -248,7 +262,6 @@ const NameTenantMain = ({ classes, formToRender }: INameTenantMainScreen) => {
|
||||
}, [
|
||||
storageClasses,
|
||||
namespace,
|
||||
tenantName,
|
||||
dispatch,
|
||||
emptyNamespace,
|
||||
loadingNamespaceInfo,
|
||||
@@ -293,18 +306,7 @@ const NameTenantMain = ({ classes, formToRender }: INameTenantMainScreen) => {
|
||||
</span>
|
||||
</div>
|
||||
<div className={classes.formFieldRow}>
|
||||
<InputBoxWrapper
|
||||
id="tenant-name"
|
||||
name="tenant-name"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
updateField("tenantName", e.target.value);
|
||||
frmValidationCleanup("tenant-name");
|
||||
}}
|
||||
label="Name"
|
||||
value={tenantName}
|
||||
required
|
||||
error={validationErrors["tenant-name"] || ""}
|
||||
/>
|
||||
<NameTenantField />
|
||||
</div>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
|
||||
24
portal-ui/src/screens/Console/Tenants/AddTenant/common.ts
Normal file
24
portal-ui/src/screens/Console/Tenants/AddTenant/common.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2022 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/>.
|
||||
export const requiredPages = [
|
||||
"nameTenant",
|
||||
"tenantSize",
|
||||
"configure",
|
||||
"affinity",
|
||||
"identityProvider",
|
||||
"security",
|
||||
"encryption",
|
||||
];
|
||||
@@ -0,0 +1,61 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2022 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 api from "../../../../common/api";
|
||||
import get from "lodash/get";
|
||||
import { NewServiceAccount } from "../../Common/CredentialsPrompt/types";
|
||||
import { ErrorResponseHandler, ITenantCreator } from "../../../../common/types";
|
||||
|
||||
export const createTenantCall = (dataSend: ITenantCreator) => {
|
||||
return new Promise<NewServiceAccount>((resolve, reject) => {
|
||||
api
|
||||
.invoke("POST", `/api/v1/tenants`, dataSend)
|
||||
.then((res) => {
|
||||
const consoleSAList = get(res, "console", []);
|
||||
|
||||
let newSrvAcc: NewServiceAccount = {
|
||||
idp: get(res, "externalIDP", false),
|
||||
console: [],
|
||||
};
|
||||
|
||||
if (consoleSAList) {
|
||||
if (Array.isArray(consoleSAList)) {
|
||||
newSrvAcc.console = consoleSAList.map((consoleKey) => {
|
||||
return {
|
||||
accessKey: consoleKey.access_key,
|
||||
secretKey: consoleKey.secret_key,
|
||||
api: "s3v4",
|
||||
path: "auto",
|
||||
url: consoleKey.url,
|
||||
};
|
||||
});
|
||||
} else {
|
||||
newSrvAcc = {
|
||||
console: {
|
||||
accessKey: res.console.access_key,
|
||||
secretKey: res.console.secret_key,
|
||||
url: res.console.url,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
resolve(newSrvAcc);
|
||||
})
|
||||
.catch((err: ErrorResponseHandler) => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
@@ -33,19 +33,29 @@ import {
|
||||
} from "./Steps/TenantResources/utils";
|
||||
import { getBytesNumber } from "../../../../common/utils";
|
||||
import { CertificateFile, FileValue, KeyFileValue } from "../tenantsSlice";
|
||||
import { NewServiceAccount } from "../../Common/CredentialsPrompt/types";
|
||||
import { createTenantAsync } from "./thunks/createTenantThunk";
|
||||
import { commonFormValidation } from "../../../../utils/validationFunctions";
|
||||
import { flipValidPageInState } from "./sliceUtils";
|
||||
|
||||
export interface ICreateTenant {
|
||||
addingTenant: boolean;
|
||||
page: number;
|
||||
validPages: string[];
|
||||
validationErrors: { [key: string]: string };
|
||||
storageClasses: Opts[];
|
||||
limitSize: any;
|
||||
fields: IFieldStore;
|
||||
certificates: ICertificatesItems;
|
||||
nodeSelectorPairs: LabelKeyPair[];
|
||||
tolerations: ITolerationModel[];
|
||||
// after creation states
|
||||
createdAccount: NewServiceAccount | null;
|
||||
showNewCredentials: boolean;
|
||||
}
|
||||
|
||||
const initialState: ICreateTenant = {
|
||||
addingTenant: false,
|
||||
page: 0,
|
||||
// We can assume all the other pages are valid with default configuration except for 'nameTenant'
|
||||
// because the user still have to choose a namespace and a name for the tenant
|
||||
@@ -57,6 +67,7 @@ const initialState: ICreateTenant = {
|
||||
"security",
|
||||
"encryption",
|
||||
],
|
||||
validationErrors: {},
|
||||
storageClasses: [],
|
||||
limitSize: {},
|
||||
fields: {
|
||||
@@ -340,6 +351,8 @@ const initialState: ICreateTenant = {
|
||||
operator: ITolerationOperator.Equal,
|
||||
},
|
||||
],
|
||||
createdAccount: null,
|
||||
showNewCredentials: false,
|
||||
};
|
||||
|
||||
export const createTenantSlice = createSlice({
|
||||
@@ -382,7 +395,6 @@ export const createTenantSlice = createSlice({
|
||||
}>
|
||||
) => {
|
||||
let originValidPages = state.validPages;
|
||||
|
||||
if (action.payload.valid) {
|
||||
if (!originValidPages.includes(action.payload.pageName)) {
|
||||
originValidPages.push(action.payload.pageName);
|
||||
@@ -393,7 +405,6 @@ export const createTenantSlice = createSlice({
|
||||
const newSetOfPages = originValidPages.filter(
|
||||
(elm) => elm !== action.payload.pageName
|
||||
);
|
||||
|
||||
state.validPages = [...newSetOfPages];
|
||||
}
|
||||
},
|
||||
@@ -658,302 +669,304 @@ export const createTenantSlice = createSlice({
|
||||
};
|
||||
},
|
||||
resetAddTenantForm: (state) => {
|
||||
state = {
|
||||
page: 0,
|
||||
// We can assume all the other pages are valid with default configuration except for 'nameTenant'
|
||||
// because the user still have to choose a namespace and a name for the tenant
|
||||
validPages: [
|
||||
"tenantSize",
|
||||
"configure",
|
||||
"affinity",
|
||||
"identityProvider",
|
||||
"security",
|
||||
"encryption",
|
||||
],
|
||||
storageClasses: [],
|
||||
limitSize: {},
|
||||
fields: {
|
||||
nameTenant: {
|
||||
tenantName: "",
|
||||
namespace: "",
|
||||
selectedStorageClass: "",
|
||||
selectedStorageType: "",
|
||||
state.addingTenant = false;
|
||||
state.page = 0;
|
||||
// We can assume all the other pages are valid with default configuration except for 'nameTenant'
|
||||
// because the user still have to choose a namespace and a name for the tenant
|
||||
state.validPages = [
|
||||
"tenantSize",
|
||||
"configure",
|
||||
"affinity",
|
||||
"identityProvider",
|
||||
"security",
|
||||
"encryption",
|
||||
];
|
||||
state.validationErrors = {};
|
||||
state.storageClasses = [];
|
||||
state.limitSize = {};
|
||||
state.fields = {
|
||||
nameTenant: {
|
||||
tenantName: "",
|
||||
namespace: "",
|
||||
selectedStorageClass: "",
|
||||
selectedStorageType: "",
|
||||
},
|
||||
configure: {
|
||||
customImage: false,
|
||||
imageName: "",
|
||||
customDockerhub: false,
|
||||
imageRegistry: "",
|
||||
imageRegistryUsername: "",
|
||||
imageRegistryPassword: "",
|
||||
exposeMinIO: true,
|
||||
exposeConsole: true,
|
||||
tenantCustom: false,
|
||||
logSearchEnabled: true,
|
||||
prometheusEnabled: true,
|
||||
logSearchVolumeSize: "5",
|
||||
logSearchSizeFactor: "Gi",
|
||||
logSearchSelectedStorageClass: "default",
|
||||
logSearchImage: "",
|
||||
kesImage: "",
|
||||
logSearchPostgresImage: "",
|
||||
logSearchPostgresInitImage: "",
|
||||
prometheusVolumeSize: "5",
|
||||
prometheusSizeFactor: "Gi",
|
||||
prometheusSelectedStorageClass: "default",
|
||||
prometheusImage: "",
|
||||
prometheusSidecarImage: "",
|
||||
prometheusInitImage: "",
|
||||
setDomains: false,
|
||||
consoleDomain: "",
|
||||
minioDomains: [""],
|
||||
tenantSecurityContext: {
|
||||
runAsUser: "1000",
|
||||
runAsGroup: "1000",
|
||||
fsGroup: "1000",
|
||||
runAsNonRoot: true,
|
||||
},
|
||||
configure: {
|
||||
customImage: false,
|
||||
imageName: "",
|
||||
customDockerhub: false,
|
||||
imageRegistry: "",
|
||||
imageRegistryUsername: "",
|
||||
imageRegistryPassword: "",
|
||||
exposeMinIO: true,
|
||||
exposeConsole: true,
|
||||
tenantCustom: false,
|
||||
logSearchEnabled: true,
|
||||
prometheusEnabled: true,
|
||||
logSearchVolumeSize: "5",
|
||||
logSearchSizeFactor: "Gi",
|
||||
logSearchSelectedStorageClass: "default",
|
||||
logSearchImage: "",
|
||||
kesImage: "",
|
||||
logSearchPostgresImage: "",
|
||||
logSearchPostgresInitImage: "",
|
||||
prometheusVolumeSize: "5",
|
||||
prometheusSizeFactor: "Gi",
|
||||
prometheusSelectedStorageClass: "default",
|
||||
prometheusImage: "",
|
||||
prometheusSidecarImage: "",
|
||||
prometheusInitImage: "",
|
||||
setDomains: false,
|
||||
consoleDomain: "",
|
||||
minioDomains: [""],
|
||||
tenantSecurityContext: {
|
||||
runAsUser: "1000",
|
||||
runAsGroup: "1000",
|
||||
fsGroup: "1000",
|
||||
runAsNonRoot: true,
|
||||
},
|
||||
logSearchSecurityContext: {
|
||||
runAsUser: "1000",
|
||||
runAsGroup: "1000",
|
||||
fsGroup: "1000",
|
||||
runAsNonRoot: true,
|
||||
},
|
||||
logSearchPostgresSecurityContext: {
|
||||
runAsUser: "999",
|
||||
runAsGroup: "999",
|
||||
fsGroup: "999",
|
||||
runAsNonRoot: true,
|
||||
},
|
||||
prometheusSecurityContext: {
|
||||
runAsUser: "1000",
|
||||
runAsGroup: "1000",
|
||||
fsGroup: "1000",
|
||||
runAsNonRoot: true,
|
||||
},
|
||||
logSearchSecurityContext: {
|
||||
runAsUser: "1000",
|
||||
runAsGroup: "1000",
|
||||
fsGroup: "1000",
|
||||
runAsNonRoot: true,
|
||||
},
|
||||
identityProvider: {
|
||||
idpSelection: "Built-in",
|
||||
accessKeys: [getRandomString(16)],
|
||||
secretKeys: [getRandomString(32)],
|
||||
openIDConfigurationURL: "",
|
||||
openIDClientID: "",
|
||||
openIDSecretID: "",
|
||||
openIDCallbackURL: "",
|
||||
openIDClaimName: "",
|
||||
openIDScopes: "",
|
||||
ADURL: "",
|
||||
ADSkipTLS: false,
|
||||
ADServerInsecure: false,
|
||||
ADGroupSearchBaseDN: "",
|
||||
ADGroupSearchFilter: "",
|
||||
ADUserDNs: [""],
|
||||
ADLookupBindDN: "",
|
||||
ADLookupBindPassword: "",
|
||||
ADUserDNSearchBaseDN: "",
|
||||
ADUserDNSearchFilter: "",
|
||||
ADServerStartTLS: false,
|
||||
logSearchPostgresSecurityContext: {
|
||||
runAsUser: "999",
|
||||
runAsGroup: "999",
|
||||
fsGroup: "999",
|
||||
runAsNonRoot: true,
|
||||
},
|
||||
security: {
|
||||
enableAutoCert: true,
|
||||
enableCustomCerts: false,
|
||||
enableTLS: true,
|
||||
},
|
||||
encryption: {
|
||||
enableEncryption: false,
|
||||
encryptionType: "vault",
|
||||
gemaltoEndpoint: "",
|
||||
gemaltoToken: "",
|
||||
gemaltoDomain: "",
|
||||
gemaltoRetry: "0",
|
||||
awsEndpoint: "",
|
||||
awsRegion: "",
|
||||
awsKMSKey: "",
|
||||
awsAccessKey: "",
|
||||
awsSecretKey: "",
|
||||
awsToken: "",
|
||||
vaultEndpoint: "",
|
||||
vaultEngine: "",
|
||||
vaultNamespace: "",
|
||||
vaultPrefix: "",
|
||||
vaultAppRoleEngine: "",
|
||||
vaultId: "",
|
||||
vaultSecret: "",
|
||||
vaultRetry: "0",
|
||||
vaultPing: "0",
|
||||
azureEndpoint: "",
|
||||
azureTenantID: "",
|
||||
azureClientID: "",
|
||||
azureClientSecret: "",
|
||||
gcpProjectID: "",
|
||||
gcpEndpoint: "",
|
||||
gcpClientEmail: "",
|
||||
gcpClientID: "",
|
||||
gcpPrivateKeyID: "",
|
||||
gcpPrivateKey: "",
|
||||
enableCustomCertsForKES: false,
|
||||
replicas: "1",
|
||||
kesSecurityContext: {
|
||||
runAsUser: "1000",
|
||||
runAsGroup: "1000",
|
||||
fsGroup: "1000",
|
||||
runAsNonRoot: true,
|
||||
},
|
||||
},
|
||||
tenantSize: {
|
||||
volumeSize: "1024",
|
||||
sizeFactor: "Gi",
|
||||
drivesPerServer: "4",
|
||||
nodes: "4",
|
||||
memoryNode: "2",
|
||||
ecParity: "",
|
||||
ecParityChoices: [],
|
||||
cleanECChoices: [],
|
||||
untouchedECField: true,
|
||||
distribution: {
|
||||
error: "",
|
||||
nodes: 0,
|
||||
persistentVolumes: 0,
|
||||
disks: 0,
|
||||
},
|
||||
ecParityCalc: {
|
||||
error: 0,
|
||||
defaultEC: "",
|
||||
erasureCodeSet: 0,
|
||||
maxEC: "",
|
||||
rawCapacity: "0",
|
||||
storageFactors: [],
|
||||
},
|
||||
limitSize: {},
|
||||
cpuToUse: "0",
|
||||
// resource request
|
||||
resourcesSpecifyLimit: false,
|
||||
resourcesCPURequestError: "",
|
||||
resourcesCPURequest: "",
|
||||
resourcesCPULimitError: "",
|
||||
resourcesCPULimit: "",
|
||||
resourcesMemoryRequestError: "",
|
||||
resourcesMemoryRequest: "",
|
||||
resourcesMemoryLimitError: "",
|
||||
resourcesMemoryLimit: "",
|
||||
resourcesSize: {
|
||||
error: "",
|
||||
memoryRequest: 0,
|
||||
memoryLimit: 0,
|
||||
cpuRequest: 0,
|
||||
cpuLimit: 0,
|
||||
},
|
||||
maxAllocatableResources: {
|
||||
min_allocatable_mem: 0,
|
||||
min_allocatable_cpu: 0,
|
||||
cpu_priority: {
|
||||
max_allocatable_cpu: 0,
|
||||
max_allocatable_mem: 0,
|
||||
},
|
||||
mem_priority: {
|
||||
max_allocatable_cpu: 0,
|
||||
max_allocatable_mem: 0,
|
||||
},
|
||||
},
|
||||
maxCPUsUse: "0",
|
||||
maxMemorySize: "0",
|
||||
integrationSelection: {
|
||||
driveSize: { driveSize: "0", sizeUnit: "B" },
|
||||
CPU: 0,
|
||||
typeSelection: "",
|
||||
memory: 0,
|
||||
drivesPerServer: 0,
|
||||
storageClass: "",
|
||||
},
|
||||
},
|
||||
affinity: {
|
||||
nodeSelectorLabels: "",
|
||||
podAffinity: "default",
|
||||
withPodAntiAffinity: true,
|
||||
prometheusSecurityContext: {
|
||||
runAsUser: "1000",
|
||||
runAsGroup: "1000",
|
||||
fsGroup: "1000",
|
||||
runAsNonRoot: true,
|
||||
},
|
||||
},
|
||||
certificates: {
|
||||
minioCertificates: [
|
||||
{
|
||||
id: Date.now().toString(),
|
||||
key: "",
|
||||
cert: "",
|
||||
encoded_key: "",
|
||||
encoded_cert: "",
|
||||
},
|
||||
],
|
||||
caCertificates: [
|
||||
{
|
||||
id: Date.now().toString(),
|
||||
key: "",
|
||||
cert: "",
|
||||
encoded_key: "",
|
||||
encoded_cert: "",
|
||||
},
|
||||
],
|
||||
consoleCaCertificates: [
|
||||
{
|
||||
id: Date.now().toString(),
|
||||
key: "",
|
||||
cert: "",
|
||||
encoded_key: "",
|
||||
encoded_cert: "",
|
||||
},
|
||||
],
|
||||
consoleCertificate: {
|
||||
id: "console_cert_pair",
|
||||
key: "",
|
||||
cert: "",
|
||||
encoded_key: "",
|
||||
encoded_cert: "",
|
||||
},
|
||||
serverCertificate: {
|
||||
id: "encryptionServerCertificate",
|
||||
key: "",
|
||||
cert: "",
|
||||
encoded_key: "",
|
||||
encoded_cert: "",
|
||||
},
|
||||
clientCertificate: {
|
||||
id: "encryptionClientCertificate",
|
||||
key: "",
|
||||
cert: "",
|
||||
encoded_key: "",
|
||||
encoded_cert: "",
|
||||
},
|
||||
vaultCertificate: {
|
||||
id: "encryptionVaultCertificate",
|
||||
key: "",
|
||||
cert: "",
|
||||
encoded_key: "",
|
||||
encoded_cert: "",
|
||||
},
|
||||
vaultCA: {
|
||||
id: "encryptionVaultCA",
|
||||
key: "",
|
||||
cert: "",
|
||||
encoded_key: "",
|
||||
encoded_cert: "",
|
||||
},
|
||||
gemaltoCA: {
|
||||
id: "encryptionGemaltoCA",
|
||||
key: "",
|
||||
cert: "",
|
||||
encoded_key: "",
|
||||
encoded_cert: "",
|
||||
identityProvider: {
|
||||
idpSelection: "Built-in",
|
||||
accessKeys: [getRandomString(16)],
|
||||
secretKeys: [getRandomString(32)],
|
||||
openIDConfigurationURL: "",
|
||||
openIDClientID: "",
|
||||
openIDSecretID: "",
|
||||
openIDCallbackURL: "",
|
||||
openIDClaimName: "",
|
||||
openIDScopes: "",
|
||||
ADURL: "",
|
||||
ADSkipTLS: false,
|
||||
ADServerInsecure: false,
|
||||
ADGroupSearchBaseDN: "",
|
||||
ADGroupSearchFilter: "",
|
||||
ADUserDNs: [""],
|
||||
ADLookupBindDN: "",
|
||||
ADLookupBindPassword: "",
|
||||
ADUserDNSearchBaseDN: "",
|
||||
ADUserDNSearchFilter: "",
|
||||
ADServerStartTLS: false,
|
||||
},
|
||||
security: {
|
||||
enableAutoCert: true,
|
||||
enableCustomCerts: false,
|
||||
enableTLS: true,
|
||||
},
|
||||
encryption: {
|
||||
enableEncryption: false,
|
||||
encryptionType: "vault",
|
||||
gemaltoEndpoint: "",
|
||||
gemaltoToken: "",
|
||||
gemaltoDomain: "",
|
||||
gemaltoRetry: "0",
|
||||
awsEndpoint: "",
|
||||
awsRegion: "",
|
||||
awsKMSKey: "",
|
||||
awsAccessKey: "",
|
||||
awsSecretKey: "",
|
||||
awsToken: "",
|
||||
vaultEndpoint: "",
|
||||
vaultEngine: "",
|
||||
vaultNamespace: "",
|
||||
vaultPrefix: "",
|
||||
vaultAppRoleEngine: "",
|
||||
vaultId: "",
|
||||
vaultSecret: "",
|
||||
vaultRetry: "0",
|
||||
vaultPing: "0",
|
||||
azureEndpoint: "",
|
||||
azureTenantID: "",
|
||||
azureClientID: "",
|
||||
azureClientSecret: "",
|
||||
gcpProjectID: "",
|
||||
gcpEndpoint: "",
|
||||
gcpClientEmail: "",
|
||||
gcpClientID: "",
|
||||
gcpPrivateKeyID: "",
|
||||
gcpPrivateKey: "",
|
||||
enableCustomCertsForKES: false,
|
||||
replicas: "1",
|
||||
kesSecurityContext: {
|
||||
runAsUser: "1000",
|
||||
runAsGroup: "1000",
|
||||
fsGroup: "1000",
|
||||
runAsNonRoot: true,
|
||||
},
|
||||
},
|
||||
nodeSelectorPairs: [{ key: "", value: "" }],
|
||||
tolerations: [
|
||||
{
|
||||
key: "",
|
||||
tolerationSeconds: { seconds: 0 },
|
||||
value: "",
|
||||
effect: ITolerationEffect.NoSchedule,
|
||||
operator: ITolerationOperator.Equal,
|
||||
tenantSize: {
|
||||
volumeSize: "1024",
|
||||
sizeFactor: "Gi",
|
||||
drivesPerServer: "4",
|
||||
nodes: "4",
|
||||
memoryNode: "2",
|
||||
ecParity: "",
|
||||
ecParityChoices: [],
|
||||
cleanECChoices: [],
|
||||
untouchedECField: true,
|
||||
distribution: {
|
||||
error: "",
|
||||
nodes: 0,
|
||||
persistentVolumes: 0,
|
||||
disks: 0,
|
||||
},
|
||||
],
|
||||
ecParityCalc: {
|
||||
error: 0,
|
||||
defaultEC: "",
|
||||
erasureCodeSet: 0,
|
||||
maxEC: "",
|
||||
rawCapacity: "0",
|
||||
storageFactors: [],
|
||||
},
|
||||
limitSize: {},
|
||||
cpuToUse: "0",
|
||||
// resource request
|
||||
resourcesSpecifyLimit: false,
|
||||
resourcesCPURequestError: "",
|
||||
resourcesCPURequest: "",
|
||||
resourcesCPULimitError: "",
|
||||
resourcesCPULimit: "",
|
||||
resourcesMemoryRequestError: "",
|
||||
resourcesMemoryRequest: "",
|
||||
resourcesMemoryLimitError: "",
|
||||
resourcesMemoryLimit: "",
|
||||
resourcesSize: {
|
||||
error: "",
|
||||
memoryRequest: 0,
|
||||
memoryLimit: 0,
|
||||
cpuRequest: 0,
|
||||
cpuLimit: 0,
|
||||
},
|
||||
maxAllocatableResources: {
|
||||
min_allocatable_mem: 0,
|
||||
min_allocatable_cpu: 0,
|
||||
cpu_priority: {
|
||||
max_allocatable_cpu: 0,
|
||||
max_allocatable_mem: 0,
|
||||
},
|
||||
mem_priority: {
|
||||
max_allocatable_cpu: 0,
|
||||
max_allocatable_mem: 0,
|
||||
},
|
||||
},
|
||||
maxCPUsUse: "0",
|
||||
maxMemorySize: "0",
|
||||
integrationSelection: {
|
||||
driveSize: { driveSize: "0", sizeUnit: "B" },
|
||||
CPU: 0,
|
||||
typeSelection: "",
|
||||
memory: 0,
|
||||
drivesPerServer: 0,
|
||||
storageClass: "",
|
||||
},
|
||||
},
|
||||
affinity: {
|
||||
nodeSelectorLabels: "",
|
||||
podAffinity: "default",
|
||||
withPodAntiAffinity: true,
|
||||
},
|
||||
};
|
||||
state.certificates = {
|
||||
minioCertificates: [
|
||||
{
|
||||
id: Date.now().toString(),
|
||||
key: "",
|
||||
cert: "",
|
||||
encoded_key: "",
|
||||
encoded_cert: "",
|
||||
},
|
||||
],
|
||||
caCertificates: [
|
||||
{
|
||||
id: Date.now().toString(),
|
||||
key: "",
|
||||
cert: "",
|
||||
encoded_key: "",
|
||||
encoded_cert: "",
|
||||
},
|
||||
],
|
||||
consoleCaCertificates: [
|
||||
{
|
||||
id: Date.now().toString(),
|
||||
key: "",
|
||||
cert: "",
|
||||
encoded_key: "",
|
||||
encoded_cert: "",
|
||||
},
|
||||
],
|
||||
consoleCertificate: {
|
||||
id: "console_cert_pair",
|
||||
key: "",
|
||||
cert: "",
|
||||
encoded_key: "",
|
||||
encoded_cert: "",
|
||||
},
|
||||
serverCertificate: {
|
||||
id: "encryptionServerCertificate",
|
||||
key: "",
|
||||
cert: "",
|
||||
encoded_key: "",
|
||||
encoded_cert: "",
|
||||
},
|
||||
clientCertificate: {
|
||||
id: "encryptionClientCertificate",
|
||||
key: "",
|
||||
cert: "",
|
||||
encoded_key: "",
|
||||
encoded_cert: "",
|
||||
},
|
||||
vaultCertificate: {
|
||||
id: "encryptionVaultCertificate",
|
||||
key: "",
|
||||
cert: "",
|
||||
encoded_key: "",
|
||||
encoded_cert: "",
|
||||
},
|
||||
vaultCA: {
|
||||
id: "encryptionVaultCA",
|
||||
key: "",
|
||||
cert: "",
|
||||
encoded_key: "",
|
||||
encoded_cert: "",
|
||||
},
|
||||
gemaltoCA: {
|
||||
id: "encryptionGemaltoCA",
|
||||
key: "",
|
||||
cert: "",
|
||||
encoded_key: "",
|
||||
encoded_cert: "",
|
||||
},
|
||||
};
|
||||
state.nodeSelectorPairs = [{ key: "", value: "" }];
|
||||
state.tolerations = [
|
||||
{
|
||||
key: "",
|
||||
tolerationSeconds: { seconds: 0 },
|
||||
value: "",
|
||||
effect: ITolerationEffect.NoSchedule,
|
||||
operator: ITolerationOperator.Equal,
|
||||
},
|
||||
];
|
||||
state.createdAccount = null;
|
||||
state.showNewCredentials = false;
|
||||
},
|
||||
setKeyValuePairs: (state, action: PayloadAction<LabelKeyPair[]>) => {
|
||||
state.nodeSelectorPairs = action.payload;
|
||||
@@ -1057,6 +1070,45 @@ export const createTenantSlice = createSlice({
|
||||
setIDP: (state, action: PayloadAction<string>) => {
|
||||
state.fields.identityProvider.idpSelection = action.payload;
|
||||
},
|
||||
setTenantName: (state, action: PayloadAction<string>) => {
|
||||
state.fields.nameTenant.tenantName = action.payload;
|
||||
delete state.validationErrors["tenant-name"];
|
||||
|
||||
const commonValidation = commonFormValidation([
|
||||
{
|
||||
fieldKey: "tenant-name",
|
||||
required: true,
|
||||
pattern: /^[a-z0-9-]{3,63}$/,
|
||||
customPatternMessage:
|
||||
"Name only can contain lowercase letters, numbers and '-'. Min. Length: 3",
|
||||
value: action.payload,
|
||||
},
|
||||
]);
|
||||
|
||||
let isValid = false;
|
||||
if ("tenant-name" in commonValidation) {
|
||||
isValid = true;
|
||||
state.validationErrors["tenant-name"] = commonValidation["tenant-name"];
|
||||
}
|
||||
|
||||
flipValidPageInState(state, "nameTenant", isValid);
|
||||
},
|
||||
},
|
||||
extraReducers: (builder) => {
|
||||
builder
|
||||
.addCase(createTenantAsync.pending, (state, action) => {
|
||||
state.addingTenant = true;
|
||||
state.createdAccount = null;
|
||||
state.showNewCredentials = false;
|
||||
})
|
||||
.addCase(createTenantAsync.rejected, (state, action) => {
|
||||
state.addingTenant = false;
|
||||
})
|
||||
.addCase(createTenantAsync.fulfilled, (state, action) => {
|
||||
state.addingTenant = false;
|
||||
state.createdAccount = action.payload;
|
||||
state.showNewCredentials = true;
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1097,6 +1149,7 @@ export const {
|
||||
addIDPADUsrAtIndex,
|
||||
removeIDPADUsrAtIndex,
|
||||
setIDP,
|
||||
setTenantName,
|
||||
} = createTenantSlice.actions;
|
||||
|
||||
export default createTenantSlice.reducer;
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2022 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 { ICreateTenant } from "./createTenantSlice";
|
||||
import { Draft } from "@reduxjs/toolkit";
|
||||
|
||||
export const flipValidPageInState = (
|
||||
state: Draft<ICreateTenant>,
|
||||
pageName: string,
|
||||
valid: boolean
|
||||
) => {
|
||||
let originValidPages = state.validPages;
|
||||
if (valid) {
|
||||
if (!originValidPages.includes(pageName)) {
|
||||
originValidPages.push(pageName);
|
||||
|
||||
state.validPages = [...originValidPages];
|
||||
}
|
||||
} else {
|
||||
const newSetOfPages = originValidPages.filter((elm) => elm !== pageName);
|
||||
state.validPages = [...newSetOfPages];
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,590 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2022 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 { createAsyncThunk } from "@reduxjs/toolkit";
|
||||
import { AppState } from "../../../../../store";
|
||||
import { generatePoolName, getBytes } from "../../../../../common/utils";
|
||||
import { getDefaultAffinity, getNodeSelector } from "../../TenantDetails/utils";
|
||||
import { ITenantCreator } from "../../../../../common/types";
|
||||
import { KeyPair } from "../../ListTenants/utils";
|
||||
import { createTenantCall } from "../createTenantAPI";
|
||||
import { setErrorSnackMessage } from "../../../../../systemSlice";
|
||||
|
||||
export const createTenantAsync = createAsyncThunk(
|
||||
"createTenant/createTenantAsync",
|
||||
async (_, { getState, rejectWithValue, dispatch }) => {
|
||||
const state = getState() as AppState;
|
||||
|
||||
let fields = state.createTenant.fields;
|
||||
let certificates = state.createTenant.certificates;
|
||||
|
||||
const tenantName = fields.nameTenant.tenantName;
|
||||
const selectedStorageClass = fields.nameTenant.selectedStorageClass;
|
||||
const imageName = fields.configure.imageName;
|
||||
const customDockerhub = fields.configure.customDockerhub;
|
||||
const imageRegistry = fields.configure.imageRegistry;
|
||||
const imageRegistryUsername = fields.configure.imageRegistryUsername;
|
||||
const imageRegistryPassword = fields.configure.imageRegistryPassword;
|
||||
const exposeMinIO = fields.configure.exposeMinIO;
|
||||
const exposeConsole = fields.configure.exposeConsole;
|
||||
const idpSelection = fields.identityProvider.idpSelection;
|
||||
const openIDConfigurationURL =
|
||||
fields.identityProvider.openIDConfigurationURL;
|
||||
const openIDClientID = fields.identityProvider.openIDClientID;
|
||||
const openIDClaimName = fields.identityProvider.openIDClaimName;
|
||||
const openIDCallbackURL = fields.identityProvider.openIDCallbackURL;
|
||||
const openIDScopes = fields.identityProvider.openIDScopes;
|
||||
const openIDSecretID = fields.identityProvider.openIDSecretID;
|
||||
const ADURL = fields.identityProvider.ADURL;
|
||||
const ADSkipTLS = fields.identityProvider.ADSkipTLS;
|
||||
const ADServerInsecure = fields.identityProvider.ADServerInsecure;
|
||||
const ADGroupSearchBaseDN = fields.identityProvider.ADGroupSearchBaseDN;
|
||||
const ADGroupSearchFilter = fields.identityProvider.ADGroupSearchFilter;
|
||||
const ADUserDNs = fields.identityProvider.ADUserDNs;
|
||||
const ADLookupBindDN = fields.identityProvider.ADLookupBindDN;
|
||||
const ADLookupBindPassword = fields.identityProvider.ADLookupBindPassword;
|
||||
const ADUserDNSearchBaseDN = fields.identityProvider.ADUserDNSearchBaseDN;
|
||||
const ADUserDNSearchFilter = fields.identityProvider.ADUserDNSearchFilter;
|
||||
const ADServerStartTLS = fields.identityProvider.ADServerStartTLS;
|
||||
const accessKeys = fields.identityProvider.accessKeys;
|
||||
const secretKeys = fields.identityProvider.secretKeys;
|
||||
const minioCertificates = certificates.minioCertificates;
|
||||
const caCertificates = certificates.caCertificates;
|
||||
const consoleCaCertificates = certificates.consoleCaCertificates;
|
||||
const consoleCertificate = certificates.consoleCertificate;
|
||||
const serverCertificate = certificates.serverCertificate;
|
||||
const clientCertificate = certificates.clientCertificate;
|
||||
const vaultCertificate = certificates.vaultCertificate;
|
||||
const vaultCA = certificates.vaultCA;
|
||||
const gemaltoCA = certificates.gemaltoCA;
|
||||
const enableEncryption = fields.encryption.enableEncryption;
|
||||
const encryptionType = fields.encryption.encryptionType;
|
||||
const gemaltoEndpoint = fields.encryption.gemaltoEndpoint;
|
||||
const gemaltoToken = fields.encryption.gemaltoToken;
|
||||
const gemaltoDomain = fields.encryption.gemaltoDomain;
|
||||
const gemaltoRetry = fields.encryption.gemaltoRetry;
|
||||
const awsEndpoint = fields.encryption.awsEndpoint;
|
||||
const awsRegion = fields.encryption.awsRegion;
|
||||
const awsKMSKey = fields.encryption.awsKMSKey;
|
||||
const awsAccessKey = fields.encryption.awsAccessKey;
|
||||
const awsSecretKey = fields.encryption.awsSecretKey;
|
||||
const awsToken = fields.encryption.awsToken;
|
||||
const vaultEndpoint = fields.encryption.vaultEndpoint;
|
||||
const vaultEngine = fields.encryption.vaultEngine;
|
||||
const vaultNamespace = fields.encryption.vaultNamespace;
|
||||
const vaultPrefix = fields.encryption.vaultPrefix;
|
||||
const vaultAppRoleEngine = fields.encryption.vaultAppRoleEngine;
|
||||
const vaultId = fields.encryption.vaultId;
|
||||
const vaultSecret = fields.encryption.vaultSecret;
|
||||
const vaultRetry = fields.encryption.vaultRetry;
|
||||
const vaultPing = fields.encryption.vaultPing;
|
||||
const azureEndpoint = fields.encryption.azureEndpoint;
|
||||
const azureTenantID = fields.encryption.azureTenantID;
|
||||
const azureClientID = fields.encryption.azureClientID;
|
||||
const azureClientSecret = fields.encryption.azureClientSecret;
|
||||
const gcpProjectID = fields.encryption.gcpProjectID;
|
||||
const gcpEndpoint = fields.encryption.gcpEndpoint;
|
||||
const gcpClientEmail = fields.encryption.gcpClientEmail;
|
||||
const gcpClientID = fields.encryption.gcpClientID;
|
||||
const gcpPrivateKeyID = fields.encryption.gcpPrivateKeyID;
|
||||
const gcpPrivateKey = fields.encryption.gcpPrivateKey;
|
||||
const enableAutoCert = fields.security.enableAutoCert;
|
||||
const enableTLS = fields.security.enableTLS;
|
||||
const ecParity = fields.tenantSize.ecParity;
|
||||
const distribution = fields.tenantSize.distribution;
|
||||
const tenantCustom = fields.configure.tenantCustom;
|
||||
const logSearchEnabled = fields.configure.logSearchEnabled;
|
||||
const prometheusEnabled = fields.configure.prometheusEnabled;
|
||||
const logSearchVolumeSize = fields.configure.logSearchVolumeSize;
|
||||
const logSearchSelectedStorageClass =
|
||||
fields.configure.logSearchSelectedStorageClass;
|
||||
const logSearchImage = fields.configure.logSearchImage;
|
||||
const kesImage = fields.configure.kesImage;
|
||||
const logSearchPostgresImage = fields.configure.logSearchPostgresImage;
|
||||
const logSearchPostgresInitImage =
|
||||
fields.configure.logSearchPostgresInitImage;
|
||||
const prometheusImage = fields.configure.prometheusImage;
|
||||
const prometheusSidecarImage = fields.configure.prometheusSidecarImage;
|
||||
const prometheusInitImage = fields.configure.prometheusInitImage;
|
||||
const prometheusSelectedStorageClass =
|
||||
fields.configure.prometheusSelectedStorageClass;
|
||||
const prometheusVolumeSize = fields.configure.prometheusVolumeSize;
|
||||
const affinityType = fields.affinity.podAffinity;
|
||||
const nodeSelectorLabels = fields.affinity.nodeSelectorLabels;
|
||||
const withPodAntiAffinity = fields.affinity.withPodAntiAffinity;
|
||||
|
||||
const tenantSecurityContext = fields.configure.tenantSecurityContext;
|
||||
const logSearchSecurityContext = fields.configure.logSearchSecurityContext;
|
||||
const logSearchPostgresSecurityContext =
|
||||
fields.configure.logSearchPostgresSecurityContext;
|
||||
const prometheusSecurityContext =
|
||||
fields.configure.prometheusSecurityContext;
|
||||
const kesSecurityContext = fields.encryption.kesSecurityContext;
|
||||
const kesReplicas = fields.encryption.replicas;
|
||||
const setDomains = fields.configure.setDomains;
|
||||
const minioDomains = fields.configure.minioDomains;
|
||||
const consoleDomain = fields.configure.consoleDomain;
|
||||
|
||||
let tolerations = state.createTenant.tolerations;
|
||||
let namespace = state.createTenant.fields.nameTenant.namespace;
|
||||
|
||||
const tolerationValues = tolerations.filter(
|
||||
(toleration) => toleration.key.trim() !== ""
|
||||
);
|
||||
|
||||
const poolName = generatePoolName([]);
|
||||
|
||||
let affinityObject = {};
|
||||
|
||||
switch (affinityType) {
|
||||
case "default":
|
||||
affinityObject = {
|
||||
affinity: getDefaultAffinity(tenantName, poolName),
|
||||
};
|
||||
break;
|
||||
case "nodeSelector":
|
||||
affinityObject = {
|
||||
affinity: getNodeSelector(
|
||||
nodeSelectorLabels,
|
||||
withPodAntiAffinity,
|
||||
tenantName,
|
||||
poolName
|
||||
),
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
const erasureCode = ecParity.split(":")[1];
|
||||
|
||||
let dataSend: ITenantCreator = {
|
||||
name: tenantName,
|
||||
namespace: namespace,
|
||||
access_key: "",
|
||||
secret_key: "",
|
||||
access_keys: [],
|
||||
secret_keys: [],
|
||||
enable_tls: enableTLS && enableAutoCert,
|
||||
enable_console: true,
|
||||
enable_prometheus: true,
|
||||
service_name: "",
|
||||
image: imageName,
|
||||
expose_minio: exposeMinIO,
|
||||
expose_console: exposeConsole,
|
||||
pools: [
|
||||
{
|
||||
name: poolName,
|
||||
servers: distribution.nodes,
|
||||
volumes_per_server: distribution.disks,
|
||||
volume_configuration: {
|
||||
size: distribution.pvSize,
|
||||
storage_class_name: selectedStorageClass,
|
||||
},
|
||||
securityContext: tenantCustom ? tenantSecurityContext : null,
|
||||
...affinityObject,
|
||||
tolerations: tolerationValues,
|
||||
},
|
||||
],
|
||||
erasureCodingParity: parseInt(erasureCode, 10),
|
||||
};
|
||||
|
||||
// Set Resources
|
||||
if (
|
||||
fields.tenantSize.resourcesCPURequest !== "" ||
|
||||
fields.tenantSize.resourcesCPULimit !== "" ||
|
||||
fields.tenantSize.resourcesMemoryRequest !== "" ||
|
||||
fields.tenantSize.resourcesMemoryLimit !== ""
|
||||
) {
|
||||
dataSend.pools[0].resources = {};
|
||||
// requests
|
||||
if (
|
||||
fields.tenantSize.resourcesCPURequest !== "" ||
|
||||
fields.tenantSize.resourcesMemoryRequest !== ""
|
||||
) {
|
||||
dataSend.pools[0].resources.requests = {};
|
||||
if (fields.tenantSize.resourcesCPURequest !== "") {
|
||||
dataSend.pools[0].resources.requests.cpu = parseInt(
|
||||
fields.tenantSize.resourcesCPURequest
|
||||
);
|
||||
}
|
||||
if (fields.tenantSize.resourcesMemoryRequest !== "") {
|
||||
dataSend.pools[0].resources.requests.memory = parseInt(
|
||||
getBytes(fields.tenantSize.resourcesMemoryRequest, "Gi", true)
|
||||
);
|
||||
}
|
||||
}
|
||||
// limits
|
||||
if (
|
||||
fields.tenantSize.resourcesCPULimit !== "" ||
|
||||
fields.tenantSize.resourcesMemoryLimit !== ""
|
||||
) {
|
||||
dataSend.pools[0].resources.limits = {};
|
||||
if (fields.tenantSize.resourcesCPULimit !== "") {
|
||||
dataSend.pools[0].resources.limits.cpu = parseInt(
|
||||
fields.tenantSize.resourcesCPULimit
|
||||
);
|
||||
}
|
||||
if (fields.tenantSize.resourcesMemoryLimit !== "") {
|
||||
dataSend.pools[0].resources.limits.memory = parseInt(
|
||||
getBytes(fields.tenantSize.resourcesMemoryLimit, "Gi", true)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (customDockerhub) {
|
||||
dataSend = {
|
||||
...dataSend,
|
||||
image_registry: {
|
||||
registry: imageRegistry,
|
||||
username: imageRegistryUsername,
|
||||
password: imageRegistryPassword,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
if (logSearchEnabled) {
|
||||
dataSend = {
|
||||
...dataSend,
|
||||
logSearchConfiguration: {
|
||||
storageClass:
|
||||
logSearchSelectedStorageClass === "default"
|
||||
? ""
|
||||
: logSearchSelectedStorageClass,
|
||||
storageSize: parseInt(logSearchVolumeSize),
|
||||
image: logSearchImage,
|
||||
postgres_image: logSearchPostgresImage,
|
||||
postgres_init_image: logSearchPostgresInitImage,
|
||||
securityContext: logSearchSecurityContext,
|
||||
postgres_securityContext: logSearchPostgresSecurityContext,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
if (prometheusEnabled) {
|
||||
dataSend = {
|
||||
...dataSend,
|
||||
prometheusConfiguration: {
|
||||
storageClass:
|
||||
prometheusSelectedStorageClass === "default"
|
||||
? ""
|
||||
: prometheusSelectedStorageClass,
|
||||
storageSize: parseInt(prometheusVolumeSize),
|
||||
image: prometheusImage,
|
||||
sidecar_image: prometheusSidecarImage,
|
||||
init_image: prometheusInitImage,
|
||||
securityContext: prometheusSecurityContext,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
let tenantCerts: any = null;
|
||||
let consoleCerts: any = null;
|
||||
let caCerts: any = null;
|
||||
let consoleCaCerts: any = null;
|
||||
|
||||
if (caCertificates.length > 0) {
|
||||
caCerts = {
|
||||
ca_certificates: caCertificates
|
||||
.map((keyPair: KeyPair) => keyPair.encoded_cert)
|
||||
.filter((keyPair) => keyPair),
|
||||
};
|
||||
}
|
||||
|
||||
if (consoleCaCertificates.length > 0) {
|
||||
consoleCaCerts = {
|
||||
console_ca_certificates: consoleCaCertificates
|
||||
.map((keyPair: KeyPair) => keyPair.encoded_cert)
|
||||
.filter((keyPair) => keyPair),
|
||||
};
|
||||
}
|
||||
|
||||
if (enableTLS && minioCertificates.length > 0) {
|
||||
tenantCerts = {
|
||||
minio: minioCertificates
|
||||
.map((keyPair: KeyPair) => ({
|
||||
crt: keyPair.encoded_cert,
|
||||
key: keyPair.encoded_key,
|
||||
}))
|
||||
.filter((keyPair) => keyPair.crt && keyPair.key),
|
||||
};
|
||||
}
|
||||
|
||||
if (
|
||||
enableTLS &&
|
||||
consoleCertificate.encoded_cert !== "" &&
|
||||
consoleCertificate.encoded_key !== ""
|
||||
) {
|
||||
consoleCerts = {
|
||||
console: {
|
||||
crt: consoleCertificate.encoded_cert,
|
||||
key: consoleCertificate.encoded_key,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
if (tenantCerts || consoleCerts || caCerts || consoleCaCerts) {
|
||||
dataSend = {
|
||||
...dataSend,
|
||||
tls: {
|
||||
...tenantCerts,
|
||||
...consoleCerts,
|
||||
...caCerts,
|
||||
...consoleCaCerts,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
if (enableEncryption) {
|
||||
let insertEncrypt = {};
|
||||
|
||||
switch (encryptionType) {
|
||||
case "gemalto":
|
||||
let gemaltoCAIntroduce = {};
|
||||
|
||||
if (gemaltoCA.encoded_cert !== "") {
|
||||
gemaltoCAIntroduce = {
|
||||
ca: gemaltoCA.encoded_cert,
|
||||
};
|
||||
}
|
||||
insertEncrypt = {
|
||||
gemalto: {
|
||||
keysecure: {
|
||||
endpoint: gemaltoEndpoint,
|
||||
credentials: {
|
||||
token: gemaltoToken,
|
||||
domain: gemaltoDomain,
|
||||
retry: parseInt(gemaltoRetry),
|
||||
},
|
||||
tls: {
|
||||
...gemaltoCAIntroduce,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
break;
|
||||
case "aws":
|
||||
insertEncrypt = {
|
||||
aws: {
|
||||
secretsmanager: {
|
||||
endpoint: awsEndpoint,
|
||||
region: awsRegion,
|
||||
kmskey: awsKMSKey,
|
||||
credentials: {
|
||||
accesskey: awsAccessKey,
|
||||
secretkey: awsSecretKey,
|
||||
token: awsToken,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
break;
|
||||
case "azure":
|
||||
insertEncrypt = {
|
||||
azure: {
|
||||
keyvault: {
|
||||
endpoint: azureEndpoint,
|
||||
credentials: {
|
||||
tenant_id: azureTenantID,
|
||||
client_id: azureClientID,
|
||||
client_secret: azureClientSecret,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
break;
|
||||
case "gcp":
|
||||
insertEncrypt = {
|
||||
gcp: {
|
||||
secretmanager: {
|
||||
project_id: gcpProjectID,
|
||||
endpoint: gcpEndpoint,
|
||||
credentials: {
|
||||
client_email: gcpClientEmail,
|
||||
client_id: gcpClientID,
|
||||
private_key_id: gcpPrivateKeyID,
|
||||
private_key: gcpPrivateKey,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
break;
|
||||
case "vault":
|
||||
let vaultKeyPair = null;
|
||||
let vaultCAInsert = null;
|
||||
if (
|
||||
vaultCertificate.encoded_key !== "" &&
|
||||
vaultCertificate.encoded_cert !== ""
|
||||
) {
|
||||
vaultKeyPair = {
|
||||
key: vaultCertificate.encoded_key,
|
||||
crt: vaultCertificate.encoded_cert,
|
||||
};
|
||||
}
|
||||
if (vaultCA.encoded_cert !== "") {
|
||||
vaultCAInsert = {
|
||||
ca: vaultCA.encoded_cert,
|
||||
};
|
||||
}
|
||||
let vaultTLS = null;
|
||||
if (vaultKeyPair || vaultCAInsert) {
|
||||
vaultTLS = {
|
||||
tls: {
|
||||
...vaultKeyPair,
|
||||
...vaultCAInsert,
|
||||
},
|
||||
};
|
||||
}
|
||||
insertEncrypt = {
|
||||
vault: {
|
||||
endpoint: vaultEndpoint,
|
||||
engine: vaultEngine,
|
||||
namespace: vaultNamespace,
|
||||
prefix: vaultPrefix,
|
||||
approle: {
|
||||
engine: vaultAppRoleEngine,
|
||||
id: vaultId,
|
||||
secret: vaultSecret,
|
||||
retry: parseInt(vaultRetry),
|
||||
},
|
||||
...vaultTLS,
|
||||
status: {
|
||||
ping: parseInt(vaultPing),
|
||||
},
|
||||
},
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
let encryptionServerKeyPair: any = {};
|
||||
let encryptionClientKeyPair: any = {};
|
||||
|
||||
if (
|
||||
clientCertificate.encoded_key !== "" &&
|
||||
clientCertificate.encoded_cert !== ""
|
||||
) {
|
||||
encryptionClientKeyPair = {
|
||||
client: {
|
||||
key: clientCertificate.encoded_key,
|
||||
crt: clientCertificate.encoded_cert,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
if (
|
||||
serverCertificate.encoded_key !== "" &&
|
||||
serverCertificate.encoded_cert !== ""
|
||||
) {
|
||||
encryptionServerKeyPair = {
|
||||
server: {
|
||||
key: serverCertificate.encoded_key,
|
||||
crt: serverCertificate.encoded_cert,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
dataSend = {
|
||||
...dataSend,
|
||||
encryption: {
|
||||
replicas: kesReplicas,
|
||||
securityContext: kesSecurityContext,
|
||||
image: kesImage,
|
||||
...encryptionClientKeyPair,
|
||||
...encryptionServerKeyPair,
|
||||
...insertEncrypt,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
let dataIDP: any = {};
|
||||
switch (idpSelection) {
|
||||
case "Built-in":
|
||||
let keyarray = [];
|
||||
for (let i = 0; i < accessKeys.length; i++) {
|
||||
keyarray.push({
|
||||
access_key: accessKeys[i],
|
||||
secret_key: secretKeys[i],
|
||||
});
|
||||
}
|
||||
dataIDP = {
|
||||
keys: keyarray,
|
||||
};
|
||||
break;
|
||||
case "OpenID":
|
||||
dataIDP = {
|
||||
oidc: {
|
||||
configuration_url: openIDConfigurationURL,
|
||||
client_id: openIDClientID,
|
||||
secret_id: openIDSecretID,
|
||||
claim_name: openIDClaimName,
|
||||
callback_url: openIDCallbackURL,
|
||||
scopes: openIDScopes,
|
||||
},
|
||||
};
|
||||
break;
|
||||
case "AD":
|
||||
dataIDP = {
|
||||
active_directory: {
|
||||
url: ADURL,
|
||||
skip_tls_verification: ADSkipTLS,
|
||||
server_insecure: ADServerInsecure,
|
||||
group_search_base_dn: ADGroupSearchBaseDN,
|
||||
group_search_filter: ADGroupSearchFilter,
|
||||
user_dns: ADUserDNs,
|
||||
lookup_bind_dn: ADLookupBindDN,
|
||||
lookup_bind_password: ADLookupBindPassword,
|
||||
user_dn_search_base_dn: ADUserDNSearchBaseDN,
|
||||
user_dn_search_filter: ADUserDNSearchFilter,
|
||||
server_start_tls: ADServerStartTLS,
|
||||
},
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
let domains: any = {};
|
||||
let sendDomain: any = {};
|
||||
|
||||
if (setDomains) {
|
||||
if (consoleDomain !== "") {
|
||||
domains.console = consoleDomain;
|
||||
}
|
||||
|
||||
const filteredDomains = minioDomains.filter((dom) => dom.trim() !== "");
|
||||
|
||||
if (filteredDomains.length > 0) {
|
||||
domains.minio = filteredDomains;
|
||||
}
|
||||
|
||||
if (Object.keys(domains).length > 0) {
|
||||
sendDomain.domains = domains;
|
||||
}
|
||||
}
|
||||
|
||||
dataSend = {
|
||||
...dataSend,
|
||||
...sendDomain,
|
||||
idp: { ...dataIDP },
|
||||
};
|
||||
|
||||
const response = createTenantCall(dataSend)
|
||||
.then((resp) => {
|
||||
return resp;
|
||||
})
|
||||
.catch((err) => {
|
||||
dispatch(setErrorSnackMessage(err));
|
||||
return rejectWithValue(err);
|
||||
});
|
||||
return response;
|
||||
}
|
||||
);
|
||||
@@ -384,5 +384,3 @@ export interface ITenantIdentityProviderResponse {
|
||||
user_dn_search_filter: string;
|
||||
};
|
||||
}
|
||||
|
||||
export type FieldsToHandle = INameTenantFields;
|
||||
|
||||
@@ -27,7 +27,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
ErrDefault = errors.New("an errors occurred, please try again")
|
||||
ErrDefault = errors.New("an error occurred, please try again")
|
||||
ErrInvalidLogin = errors.New("invalid Login")
|
||||
ErrForbidden = errors.New("403 Forbidden")
|
||||
ErrFileTooLarge = errors.New("413 File too Large")
|
||||
|
||||
Reference in New Issue
Block a user