diff --git a/iconos/Lambda.svg b/iconos/Lambda.svg new file mode 100644 index 000000000..eb7c631e0 --- /dev/null +++ b/iconos/Lambda.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/iconos/Tiers.svg b/iconos/Tiers.svg new file mode 100644 index 000000000..d7d85d772 --- /dev/null +++ b/iconos/Tiers.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/pkg/acl/endpoints.go b/pkg/acl/endpoints.go index 28eb46cd1..fe7c59568 100644 --- a/pkg/acl/endpoints.go +++ b/pkg/acl/endpoints.go @@ -22,49 +22,52 @@ import ( // endpoints definition var ( - configuration = "/settings" - users = "/users" - usersDetail = "/users/:userName+" - groups = "/groups" - iamPolicies = "/policies" - policiesDetail = "/policies/*" - dashboard = "/dashboard" - metrics = "/metrics" - profiling = "/profiling" - buckets = "/buckets" - bucketsGeneral = "/buckets/*" - bucketsAdmin = "/buckets/:bucketName/admin/*" - bucketsAdminMain = "/buckets/:bucketName/admin" - bucketsBrowserMenu = "/buckets" - bucketsBrowserList = "/buckets/*" - bucketsBrowser = "/buckets/:bucketName/browse/*" - bucketsBrowserMain = "/buckets/:bucketName/browse" - serviceAccounts = "/account" - changePassword = "/account/change-password" - tenants = "/tenants" - tenantsAdd = "/tenants/add" - tenantsAddSub = "/tenants/add/*" - tenantsDetail = "/namespaces/:tenantNamespace/tenants/:tenantName" - tenantHop = "/namespaces/:tenantNamespace/tenants/:tenantName/hop" - podsDetail = "/namespaces/:tenantNamespace/tenants/:tenantName/pods/:podName" - tenantsDetailSummary = "/namespaces/:tenantNamespace/tenants/:tenantName/summary" - tenantsDetailMetrics = "/namespaces/:tenantNamespace/tenants/:tenantName/metrics" - tenantsDetailPods = "/namespaces/:tenantNamespace/tenants/:tenantName/pods" - tenantsDetailPools = "/namespaces/:tenantNamespace/tenants/:tenantName/pools" - tenantsDetailVolumes = "/namespaces/:tenantNamespace/tenants/:tenantName/volumes" - tenantsDetailLicense = "/namespaces/:tenantNamespace/tenants/:tenantName/license" - tenantsDetailSecurity = "/namespaces/:tenantNamespace/tenants/:tenantName/security" - storage = "/storage" - storageVolumes = "/storage/volumes" - storageDrives = "/storage/drives" - remoteBuckets = "/remote-buckets" - replication = "/replication" - license = "/license" - watch = "/watch" - heal = "/heal" - trace = "/trace" - logs = "/logs" - healthInfo = "/health-info" + configuration = "/settings" + notificationEndpoints = "/notification-endpoints" + notificationEndpointsAddAny = "/notification-endpoints/add/:service" + notificationEndpointsAdd = "/notification-endpoints/add" + users = "/users" + usersDetail = "/users/:userName+" + groups = "/groups" + iamPolicies = "/policies" + policiesDetail = "/policies/*" + dashboard = "/dashboard" + metrics = "/metrics" + profiling = "/profiling" + buckets = "/buckets" + bucketsGeneral = "/buckets/*" + bucketsAdmin = "/buckets/:bucketName/admin/*" + bucketsAdminMain = "/buckets/:bucketName/admin" + bucketsBrowserMenu = "/buckets" + bucketsBrowserList = "/buckets/*" + bucketsBrowser = "/buckets/:bucketName/browse/*" + bucketsBrowserMain = "/buckets/:bucketName/browse" + serviceAccounts = "/account" + changePassword = "/account/change-password" + tenants = "/tenants" + tenantsAdd = "/tenants/add" + tenantsAddSub = "/tenants/add/*" + tenantsDetail = "/namespaces/:tenantNamespace/tenants/:tenantName" + tenantHop = "/namespaces/:tenantNamespace/tenants/:tenantName/hop" + podsDetail = "/namespaces/:tenantNamespace/tenants/:tenantName/pods/:podName" + tenantsDetailSummary = "/namespaces/:tenantNamespace/tenants/:tenantName/summary" + tenantsDetailMetrics = "/namespaces/:tenantNamespace/tenants/:tenantName/metrics" + tenantsDetailPods = "/namespaces/:tenantNamespace/tenants/:tenantName/pods" + tenantsDetailPools = "/namespaces/:tenantNamespace/tenants/:tenantName/pools" + tenantsDetailVolumes = "/namespaces/:tenantNamespace/tenants/:tenantName/volumes" + tenantsDetailLicense = "/namespaces/:tenantNamespace/tenants/:tenantName/license" + tenantsDetailSecurity = "/namespaces/:tenantNamespace/tenants/:tenantName/security" + storage = "/storage" + storageVolumes = "/storage/volumes" + storageDrives = "/storage/drives" + remoteBuckets = "/remote-buckets" + replication = "/replication" + license = "/license" + watch = "/watch" + heal = "/heal" + trace = "/trace" + logs = "/logs" + healthInfo = "/health-info" ) type ConfigurationActionSet struct { @@ -287,33 +290,36 @@ var displayRules = map[string]func() bool{ // endpointRules contains the mapping between endpoints and ActionSets, additional rules can be added here var endpointRules = map[string]ConfigurationActionSet{ - configuration: configurationActionSet, - users: usersActionSet, - usersDetail: usersActionSet, - groups: groupsActionSet, - iamPolicies: iamPoliciesActionSet, - policiesDetail: iamPoliciesActionSet, - dashboard: dashboardActionSet, - metrics: dashboardActionSet, - profiling: profilingActionSet, - buckets: bucketsActionSet, - bucketsGeneral: bucketsActionSet, - bucketsAdmin: bucketsActionSet, - bucketsAdminMain: bucketsActionSet, - serviceAccounts: serviceAccountsActionSet, - changePassword: changePasswordActionSet, - remoteBuckets: remoteBucketsActionSet, - replication: replicationActionSet, - bucketsBrowser: objectBrowserActionSet, - bucketsBrowserMenu: objectBrowserActionSet, - bucketsBrowserList: objectBrowserActionSet, - bucketsBrowserMain: objectBrowserActionSet, - license: licenseActionSet, - watch: watchActionSet, - heal: healActionSet, - trace: traceActionSet, - logs: logsActionSet, - healthInfo: healthInfoActionSet, + configuration: configurationActionSet, + notificationEndpoints: configurationActionSet, + notificationEndpointsAdd: configurationActionSet, + notificationEndpointsAddAny: configurationActionSet, + users: usersActionSet, + usersDetail: usersActionSet, + groups: groupsActionSet, + iamPolicies: iamPoliciesActionSet, + policiesDetail: iamPoliciesActionSet, + dashboard: dashboardActionSet, + metrics: dashboardActionSet, + profiling: profilingActionSet, + buckets: bucketsActionSet, + bucketsGeneral: bucketsActionSet, + bucketsAdmin: bucketsActionSet, + bucketsAdminMain: bucketsActionSet, + serviceAccounts: serviceAccountsActionSet, + changePassword: changePasswordActionSet, + remoteBuckets: remoteBucketsActionSet, + replication: replicationActionSet, + bucketsBrowser: objectBrowserActionSet, + bucketsBrowserMenu: objectBrowserActionSet, + bucketsBrowserList: objectBrowserActionSet, + bucketsBrowserMain: objectBrowserActionSet, + license: licenseActionSet, + watch: watchActionSet, + heal: healActionSet, + trace: traceActionSet, + logs: logsActionSet, + healthInfo: healthInfoActionSet, } // operatorRules contains the mapping between endpoints and ActionSets for operator only mode diff --git a/pkg/acl/endpoints_test.go b/pkg/acl/endpoints_test.go index fe55a21dc..9a3f3cfb0 100644 --- a/pkg/acl/endpoints_test.go +++ b/pkg/acl/endpoints_test.go @@ -70,7 +70,7 @@ func TestGetAuthorizedEndpoints(t *testing.T) { "admin:*", }, }, - want: 23, + want: 26, }, { name: "all s3 endpoints", @@ -89,7 +89,7 @@ func TestGetAuthorizedEndpoints(t *testing.T) { "s3:*", }, }, - want: 25, + want: 28, }, { name: "Console User - default endpoints", diff --git a/portal-ui/public/amqp-logo.svg b/portal-ui/public/amqp-logo.svg new file mode 100644 index 000000000..5b2cfec44 --- /dev/null +++ b/portal-ui/public/amqp-logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/portal-ui/public/elasticsearch-logo.svg b/portal-ui/public/elasticsearch-logo.svg new file mode 100644 index 000000000..6d8395112 --- /dev/null +++ b/portal-ui/public/elasticsearch-logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/portal-ui/public/kafka-logo.svg b/portal-ui/public/kafka-logo.svg new file mode 100644 index 000000000..43cfd5534 --- /dev/null +++ b/portal-ui/public/kafka-logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/portal-ui/public/lambda-rect.svg b/portal-ui/public/lambda-rect.svg new file mode 100644 index 000000000..3df041b69 --- /dev/null +++ b/portal-ui/public/lambda-rect.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/portal-ui/public/mqtt-logo.svg b/portal-ui/public/mqtt-logo.svg new file mode 100644 index 000000000..6e42e7a11 --- /dev/null +++ b/portal-ui/public/mqtt-logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/portal-ui/public/mysql-logo.svg b/portal-ui/public/mysql-logo.svg new file mode 100644 index 000000000..c87a4e325 --- /dev/null +++ b/portal-ui/public/mysql-logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/portal-ui/public/nats-logo.svg b/portal-ui/public/nats-logo.svg new file mode 100644 index 000000000..d5ec5b5a9 --- /dev/null +++ b/portal-ui/public/nats-logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/portal-ui/public/nsq-logo.svg b/portal-ui/public/nsq-logo.svg new file mode 100644 index 000000000..e5fe58ac6 --- /dev/null +++ b/portal-ui/public/nsq-logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/portal-ui/public/postgres-logo.svg b/portal-ui/public/postgres-logo.svg new file mode 100644 index 000000000..fdca8d8b4 --- /dev/null +++ b/portal-ui/public/postgres-logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/portal-ui/public/redis-logo.svg b/portal-ui/public/redis-logo.svg new file mode 100644 index 000000000..d2eb2304d --- /dev/null +++ b/portal-ui/public/redis-logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/portal-ui/public/webhooks-logo.svg b/portal-ui/public/webhooks-logo.svg new file mode 100644 index 000000000..16c536bf2 --- /dev/null +++ b/portal-ui/public/webhooks-logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/portal-ui/src/icons/LambdaIcon.tsx b/portal-ui/src/icons/LambdaIcon.tsx new file mode 100644 index 000000000..5c2d70f7c --- /dev/null +++ b/portal-ui/src/icons/LambdaIcon.tsx @@ -0,0 +1,33 @@ +// This file is part of MinIO Console Server +// Copyright (c) 2021 MinIO, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +import * as React from "react"; +import { SvgIcon, SvgIconProps } from "@material-ui/core"; + +const LambdaIcon = (props: SvgIconProps) => { + return ( + + + + + + ); +}; + +export default LambdaIcon; diff --git a/portal-ui/src/icons/TiersIcon.tsx b/portal-ui/src/icons/TiersIcon.tsx new file mode 100644 index 000000000..12bfe56f8 --- /dev/null +++ b/portal-ui/src/icons/TiersIcon.tsx @@ -0,0 +1,33 @@ +// This file is part of MinIO Console Server +// Copyright (c) 2021 MinIO, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +import * as React from "react"; +import { SvgIcon, SvgIconProps } from "@material-ui/core"; + +const TiersIcon = (props: SvgIconProps) => { + return ( + + + + + + ); +}; + +export default TiersIcon; diff --git a/portal-ui/src/icons/index.ts b/portal-ui/src/icons/index.ts index f33a0d2a0..24fccabd4 100644 --- a/portal-ui/src/icons/index.ts +++ b/portal-ui/src/icons/index.ts @@ -99,3 +99,5 @@ export { default as FileVideoIcon } from "./FileVideoIcon"; export { default as ArrowRightIcon } from "./ArrowRightIcon"; export { default as CalendarIcon } from "./CalendarIcon"; export { default as UptimeIcon } from "./UptimeIcon"; +export { default as LambdaIcon } from "./LambdaIcon"; +export { default as TiersIcon } from "./TiersIcon"; diff --git a/portal-ui/src/screens/Console/Common/FormComponents/common/styleLibrary.ts b/portal-ui/src/screens/Console/Common/FormComponents/common/styleLibrary.ts index 0d5455a51..d3d2557a4 100644 --- a/portal-ui/src/screens/Console/Common/FormComponents/common/styleLibrary.ts +++ b/portal-ui/src/screens/Console/Common/FormComponents/common/styleLibrary.ts @@ -359,8 +359,8 @@ export const typesSelection = { iconContainer: { display: "flex" as const, flexDirection: "row" as const, - maxWidth: 455, - justifyContent: "space-between" as const, + maxWidth: 1180, + justifyContent: "start" as const, flexWrap: "wrap" as const, width: "100%", }, @@ -388,21 +388,40 @@ export const typesSelection = { height: "80px", }, lambdaNotif: { - backgroundColor: "#fff", - border: "#393939 1px solid", + background: + "linear-gradient(90deg, rgba(249,249,250,1) 0%, rgba(250,250,251,1) 68%, rgba(254,254,254,1) 100%)", + border: "#E5E5E5 1px solid", borderRadius: 5, - width: 101, - height: 91, + width: 250, + height: 80, + display: "flex", + alignItems: "center", + justifyContent: "start", + marginBottom: 16, + marginRight: 8, + cursor: "pointer", + padding: 0, + overflow: "hidden", + }, + lambdaNotifIcon: { + backgroundColor: "#FEFEFE", display: "flex", alignItems: "center", justifyContent: "center", - marginBottom: 16, - cursor: "pointer", + width: 80, + height: 80, + "& img": { - maxWidth: 71, - maxHeight: 71, + maxWidth: 46, + maxHeight: 46, }, }, + lambdaNotifTitle: { + color: "#07193E", + fontSize: 16, + fontFamily: "Lato,sans-serif", + paddingLeft: 18, + }, }; export const logsCommon = { diff --git a/portal-ui/src/screens/Console/Common/MainError/MainError.tsx b/portal-ui/src/screens/Console/Common/MainError/MainError.tsx index afdce6da3..88815f3af 100644 --- a/portal-ui/src/screens/Console/Common/MainError/MainError.tsx +++ b/portal-ui/src/screens/Console/Common/MainError/MainError.tsx @@ -35,7 +35,7 @@ interface IMainErrorProps { const styles = (theme: Theme) => createStyles({ mainErrorContainer: { - position: "absolute", + position: "fixed", width: "100%", backgroundColor: "#fff", border: "#C72C48 1px solid", diff --git a/portal-ui/src/screens/Console/Configurations/ConfigurationMain.tsx b/portal-ui/src/screens/Console/Configurations/ConfigurationMain.tsx index 245797215..5f3a52378 100644 --- a/portal-ui/src/screens/Console/Configurations/ConfigurationMain.tsx +++ b/portal-ui/src/screens/Console/Configurations/ConfigurationMain.tsx @@ -20,7 +20,6 @@ import { Grid } from "@material-ui/core"; import { createStyles, Theme, withStyles } from "@material-ui/core/styles"; import { containerForHeader } from "../Common/FormComponents/common/styleLibrary"; import ConfigurationsList from "./ConfigurationPanels/ConfigurationsList"; -import ListNotificationEndpoints from "./NotificationEndpoints/ListNotificationEndpoints"; import ListTiersConfiguration from "./TiersConfiguration/ListTiersConfiguration"; import { AppState } from "../../../store"; import { connect } from "react-redux"; @@ -68,15 +67,6 @@ const ConfigurationMain = ({ > - { - setSelectedTab(1); - }} - > - - )} - {selectedTab === 1 && ( - -

Lambda Notifications

- -
- )} {selectedTab === 2 && distributedSetup && (

Tiers

diff --git a/portal-ui/src/screens/Console/Configurations/ConfigurationPanels/ConfigurationsList.tsx b/portal-ui/src/screens/Console/Configurations/ConfigurationPanels/ConfigurationsList.tsx index e86f98b41..d5bb7630d 100644 --- a/portal-ui/src/screens/Console/Configurations/ConfigurationPanels/ConfigurationsList.tsx +++ b/portal-ui/src/screens/Console/Configurations/ConfigurationPanels/ConfigurationsList.tsx @@ -22,7 +22,7 @@ import history from "../../../../history"; import TableWrapper from "../../Common/TableWrapper/TableWrapper"; import { configurationElements } from "../utils"; import { IConfigurationElement } from "../types"; -import EditConfiguration from "../CustomForms/EditConfiguration"; +import EditConfiguration from "../../NotificationEndpoints/CustomForms/EditConfiguration"; import { actionsTray, containerForHeader, diff --git a/portal-ui/src/screens/Console/Configurations/ConfigurationPanels/WebhookPanel.tsx b/portal-ui/src/screens/Console/Configurations/ConfigurationPanels/WebhookPanel.tsx index 08d8dd478..770f45f40 100644 --- a/portal-ui/src/screens/Console/Configurations/ConfigurationPanels/WebhookPanel.tsx +++ b/portal-ui/src/screens/Console/Configurations/ConfigurationPanels/WebhookPanel.tsx @@ -23,7 +23,7 @@ import { createStyles, Theme, withStyles } from "@material-ui/core/styles"; import InputAdornment from "@material-ui/core/InputAdornment"; import AddIcon from "@material-ui/icons/Add"; import TableWrapper from "../../Common/TableWrapper/TableWrapper"; -import EditConfiguration from "../CustomForms/EditConfiguration"; +import EditConfiguration from "../../NotificationEndpoints/CustomForms/EditConfiguration"; import SearchIcon from "../../../../icons/SearchIcon"; interface IMatchParams { diff --git a/portal-ui/src/screens/Console/Configurations/NotificationEndpoints/NotificationTypeSelector.tsx b/portal-ui/src/screens/Console/Configurations/NotificationEndpoints/NotificationTypeSelector.tsx deleted file mode 100644 index 6995940a5..000000000 --- a/portal-ui/src/screens/Console/Configurations/NotificationEndpoints/NotificationTypeSelector.tsx +++ /dev/null @@ -1,99 +0,0 @@ -// This file is part of MinIO Console Server -// Copyright (c) 2021 MinIO, Inc. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -import React, { Fragment } from "react"; -import Grid from "@material-ui/core/Grid"; -import { Button } from "@material-ui/core"; -import { createStyles, Theme, withStyles } from "@material-ui/core/styles"; -import { servicesList } from "./utils"; -import { - settingsCommon, - typesSelection, -} from "../../Common/FormComponents/common/styleLibrary"; - -interface INotificationTypeSelector { - classes: any; - setService: (trigger: string) => any; -} - -const nonLogos = servicesList.filter((elService) => elService.logo === ""); -const withLogos = servicesList.filter((elService) => elService.logo !== ""); - -const styles = (theme: Theme) => - createStyles({ - ...settingsCommon, - customTitle: { - ...settingsCommon.customTitle, - marginTop: 0, - }, - ...typesSelection, - }); - -const NotificationTypeSelector = ({ - classes, - setService, -}: INotificationTypeSelector) => { - return ( - - - - - Pick a supported service - - -
- {nonLogos.map((item) => { - return ( - - ); - })} -
-
- {withLogos.map((item) => { - return ( - - ); - })} -
-
-
-
-
- ); -}; - -export default withStyles(styles)(NotificationTypeSelector); diff --git a/portal-ui/src/screens/Console/Configurations/NotificationEndpoints/utils.ts b/portal-ui/src/screens/Console/Configurations/NotificationEndpoints/utils.ts deleted file mode 100644 index 15630f84c..000000000 --- a/portal-ui/src/screens/Console/Configurations/NotificationEndpoints/utils.ts +++ /dev/null @@ -1,93 +0,0 @@ -// This file is part of MinIO Console Server -// Copyright (c) 2021 MinIO, Inc. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -import { NotificationEndpointItem } from "./types"; -import { - notifyAmqp, - notifyElasticsearch, - notifyKafka, - notifyMqtt, - notifyMysql, - notifyNats, - notifyNsq, - notifyPostgres, - notifyRedis, - notifyWebhooks, -} from "../utils"; - -export const notificationTransform = ( - notificationElements: NotificationEndpointItem[] -) => { - return notificationElements.map((element) => { - return { - service_name: `${element.service}:${element.account_id}`, - status: element.status, - }; - }); -}; - -export const servicesList = [ - { - actionTrigger: notifyPostgres, - targetTitle: "Postgres SQL", - logo: "/postgres.png", - }, - { - actionTrigger: notifyKafka, - targetTitle: "Kafka", - logo: "/kafka.png", - }, - { - actionTrigger: notifyAmqp, - targetTitle: "AMQP", - logo: "/amqp.png", - }, - { - actionTrigger: notifyMqtt, - targetTitle: "MQTT", - logo: "/mqtt.png", - }, - { - actionTrigger: notifyRedis, - targetTitle: "Redis", - logo: "/redis.png", - }, - { - actionTrigger: notifyNats, - targetTitle: "NATS", - logo: "/nats.png", - }, - { - actionTrigger: notifyMysql, - targetTitle: "Mysql", - logo: "/mysql.png", - }, - { - actionTrigger: notifyElasticsearch, - targetTitle: "Elastic Search", - logo: "/elasticsearch.png", - }, - { - actionTrigger: notifyWebhooks, - targetTitle: "Webhook", - logo: "", - }, - { - actionTrigger: notifyNsq, - targetTitle: "NSQ", - logo: "", - }, -]; diff --git a/portal-ui/src/screens/Console/Configurations/TiersConfiguration/ListTiersConfiguration.tsx b/portal-ui/src/screens/Console/Configurations/TiersConfiguration/ListTiersConfiguration.tsx index 640434059..001a14ec9 100644 --- a/portal-ui/src/screens/Console/Configurations/TiersConfiguration/ListTiersConfiguration.tsx +++ b/portal-ui/src/screens/Console/Configurations/TiersConfiguration/ListTiersConfiguration.tsx @@ -41,6 +41,7 @@ import AddTierConfiguration from "./AddTierConfiguration"; import UpdateTierCredentiasModal from "./UpdateTierCredentiasModal"; import RefreshIcon from "../../../../icons/RefreshIcon"; import SearchIcon from "../../../../icons/SearchIcon"; +import history from "../../../../history"; interface IListTiersConfig { classes: any; @@ -341,11 +342,17 @@ const ListTiersConfiguration = ({ typeSelect("minio"); }} > - {"MinIO"} +
+ {"MinIO"} +
+ +
+ MinIO +
+
diff --git a/portal-ui/src/screens/Console/Configurations/utils.ts b/portal-ui/src/screens/Console/Configurations/utils.ts index 025f8f937..900af4a47 100644 --- a/portal-ui/src/screens/Console/Configurations/utils.ts +++ b/portal-ui/src/screens/Console/Configurations/utils.ts @@ -15,17 +15,6 @@ // along with this program. If not, see . import { IConfigurationElement, IElementValue } from "./types"; -export const notifyPostgres = "notify_postgres"; -export const notifyMysql = "notify_mysql"; -export const notifyKafka = "notify_kafka"; -export const notifyAmqp = "notify_amqp"; -export const notifyMqtt = "notify_mqtt"; -export const notifyRedis = "notify_redis"; -export const notifyNats = "notify_nats"; -export const notifyElasticsearch = "notify_elasticsearch"; -export const notifyWebhooks = "notify_webhook"; -export const notifyNsq = "notify_nsq"; - export const configurationElements: IConfigurationElement[] = [ { configuration_id: "region", @@ -373,466 +362,6 @@ export const fieldsConfigurations: any = { ], }; -const commonFields = [ - { - name: "queue-dir", - label: "Queue Directory", - required: true, - - tooltip: "staging dir for undelivered messages e.g. '/home/events'", - type: "string", - placeholder: "Enter Queue Directory", - }, - { - name: "queue-limit", - label: "Queue Limit", - required: false, - - tooltip: "maximum limit for undelivered messages, defaults to '10000'", - type: "number", - placeholder: "Enter Queue Limit", - }, - { - name: "comment", - label: "Comment", - required: false, - type: "comment", - placeholder: "Enter Comment", - }, -]; - -export const notificationEndpointsFields: any = { - [notifyKafka]: [ - { - name: "brokers", - label: "Brokers", - required: true, - - tooltip: "Comma separated list of Kafka broker addresses", - type: "string", - placeholder: "Enter Brokers", - }, - { - name: "topic", - label: "Topic", - tooltip: "Kafka topic used for bucket notifications", - type: "string", - placeholder: "Enter Topic", - }, - { - name: "sasl_username", - label: "SASL Username", - tooltip: "Username for SASL/PLAIN or SASL/SCRAM authentication", - type: "string", - placeholder: "Enter SASL Username", - }, - { - name: "sasl_password", - label: "SASL Password", - tooltip: "Password for SASL/PLAIN or SASL/SCRAM authentication", - type: "string", - placeholder: "Enter SASL Password", - }, - { - name: "sasl_mechanism", - label: "SASL Mechanism", - tooltip: "SASL authentication mechanism, default 'PLAIN'", - type: "string", - }, - { - name: "tls_client_auth", - label: "TLS Client Auth", - tooltip: - "Client Auth determines the Kafka server's policy for TLS client auth", - type: "string", - placeholder: "Enter TLS Client Auth", - }, - { - name: "sasl", - label: "SASL", - tooltip: "Set to 'on' to enable SASL authentication", - type: "on|off", - }, - { - name: "tls", - label: "TLS", - tooltip: "Set to 'on' to enable TLS", - type: "on|off", - }, - { - name: "tls_skip_verify", - label: "TLS skip verify", - tooltip: - 'Trust server TLS without verification, defaults to "on" (verify)', - type: "on|off", - }, - { - name: "client_tls_cert", - label: "client TLS cert", - tooltip: "Path to client certificate for mTLS auth", - type: "path", - placeholder: "Enter TLS Client Cert", - }, - { - name: "client_tls_key", - label: "client TLS key", - tooltip: "Path to client key for mTLS auth", - type: "path", - placeholder: "Enter TLS Client Key", - }, - { - name: "version", - label: "Version", - tooltip: "Specify the version of the Kafka cluster e.g '2.2.0'", - type: "string", - placeholder: "Enter Kafka Version", - }, - ...commonFields, - ], - [notifyAmqp]: [ - { - name: "url", - required: true, - label: "URL", - tooltip: - "AMQP server endpoint e.g. `amqp://myuser:mypassword@localhost:5672`", - type: "url", - }, - { - name: "exchange", - label: "Exchange", - tooltip: "Name of the AMQP exchange", - type: "string", - placeholder: "Enter Exchange", - }, - { - name: "exchange_type", - label: "Exchange Type", - tooltip: "AMQP exchange type", - type: "string", - placeholder: "Enter Exchange Type", - }, - { - name: "routing_key", - label: "Routing Key", - tooltip: "Routing key for publishing", - type: "string", - placeholder: "Enter Routing Key", - }, - { - name: "mandatory", - label: "Mandatory", - tooltip: - "Quietly ignore undelivered messages when set to 'off', default is 'on'", - type: "on|off", - }, - { - name: "durable", - label: "Durable", - tooltip: - "Persist queue across broker restarts when set to 'on', default is 'off'", - type: "on|off", - }, - { - name: "no_wait", - label: "No Wait", - tooltip: - "Non-blocking message delivery when set to 'on', default is 'off'", - type: "on|off", - }, - { - name: "internal", - label: "Internal", - tooltip: - "Set to 'on' for exchange to be not used directly by publishers, but only when bound to other exchanges", - type: "on|off", - }, - { - name: "auto_deleted", - label: "Auto Deleted", - tooltip: - "Auto delete queue when set to 'on', when there are no consumers", - type: "on|off", - }, - { - name: "delivery_mode", - label: "Delivery Mode", - tooltip: "Set to '1' for non-persistent or '2' for persistent queue", - type: "number", - placeholder: "Enter Delivery Mode", - }, - ...commonFields, - ], - [notifyRedis]: [ - { - name: "address", - required: true, - label: "Address", - tooltip: "Redis server's address. For example: `localhost:6379`", - type: "address", - placeholder: "Enter Address", - }, - { - name: "key", - required: true, - label: "Key", - tooltip: "Redis key to store/update events, key is auto-created", - type: "string", - placeholder: "Enter Key", - }, - { - name: "password", - label: "Password", - tooltip: "Redis server password", - type: "string", - placeholder: "Enter Password", - }, - ...commonFields, - ], - [notifyMqtt]: [ - { - name: "broker", - required: true, - label: "Broker", - tooltip: "MQTT server endpoint e.g. `tcp://localhost:1883`", - type: "uri", - placeholder: "Enter Brokers", - }, - { - name: "topic", - required: true, - label: "Topic", - tooltip: "name of the MQTT topic to publish", - type: "string", - placeholder: "Enter Topic", - }, - { - name: "username", - label: "Username", - tooltip: "MQTT username", - type: "string", - placeholder: "Enter Username", - }, - { - name: "password", - label: "Password", - tooltip: "MQTT password", - type: "string", - placeholder: "Enter Password", - }, - { - name: "qos", - label: "QOS", - tooltip: "Set the quality of service priority, defaults to '0'", - type: "number", - placeholder: "Enter QOS", - }, - { - name: "keep_alive_interval", - label: "Keep Alive Interval", - tooltip: "Keep-alive interval for MQTT connections in s,m,h,d", - type: "duration", - placeholder: "Enter Keep Alive Internal", - }, - { - name: "reconnect_interval", - label: "Reconnect Interval", - tooltip: "Reconnect interval for MQTT connections in s,m,h,d", - type: "duration", - placeholder: "Enter Reconnect Interval", - }, - ...commonFields, - ], - [notifyNats]: [ - { - name: "address", - required: true, - label: "Address", - tooltip: "NATS server address e.g. '0.0.0.0:4222'", - type: "address", - placeholder: "Enter Address", - }, - { - name: "subject", - required: true, - label: "Subject", - tooltip: "NATS subscription subject", - type: "string", - placeholder: "Enter NATS Subject", - }, - { - name: "username", - label: "Username", - tooltip: "NATS username", - type: "string", - placeholder: "Enter NATS Username", - }, - { - name: "password", - label: "Password", - tooltip: "NATS password", - type: "string", - placeholder: "Enter NATS password", - }, - { - name: "token", - label: "Token", - tooltip: "NATS token", - type: "string", - placeholder: "Enter NATS token", - }, - { - name: "tls", - label: "TLS", - tooltip: "Set to 'on' to enable TLS", - type: "on|off", - }, - { - name: "tls_skip_verify", - label: "TLS Skip Verify", - tooltip: - 'Trust server TLS without verification, defaults to "on" (verify)', - type: "on|off", - }, - { - name: "ping_interval", - label: "Ping Interval", - tooltip: "Client ping commands interval in s,m,h,d. Disabled by default", - type: "duration", - placeholder: "Enter Ping Interval", - }, - { - name: "streaming", - label: "Streaming", - tooltip: "Set to 'on', to use streaming NATS server", - type: "on|off", - }, - { - name: "streaming_async", - label: "Streaming async", - tooltip: "Set to 'on', to enable asynchronous publish", - type: "on|off", - }, - { - name: "streaming_max_pub_acks_in_flight", - label: "Streaming max publish ACKS in flight", - tooltip: "Number of messages to publish without waiting for ACKs", - type: "number", - placeholder: "Enter Streaming in flight value", - }, - { - name: "streaming_cluster_id", - label: "Streaming Cluster ID", - tooltip: "Unique ID for NATS streaming cluster", - type: "string", - placeholder: "Enter Streaming Cluster ID", - }, - { - name: "cert_authority", - label: "Cert Authority", - tooltip: "Path to certificate chain of the target NATS server", - type: "string", - placeholder: "Enter Cert Authority", - }, - { - name: "client_cert", - label: "Client Cert", - tooltip: "Client cert for NATS mTLS auth", - type: "string", - placeholder: "Enter Client Cert", - }, - { - name: "client_key", - label: "Client Key", - tooltip: "Client cert key for NATS mTLS auth", - type: "string", - placeholder: "Enter Client Key", - }, - ...commonFields, - ], - [notifyElasticsearch]: [ - { - name: "url", - required: true, - label: "URL", - tooltip: - "Elasticsearch server's address, with optional authentication info", - type: "url", - placeholder: "Enter URL", - }, - { - name: "index", - required: true, - label: "Index", - tooltip: - "Elasticsearch index to store/update events, index is auto-created", - type: "string", - placeholder: "Enter Index", - }, - { - name: "format", - required: true, - label: "Format", - tooltip: - "'namespace' reflects current bucket/object list and 'access' reflects a journal of object operations, defaults to 'namespace'", - type: "enum", - placeholder: "Enter Format", - }, - ...commonFields, - ], - [notifyWebhooks]: [ - { - name: "endpoint", - required: true, - label: "Endpoint", - tooltip: - "webhook server endpoint e.g. http://localhost:8080/minio/events", - type: "url", - placeholder: "Enter Endpoint", - }, - { - name: "auth_token", - label: "Auth Token", - tooltip: "opaque string or JWT authorization token", - type: "string", - placeholder: "Enter auth_token", - }, - ...commonFields, - ], - [notifyNsq]: [ - { - name: "nsqd_address", - required: true, - label: "NSQD Address", - tooltip: "NSQ server address e.g. '127.0.0.1:4150'", - type: "address", - placeholder: "Enter nsqd_address", - }, - { - name: "topic", - required: true, - label: "Topic", - tooltip: "NSQ topic", - type: "string", - placeholder: "Enter Topic", - }, - { - name: "tls", - label: "TLS", - tooltip: "set to 'on' to enable TLS", - type: "on|off", - }, - { - name: "tls_skip_verify", - label: "TLS Skip Verify", - tooltip: - 'trust server TLS without verification, defaults to "on" (verify)', - type: "on|off", - }, - ...commonFields, - ], -}; - export const removeEmptyFields = (formFields: IElementValue[]) => { const nonEmptyFields = formFields.filter((field) => field.value !== ""); diff --git a/portal-ui/src/screens/Console/Console.tsx b/portal-ui/src/screens/Console/Console.tsx index 785c86c72..c7e0eaba8 100644 --- a/portal-ui/src/screens/Console/Console.tsx +++ b/portal-ui/src/screens/Console/Console.tsx @@ -56,6 +56,9 @@ import Metrics from "./Dashboard/Metrics"; import Hop from "./Tenants/TenantDetails/hop/Hop"; import MainError from "./Common/MainError/MainError"; import AddTenant from "./Tenants/AddTenant/AddTenant"; +import NotificationEndpoints from "./NotificationEndpoints/NotificationEndpoints"; +import AddNotificationEndpoint from "./NotificationEndpoints/AddNotificationEndpoint"; +import NotificationTypeSelector from "./NotificationEndpoints/NotificationTypeSelector"; const drawerWidth = 245; @@ -278,6 +281,18 @@ const Console = ({ component: ConfigurationMain, path: "/settings", }, + { + component: AddNotificationEndpoint, + path: "/notification-endpoints/add/:service", + }, + { + component: NotificationTypeSelector, + path: "/notification-endpoints/add", + }, + { + component: NotificationEndpoints, + path: "/notification-endpoints", + }, { component: Account, path: "/account", diff --git a/portal-ui/src/screens/Console/Menu/Menu.tsx b/portal-ui/src/screens/Console/Menu/Menu.tsx index 01b220917..5f280db8d 100644 --- a/portal-ui/src/screens/Console/Menu/Menu.tsx +++ b/portal-ui/src/screens/Console/Menu/Menu.tsx @@ -38,6 +38,7 @@ import { DashboardIcon, GroupsIcon, IAMPoliciesIcon, + LambdaIcon, TraceIcon, UsersIcon, VersionIcon, @@ -366,6 +367,14 @@ const Menu = ({ name: "Settings", icon: , }, + { + group: "common", + type: "item", + component: NavLink, + to: "/notification-endpoints", + name: "Notification Endpoints", + icon: , + }, { group: "Tools", type: "item", diff --git a/portal-ui/src/screens/Console/NotificationEndopoints/AddNotificationEndpoint.tsx b/portal-ui/src/screens/Console/NotificationEndopoints/AddNotificationEndpoint.tsx deleted file mode 100644 index 35e89b523..000000000 --- a/portal-ui/src/screens/Console/NotificationEndopoints/AddNotificationEndpoint.tsx +++ /dev/null @@ -1,380 +0,0 @@ -// This file is part of MinIO Console Server -// Copyright (c) 2021 MinIO, Inc. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -import React, { useCallback, useEffect, useState } from "react"; -import get from "lodash/get"; -import { connect } from "react-redux"; -import { createStyles, Theme, withStyles } from "@material-ui/core/styles"; -import { Button, LinearProgress } from "@material-ui/core"; -import Grid from "@material-ui/core/Grid"; -import { serverNeedsRestart, setErrorSnackMessage } from "../../../actions"; -import { - notificationEndpointsFields, - notifyPostgres, - notifyMysql, - notifyKafka, - notifyAmqp, - notifyMqtt, - notifyRedis, - notifyNats, - notifyElasticsearch, - notifyWebhooks, - notifyNsq, - removeEmptyFields, -} from "../Configurations/utils"; -import { IElementValue } from "../Configurations/types"; -import { modalBasic } from "../Common/FormComponents/common/styleLibrary"; -import { ErrorResponseHandler } from "../../../common/types"; -import ConfMySql from "../Configurations/CustomForms/ConfMySql"; -import ConfTargetGeneric from "../Configurations/ConfTargetGeneric"; -import ModalWrapper from "../Common/ModalWrapper/ModalWrapper"; -import ConfPostgres from "../Configurations/CustomForms/ConfPostgres"; -import api from "../../../common/api"; - -const styles = (theme: Theme) => - createStyles({ - errorBlock: { - color: "red", - }, - strongText: { - fontWeight: 700, - }, - keyName: { - marginLeft: 5, - }, - buttonContainer: { - textAlign: "right", - }, - logoButton: { - height: "80px", - }, - lambdaNotif: { - backgroundColor: "#fff", - border: "#393939 1px solid", - borderRadius: 5, - width: 101, - height: 91, - display: "flex", - alignItems: "center", - justifyContent: "center", - marginBottom: 16, - cursor: "pointer", - "& img": { - maxWidth: 71, - maxHeight: 71, - }, - }, - iconContainer: { - display: "flex", - flexDirection: "row", - width: 455, - justifyContent: "space-between", - flexWrap: "wrap", - }, - nonIconContainer: { - marginBottom: 16, - "& button": { - marginRight: 16, - }, - }, - pickTitle: { - fontWeight: 600, - color: "#393939", - fontSize: 14, - marginBottom: 16, - }, - lambdaFormIndicator: { - display: "flex", - marginBottom: 40, - }, - lambdaName: { - fontSize: 18, - fontWeight: 700, - color: "#000", - marginBottom: 6, - }, - lambdaSubname: { - fontSize: 12, - color: "#000", - fontWeight: 600, - }, - lambdaIcon: { - borderRadius: 5, - border: "#393939 1px solid", - width: 53, - height: 48, - display: "flex", - justifyContent: "center", - alignItems: "center", - marginRight: 16, - "& img": { - width: 38, - }, - }, - ...modalBasic, - }); - -interface IAddNotificationEndpointProps { - open: boolean; - closeModalAndRefresh: any; - serverNeedsRestart: typeof serverNeedsRestart; - classes: any; - setErrorSnackMessage: typeof setErrorSnackMessage; -} - -const AddNotificationEndpoint = ({ - open, - closeModalAndRefresh, - serverNeedsRestart, - setErrorSnackMessage, - classes, -}: IAddNotificationEndpointProps) => { - //Local States - const [service, setService] = useState(""); - const [valuesArr, setValueArr] = useState([]); - const [saving, setSaving] = useState(false); - - //Effects - useEffect(() => { - if (saving) { - const payload = { - key_values: removeEmptyFields(valuesArr), - }; - api - .invoke("PUT", `/api/v1/configs/${service}`, payload) - .then((res) => { - setSaving(false); - serverNeedsRestart(true); - - closeModalAndRefresh(); - }) - .catch((err: ErrorResponseHandler) => { - setSaving(false); - setErrorSnackMessage(err); - }); - } - }, [ - saving, - serverNeedsRestart, - service, - valuesArr, - closeModalAndRefresh, - setErrorSnackMessage, - ]); - - //Fetch Actions - const submitForm = (event: React.FormEvent) => { - event.preventDefault(); - setSaving(true); - }; - - const onValueChange = useCallback( - (newValue) => { - setValueArr(newValue); - }, - [setValueArr] - ); - - let srvComponent = ; - switch (service) { - case notifyPostgres: { - srvComponent = ; - break; - } - case notifyMysql: { - srvComponent = ; - break; - } - default: { - const fields = get(notificationEndpointsFields, service, []); - - srvComponent = ( - - ); - } - } - - const servicesList = [ - { - actionTrigger: notifyPostgres, - targetTitle: "Postgres SQL", - logo: "/postgres.png", - }, - { - actionTrigger: notifyKafka, - targetTitle: "Kafka", - logo: "/kafka.png", - }, - { - actionTrigger: notifyAmqp, - targetTitle: "AMQP", - logo: "/amqp.png", - }, - { - actionTrigger: notifyMqtt, - targetTitle: "MQTT", - logo: "/mqtt.png", - }, - { - actionTrigger: notifyRedis, - targetTitle: "Redis", - logo: "/redis.png", - }, - { - actionTrigger: notifyNats, - targetTitle: "NATS", - logo: "/nats.png", - }, - { - actionTrigger: notifyMysql, - targetTitle: "Mysql", - logo: "/mysql.png", - }, - { - actionTrigger: notifyElasticsearch, - targetTitle: "Elastic Search", - logo: "/elasticsearch.png", - }, - { - actionTrigger: notifyWebhooks, - targetTitle: "Webhook", - logo: "", - }, - { - actionTrigger: notifyNsq, - targetTitle: "NSQ", - logo: "", - }, - ]; - - const nonLogos = servicesList.filter((elService) => elService.logo === ""); - const withLogos = servicesList.filter((elService) => elService.logo !== ""); - - const targetElement = servicesList.find( - (element) => element.actionTrigger === service - ); - - const goBack = () => { - setService(""); - }; - - return ( - - {service === "" && ( - - -
Pick a supported service:
-
- {nonLogos.map((item) => { - return ( - - ); - })} -
-
- {withLogos.map((item) => { - return ( - - ); - })} -
-
- -
-
- - {saving && ( - - - - )} -
- )} - {service !== "" && ( - -
- - {targetElement && targetElement.logo !== "" && ( -
- {targetElement.targetTitle} -
- )} - -
-
- {targetElement ? targetElement.targetTitle : ""} -
-
- Add Lambda Notification Target -
-
-
- - {srvComponent} - - - - - - - -
- )} -
- ); -}; - -const connector = connect(null, { serverNeedsRestart, setErrorSnackMessage }); - -export default connector(withStyles(styles)(AddNotificationEndpoint)); diff --git a/portal-ui/src/screens/Console/Configurations/NotificationEndpoints/AddNotificationEndpoint.tsx b/portal-ui/src/screens/Console/NotificationEndpoints/AddNotificationEndpoint.tsx similarity index 54% rename from portal-ui/src/screens/Console/Configurations/NotificationEndpoints/AddNotificationEndpoint.tsx rename to portal-ui/src/screens/Console/NotificationEndpoints/AddNotificationEndpoint.tsx index 075688b62..9e6328f5e 100644 --- a/portal-ui/src/screens/Console/Configurations/NotificationEndpoints/AddNotificationEndpoint.tsx +++ b/portal-ui/src/screens/Console/NotificationEndpoints/AddNotificationEndpoint.tsx @@ -20,24 +20,27 @@ import get from "lodash/get"; import Grid from "@material-ui/core/Grid"; import { createStyles, Theme, withStyles } from "@material-ui/core/styles"; import { Button } from "@material-ui/core"; -import ConfPostgres from "../CustomForms/ConfPostgres"; -import api from "../../../../common/api"; -import { serverNeedsRestart, setErrorSnackMessage } from "../../../../actions"; +import ConfPostgres from "./CustomForms/ConfPostgres"; +import api from "../../../common/api"; +import { serverNeedsRestart, setErrorSnackMessage } from "../../../actions"; import { notificationEndpointsFields, notifyMysql, notifyPostgres, removeEmptyFields, -} from "../utils"; -import { IElementValue } from "../types"; +} from "./utils"; import { modalBasic, settingsCommon, -} from "../../Common/FormComponents/common/styleLibrary"; +} from "../Common/FormComponents/common/styleLibrary"; import { servicesList } from "./utils"; -import { ErrorResponseHandler } from "../../../../common/types"; -import ConfMySql from "../CustomForms/ConfMySql"; -import ConfTargetGeneric from "../ConfTargetGeneric"; +import { ErrorResponseHandler } from "../../../common/types"; +import ConfMySql from "./CustomForms/ConfMySql"; +import ConfTargetGeneric from "./ConfTargetGeneric"; +import { IElementValue } from "../Configurations/types"; +import PageHeader from "../Common/PageHeader/PageHeader"; +import { BackSettingsIcon } from "../../../icons"; +import history from "../../../history"; const styles = (theme: Theme) => createStyles({ @@ -60,14 +63,52 @@ const styles = (theme: Theme) => ...settingsCommon.customTitle, marginTop: 0, }, - settingsFormContainer: { - ...settingsCommon.settingsFormContainer, - height: "calc(100vh - 422px)", + lambdaNotif: { + background: + "linear-gradient(90deg, rgba(249,249,250,1) 0%, rgba(250,250,251,1) 68%, rgba(254,254,254,1) 100%)", + border: "#E5E5E5 1px solid", + borderRadius: 5, + height: 80, + display: "flex", + alignItems: "center", + justifyContent: "start", + marginBottom: 16, + marginRight: 8, + cursor: "pointer", + padding: 0, + overflow: "hidden", + }, + lambdaNotifIcon: { + backgroundColor: "#FEFEFE", + display: "flex", + alignItems: "center", + justifyContent: "center", + width: 80, + height: 80, + + "& img": { + maxWidth: 46, + maxHeight: 46, + }, + }, + lambdaNotifTitle: { + color: "#07193E", + fontSize: 16, + fontFamily: "Lato,sans-serif", + paddingLeft: 18, + }, + mainCont: { + maxWidth: 1180, + paddingLeft: 38, + paddingRight: 38, + }, + backTo: { + margin: "20px 0px 0", }, }); interface IAddNotificationEndpointProps { - service: string; + match: any; saveAndRefresh: any; serverNeedsRestart: typeof serverNeedsRestart; setErrorSnackMessage: typeof setErrorSnackMessage; @@ -75,7 +116,7 @@ interface IAddNotificationEndpointProps { } const AddNotificationEndpoint = ({ - service, + match, saveAndRefresh, serverNeedsRestart, classes, @@ -84,7 +125,7 @@ const AddNotificationEndpoint = ({ //Local States const [valuesArr, setValueArr] = useState([]); const [saving, setSaving] = useState(false); - + const service = match.params["service"]; //Effects useEffect(() => { @@ -97,7 +138,7 @@ const AddNotificationEndpoint = ({ .then(() => { setSaving(false); serverNeedsRestart(true); - saveAndRefresh(); + history.push("/notification-endpoints"); }) .catch((err: ErrorResponseHandler) => { setSaving(false); @@ -151,36 +192,63 @@ const AddNotificationEndpoint = ({ return ( - {service !== "" && ( - -
- - {targetElement ? targetElement.targetTitle : ""} - Add Lambda - Notification Target - - - {srvComponent} - - - + + + + + + + + {service !== "" && ( + + + {targetElement && ( +
+
+ {targetElement.targetTitle} +
+ +
+ + {targetElement ? targetElement.targetTitle : ""} Lambda + Notification Target + +
+
+ )} +
+ + {srvComponent} + + -
- - -
- )} +
+ )} + + ); }; diff --git a/portal-ui/src/screens/Console/Configurations/ConfTargetGeneric.tsx b/portal-ui/src/screens/Console/NotificationEndpoints/ConfTargetGeneric.tsx similarity index 98% rename from portal-ui/src/screens/Console/Configurations/ConfTargetGeneric.tsx rename to portal-ui/src/screens/Console/NotificationEndpoints/ConfTargetGeneric.tsx index 4e756ae60..50d26d5eb 100644 --- a/portal-ui/src/screens/Console/Configurations/ConfTargetGeneric.tsx +++ b/portal-ui/src/screens/Console/NotificationEndpoints/ConfTargetGeneric.tsx @@ -17,7 +17,7 @@ import React, { useEffect, useState, Fragment } from "react"; import { createStyles, Theme, withStyles } from "@material-ui/core/styles"; import Grid from "@material-ui/core/Grid"; -import { IElementValue, KVField } from "./types"; +import { IElementValue, KVField } from "../Configurations/types"; import { modalBasic } from "../Common/FormComponents/common/styleLibrary"; import InputBoxWrapper from "../Common/FormComponents/InputBoxWrapper/InputBoxWrapper"; import CSVMultiSelector from "../Common/FormComponents/CSVMultiSelector/CSVMultiSelector"; diff --git a/portal-ui/src/screens/Console/Configurations/CustomForms/ConfMySql.tsx b/portal-ui/src/screens/Console/NotificationEndpoints/CustomForms/ConfMySql.tsx similarity index 99% rename from portal-ui/src/screens/Console/Configurations/CustomForms/ConfMySql.tsx rename to portal-ui/src/screens/Console/NotificationEndpoints/CustomForms/ConfMySql.tsx index 64064c76a..fcf5863db 100644 --- a/portal-ui/src/screens/Console/Configurations/CustomForms/ConfMySql.tsx +++ b/portal-ui/src/screens/Console/NotificationEndpoints/CustomForms/ConfMySql.tsx @@ -19,7 +19,7 @@ import { createStyles, Theme, withStyles } from "@material-ui/core/styles"; import Grid from "@material-ui/core/Grid"; import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper"; import RadioGroupSelector from "../../Common/FormComponents/RadioGroupSelector/RadioGroupSelector"; -import { IElementValue } from "../types"; +import { IElementValue } from "../../Configurations/types"; import { modalBasic } from "../../Common/FormComponents/common/styleLibrary"; import CommentBoxWrapper from "../../Common/FormComponents/CommentBoxWrapper/CommentBoxWrapper"; import FormSwitchWrapper from "../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper"; diff --git a/portal-ui/src/screens/Console/Configurations/CustomForms/ConfPostgres.tsx b/portal-ui/src/screens/Console/NotificationEndpoints/CustomForms/ConfPostgres.tsx similarity index 99% rename from portal-ui/src/screens/Console/Configurations/CustomForms/ConfPostgres.tsx rename to portal-ui/src/screens/Console/NotificationEndpoints/CustomForms/ConfPostgres.tsx index a270e3f2d..9088aa5ac 100644 --- a/portal-ui/src/screens/Console/Configurations/CustomForms/ConfPostgres.tsx +++ b/portal-ui/src/screens/Console/NotificationEndpoints/CustomForms/ConfPostgres.tsx @@ -20,7 +20,7 @@ import Grid from "@material-ui/core/Grid"; import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper"; import RadioGroupSelector from "../../Common/FormComponents/RadioGroupSelector/RadioGroupSelector"; import SelectWrapper from "../../Common/FormComponents/SelectWrapper/SelectWrapper"; -import { IElementValue } from "../types"; +import { IElementValue } from "../../Configurations/types"; import { modalBasic } from "../../Common/FormComponents/common/styleLibrary"; import CommentBoxWrapper from "../../Common/FormComponents/CommentBoxWrapper/CommentBoxWrapper"; import FormSwitchWrapper from "../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper"; diff --git a/portal-ui/src/screens/Console/Configurations/CustomForms/EditConfiguration.tsx b/portal-ui/src/screens/Console/NotificationEndpoints/CustomForms/EditConfiguration.tsx similarity index 96% rename from portal-ui/src/screens/Console/Configurations/CustomForms/EditConfiguration.tsx rename to portal-ui/src/screens/Console/NotificationEndpoints/CustomForms/EditConfiguration.tsx index d73e85604..2a7ec8ed6 100644 --- a/portal-ui/src/screens/Console/Configurations/CustomForms/EditConfiguration.tsx +++ b/portal-ui/src/screens/Console/NotificationEndpoints/CustomForms/EditConfiguration.tsx @@ -27,8 +27,14 @@ import { fieldBasic, settingsCommon, } from "../../Common/FormComponents/common/styleLibrary"; -import { fieldsConfigurations, removeEmptyFields } from "../utils"; -import { IConfigurationElement, IElementValue } from "../types"; +import { + fieldsConfigurations, + removeEmptyFields, +} from "../../Configurations/utils"; +import { + IConfigurationElement, + IElementValue, +} from "../../Configurations/types"; import { ErrorResponseHandler } from "../../../../common/types"; const styles = (theme: Theme) => diff --git a/portal-ui/src/screens/Console/Configurations/NotificationEndpoints/ListNotificationEndpoints.tsx b/portal-ui/src/screens/Console/NotificationEndpoints/ListNotificationEndpoints.tsx similarity index 66% rename from portal-ui/src/screens/Console/Configurations/NotificationEndpoints/ListNotificationEndpoints.tsx rename to portal-ui/src/screens/Console/NotificationEndpoints/ListNotificationEndpoints.tsx index 4efda65de..d37966083 100644 --- a/portal-ui/src/screens/Console/Configurations/NotificationEndpoints/ListNotificationEndpoints.tsx +++ b/portal-ui/src/screens/Console/NotificationEndpoints/ListNotificationEndpoints.tsx @@ -29,23 +29,24 @@ import { TransformedEndpointItem, } from "./types"; import { notificationTransform } from "./utils"; -import { AddIcon } from "../../../../icons"; -import TableWrapper from "../../Common/TableWrapper/TableWrapper"; +import { AddIcon } from "../../../icons"; +import TableWrapper from "../Common/TableWrapper/TableWrapper"; import AddNotificationEndpoint from "./AddNotificationEndpoint"; -import { setErrorSnackMessage } from "../../../../actions"; +import { setErrorSnackMessage } from "../../../actions"; import { actionsTray, containerForHeader, searchField, settingsCommon, -} from "../../Common/FormComponents/common/styleLibrary"; -import { ErrorResponseHandler } from "../../../../common/types"; -import api from "../../../../common/api"; -import SlideOptions from "../../Common/SlideOptions/SlideOptions"; -import BackSettingsIcon from "../../../../icons/BackSettingsIcon"; +} from "../Common/FormComponents/common/styleLibrary"; +import { ErrorResponseHandler } from "../../../common/types"; +import api from "../../../common/api"; +import SlideOptions from "../Common/SlideOptions/SlideOptions"; +import BackSettingsIcon from "../../../icons/BackSettingsIcon"; import NotificationTypeSelector from "./NotificationTypeSelector"; -import RefreshIcon from "../../../../icons/RefreshIcon"; -import SearchIcon from "../../../../icons/SearchIcon"; +import RefreshIcon from "../../../icons/RefreshIcon"; +import SearchIcon from "../../../icons/SearchIcon"; +import history from "../../../history"; interface IListNotificationEndpoints { classes: any; @@ -77,10 +78,6 @@ const styles = (theme: Theme) => lambdaContainer: { padding: "15px 0", }, - actionsTray: { - ...actionsTray.actionsTray, - padding: "0 38px", - }, }); const ListNotificationEndpoints = ({ @@ -163,6 +160,45 @@ const ListNotificationEndpoints = ({ return ( + + { + setFilter(event.target.value); + }} + InputProps={{ + disableUnderline: true, + startAdornment: ( + + + + ), + }} + /> + { + setIsLoading(true); + }} + > + + + +
@@ -170,43 +206,6 @@ const ListNotificationEndpoints = ({ slideOptions={[ - - { - setFilter(event.target.value); - }} - InputProps={{ - disableUnderline: true, - startAdornment: ( - - - - ), - }} - /> - { - setIsLoading(true); - }} - > - - - - - { - setService(serviceName); - setCurrentPanel(2); - }} - /> - - , - - - - - - + , ]} diff --git a/portal-ui/src/screens/Console/NotificationEndpoints/NotificationEndpoints.tsx b/portal-ui/src/screens/Console/NotificationEndpoints/NotificationEndpoints.tsx new file mode 100644 index 000000000..db9d554c4 --- /dev/null +++ b/portal-ui/src/screens/Console/NotificationEndpoints/NotificationEndpoints.tsx @@ -0,0 +1,71 @@ +// This file is part of MinIO Console Server +// Copyright (c) 2021 MinIO, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +import React, { Fragment, useState } from "react"; +import PageHeader from "../Common/PageHeader/PageHeader"; +import { Grid } from "@material-ui/core"; +import { createStyles, Theme, withStyles } from "@material-ui/core/styles"; +import { containerForHeader } from "../Common/FormComponents/common/styleLibrary"; + +import { AppState } from "../../../store"; +import { connect } from "react-redux"; +import { ISessionResponse } from "../types"; +import ListNotificationEndpoints from "./ListNotificationEndpoints"; + +interface INotificationEndpoints { + classes: any; + session: ISessionResponse; + distributedSetup: boolean; +} + +const styles = (theme: Theme) => + createStyles({ + headerLabel: { + fontSize: 22, + fontWeight: 600, + color: "#000", + marginTop: 4, + }, + ...containerForHeader(theme.spacing(4)), + }); + +const NotificationEndpoints = ({ + classes, + session, + distributedSetup, +}: INotificationEndpoints) => { + const [selectedTab, setSelectedTab] = useState(0); + + return ( + + + + + + + + + ); +}; + +const mapState = (state: AppState) => ({ + session: state.console.session, + distributedSetup: state.system.distributedSetup, +}); + +const connector = connect(mapState, {}); + +export default withStyles(styles)(connector(NotificationEndpoints)); diff --git a/portal-ui/src/screens/Console/NotificationEndpoints/NotificationTypeSelector.tsx b/portal-ui/src/screens/Console/NotificationEndpoints/NotificationTypeSelector.tsx new file mode 100644 index 000000000..47cb8a4ab --- /dev/null +++ b/portal-ui/src/screens/Console/NotificationEndpoints/NotificationTypeSelector.tsx @@ -0,0 +1,93 @@ +// This file is part of MinIO Console Server +// Copyright (c) 2021 MinIO, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +import React, { Fragment, useState } from "react"; +import Grid from "@material-ui/core/Grid"; +import { createStyles, Theme, withStyles } from "@material-ui/core/styles"; +import { servicesList } from "./utils"; +import { + settingsCommon, + typesSelection, +} from "../Common/FormComponents/common/styleLibrary"; +import PageHeader from "../Common/PageHeader/PageHeader"; +import history from "../../../history"; + +interface INotificationTypeSelector { + classes: any; +} + +const withLogos = servicesList.filter((elService) => elService.logo !== ""); + +const styles = (theme: Theme) => + createStyles({ + ...settingsCommon, + mainCont: { + paddingLeft: 50, + paddingRight: 50, + }, + mainTitle: { + fontSize: 18, + color: "#000", + fontWeight: 600, + marginBottom: 10, + marginTop: 10, + }, + ...typesSelection, + }); + +const NotificationTypeSelector = ({ classes }: INotificationTypeSelector) => { + return ( + + + + + Pick a supported service + + +
+ {withLogos.map((item) => { + return ( + + ); + })} +
+
+
+
+ ); +}; + +export default withStyles(styles)(NotificationTypeSelector); diff --git a/portal-ui/src/screens/Console/Configurations/NotificationEndpoints/types.ts b/portal-ui/src/screens/Console/NotificationEndpoints/types.ts similarity index 100% rename from portal-ui/src/screens/Console/Configurations/NotificationEndpoints/types.ts rename to portal-ui/src/screens/Console/NotificationEndpoints/types.ts diff --git a/portal-ui/src/screens/Console/NotificationEndpoints/utils.ts b/portal-ui/src/screens/Console/NotificationEndpoints/utils.ts new file mode 100644 index 000000000..653a16a55 --- /dev/null +++ b/portal-ui/src/screens/Console/NotificationEndpoints/utils.ts @@ -0,0 +1,560 @@ +// This file is part of MinIO Console Server +// Copyright (c) 2021 MinIO, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +import { NotificationEndpointItem } from "./types"; + +import { IElementValue } from "../Configurations/types"; + +export const notifyPostgres = "notify_postgres"; +export const notifyMysql = "notify_mysql"; +export const notifyKafka = "notify_kafka"; +export const notifyAmqp = "notify_amqp"; +export const notifyMqtt = "notify_mqtt"; +export const notifyRedis = "notify_redis"; +export const notifyNats = "notify_nats"; +export const notifyElasticsearch = "notify_elasticsearch"; +export const notifyWebhooks = "notify_webhook"; +export const notifyNsq = "notify_nsq"; + +export const notificationTransform = ( + notificationElements: NotificationEndpointItem[] +) => { + return notificationElements.map((element) => { + return { + service_name: `${element.service}:${element.account_id}`, + status: element.status, + }; + }); +}; + +export const servicesList = [ + { + actionTrigger: notifyPostgres, + targetTitle: "Postgres SQL", + logo: "/postgres-logo.svg", + }, + { + actionTrigger: notifyKafka, + targetTitle: "Kafka", + logo: "/kafka-logo.svg", + }, + { + actionTrigger: notifyAmqp, + targetTitle: "AMQP", + logo: "/amqp-logo.svg", + }, + { + actionTrigger: notifyMqtt, + targetTitle: "MQTT", + logo: "/mqtt-logo.svg", + }, + { + actionTrigger: notifyRedis, + targetTitle: "Redis", + logo: "/redis-logo.svg", + }, + { + actionTrigger: notifyNats, + targetTitle: "NATS", + logo: "/nats-logo.svg", + }, + { + actionTrigger: notifyMysql, + targetTitle: "Mysql", + logo: "/mysql-logo.svg", + }, + { + actionTrigger: notifyElasticsearch, + targetTitle: "Elastic Search", + logo: "/elasticsearch-logo.svg", + }, + { + actionTrigger: notifyWebhooks, + targetTitle: "Webhook", + logo: "/webhooks-logo.svg", + }, + { + actionTrigger: notifyNsq, + targetTitle: "NSQ", + logo: "/nsq-logo.svg", + }, +]; + +const commonFields = [ + { + name: "queue-dir", + label: "Queue Directory", + required: true, + + tooltip: "staging dir for undelivered messages e.g. '/home/events'", + type: "string", + placeholder: "Enter Queue Directory", + }, + { + name: "queue-limit", + label: "Queue Limit", + required: false, + + tooltip: "maximum limit for undelivered messages, defaults to '10000'", + type: "number", + placeholder: "Enter Queue Limit", + }, + { + name: "comment", + label: "Comment", + required: false, + type: "comment", + placeholder: "Enter Comment", + }, +]; + +export const removeEmptyFields = (formFields: IElementValue[]) => { + const nonEmptyFields = formFields.filter((field) => field.value !== ""); + + return nonEmptyFields; +}; + +export const notificationEndpointsFields: any = { + [notifyKafka]: [ + { + name: "brokers", + label: "Brokers", + required: true, + + tooltip: "Comma separated list of Kafka broker addresses", + type: "string", + placeholder: "Enter Brokers", + }, + { + name: "topic", + label: "Topic", + tooltip: "Kafka topic used for bucket notifications", + type: "string", + placeholder: "Enter Topic", + }, + { + name: "sasl_username", + label: "SASL Username", + tooltip: "Username for SASL/PLAIN or SASL/SCRAM authentication", + type: "string", + placeholder: "Enter SASL Username", + }, + { + name: "sasl_password", + label: "SASL Password", + tooltip: "Password for SASL/PLAIN or SASL/SCRAM authentication", + type: "string", + placeholder: "Enter SASL Password", + }, + { + name: "sasl_mechanism", + label: "SASL Mechanism", + tooltip: "SASL authentication mechanism, default 'PLAIN'", + type: "string", + }, + { + name: "tls_client_auth", + label: "TLS Client Auth", + tooltip: + "Client Auth determines the Kafka server's policy for TLS client auth", + type: "string", + placeholder: "Enter TLS Client Auth", + }, + { + name: "sasl", + label: "SASL", + tooltip: "Set to 'on' to enable SASL authentication", + type: "on|off", + }, + { + name: "tls", + label: "TLS", + tooltip: "Set to 'on' to enable TLS", + type: "on|off", + }, + { + name: "tls_skip_verify", + label: "TLS skip verify", + tooltip: + 'Trust server TLS without verification, defaults to "on" (verify)', + type: "on|off", + }, + { + name: "client_tls_cert", + label: "client TLS cert", + tooltip: "Path to client certificate for mTLS auth", + type: "path", + placeholder: "Enter TLS Client Cert", + }, + { + name: "client_tls_key", + label: "client TLS key", + tooltip: "Path to client key for mTLS auth", + type: "path", + placeholder: "Enter TLS Client Key", + }, + { + name: "version", + label: "Version", + tooltip: "Specify the version of the Kafka cluster e.g '2.2.0'", + type: "string", + placeholder: "Enter Kafka Version", + }, + ...commonFields, + ], + [notifyAmqp]: [ + { + name: "url", + required: true, + label: "URL", + tooltip: + "AMQP server endpoint e.g. `amqp://myuser:mypassword@localhost:5672`", + type: "url", + }, + { + name: "exchange", + label: "Exchange", + tooltip: "Name of the AMQP exchange", + type: "string", + placeholder: "Enter Exchange", + }, + { + name: "exchange_type", + label: "Exchange Type", + tooltip: "AMQP exchange type", + type: "string", + placeholder: "Enter Exchange Type", + }, + { + name: "routing_key", + label: "Routing Key", + tooltip: "Routing key for publishing", + type: "string", + placeholder: "Enter Routing Key", + }, + { + name: "mandatory", + label: "Mandatory", + tooltip: + "Quietly ignore undelivered messages when set to 'off', default is 'on'", + type: "on|off", + }, + { + name: "durable", + label: "Durable", + tooltip: + "Persist queue across broker restarts when set to 'on', default is 'off'", + type: "on|off", + }, + { + name: "no_wait", + label: "No Wait", + tooltip: + "Non-blocking message delivery when set to 'on', default is 'off'", + type: "on|off", + }, + { + name: "internal", + label: "Internal", + tooltip: + "Set to 'on' for exchange to be not used directly by publishers, but only when bound to other exchanges", + type: "on|off", + }, + { + name: "auto_deleted", + label: "Auto Deleted", + tooltip: + "Auto delete queue when set to 'on', when there are no consumers", + type: "on|off", + }, + { + name: "delivery_mode", + label: "Delivery Mode", + tooltip: "Set to '1' for non-persistent or '2' for persistent queue", + type: "number", + placeholder: "Enter Delivery Mode", + }, + ...commonFields, + ], + [notifyRedis]: [ + { + name: "address", + required: true, + label: "Address", + tooltip: "Redis server's address. For example: `localhost:6379`", + type: "address", + placeholder: "Enter Address", + }, + { + name: "key", + required: true, + label: "Key", + tooltip: "Redis key to store/update events, key is auto-created", + type: "string", + placeholder: "Enter Key", + }, + { + name: "password", + label: "Password", + tooltip: "Redis server password", + type: "string", + placeholder: "Enter Password", + }, + ...commonFields, + ], + [notifyMqtt]: [ + { + name: "broker", + required: true, + label: "Broker", + tooltip: "MQTT server endpoint e.g. `tcp://localhost:1883`", + type: "uri", + placeholder: "Enter Brokers", + }, + { + name: "topic", + required: true, + label: "Topic", + tooltip: "name of the MQTT topic to publish", + type: "string", + placeholder: "Enter Topic", + }, + { + name: "username", + label: "Username", + tooltip: "MQTT username", + type: "string", + placeholder: "Enter Username", + }, + { + name: "password", + label: "Password", + tooltip: "MQTT password", + type: "string", + placeholder: "Enter Password", + }, + { + name: "qos", + label: "QOS", + tooltip: "Set the quality of service priority, defaults to '0'", + type: "number", + placeholder: "Enter QOS", + }, + { + name: "keep_alive_interval", + label: "Keep Alive Interval", + tooltip: "Keep-alive interval for MQTT connections in s,m,h,d", + type: "duration", + placeholder: "Enter Keep Alive Internal", + }, + { + name: "reconnect_interval", + label: "Reconnect Interval", + tooltip: "Reconnect interval for MQTT connections in s,m,h,d", + type: "duration", + placeholder: "Enter Reconnect Interval", + }, + ...commonFields, + ], + [notifyNats]: [ + { + name: "address", + required: true, + label: "Address", + tooltip: "NATS server address e.g. '0.0.0.0:4222'", + type: "address", + placeholder: "Enter Address", + }, + { + name: "subject", + required: true, + label: "Subject", + tooltip: "NATS subscription subject", + type: "string", + placeholder: "Enter NATS Subject", + }, + { + name: "username", + label: "Username", + tooltip: "NATS username", + type: "string", + placeholder: "Enter NATS Username", + }, + { + name: "password", + label: "Password", + tooltip: "NATS password", + type: "string", + placeholder: "Enter NATS password", + }, + { + name: "token", + label: "Token", + tooltip: "NATS token", + type: "string", + placeholder: "Enter NATS token", + }, + { + name: "tls", + label: "TLS", + tooltip: "Set to 'on' to enable TLS", + type: "on|off", + }, + { + name: "tls_skip_verify", + label: "TLS Skip Verify", + tooltip: + 'Trust server TLS without verification, defaults to "on" (verify)', + type: "on|off", + }, + { + name: "ping_interval", + label: "Ping Interval", + tooltip: "Client ping commands interval in s,m,h,d. Disabled by default", + type: "duration", + placeholder: "Enter Ping Interval", + }, + { + name: "streaming", + label: "Streaming", + tooltip: "Set to 'on', to use streaming NATS server", + type: "on|off", + }, + { + name: "streaming_async", + label: "Streaming async", + tooltip: "Set to 'on', to enable asynchronous publish", + type: "on|off", + }, + { + name: "streaming_max_pub_acks_in_flight", + label: "Streaming max publish ACKS in flight", + tooltip: "Number of messages to publish without waiting for ACKs", + type: "number", + placeholder: "Enter Streaming in flight value", + }, + { + name: "streaming_cluster_id", + label: "Streaming Cluster ID", + tooltip: "Unique ID for NATS streaming cluster", + type: "string", + placeholder: "Enter Streaming Cluster ID", + }, + { + name: "cert_authority", + label: "Cert Authority", + tooltip: "Path to certificate chain of the target NATS server", + type: "string", + placeholder: "Enter Cert Authority", + }, + { + name: "client_cert", + label: "Client Cert", + tooltip: "Client cert for NATS mTLS auth", + type: "string", + placeholder: "Enter Client Cert", + }, + { + name: "client_key", + label: "Client Key", + tooltip: "Client cert key for NATS mTLS auth", + type: "string", + placeholder: "Enter Client Key", + }, + ...commonFields, + ], + [notifyElasticsearch]: [ + { + name: "url", + required: true, + label: "URL", + tooltip: + "Elasticsearch server's address, with optional authentication info", + type: "url", + placeholder: "Enter URL", + }, + { + name: "index", + required: true, + label: "Index", + tooltip: + "Elasticsearch index to store/update events, index is auto-created", + type: "string", + placeholder: "Enter Index", + }, + { + name: "format", + required: true, + label: "Format", + tooltip: + "'namespace' reflects current bucket/object list and 'access' reflects a journal of object operations, defaults to 'namespace'", + type: "enum", + placeholder: "Enter Format", + }, + ...commonFields, + ], + [notifyWebhooks]: [ + { + name: "endpoint", + required: true, + label: "Endpoint", + tooltip: + "webhook server endpoint e.g. http://localhost:8080/minio/events", + type: "url", + placeholder: "Enter Endpoint", + }, + { + name: "auth_token", + label: "Auth Token", + tooltip: "opaque string or JWT authorization token", + type: "string", + placeholder: "Enter auth_token", + }, + ...commonFields, + ], + [notifyNsq]: [ + { + name: "nsqd_address", + required: true, + label: "NSQD Address", + tooltip: "NSQ server address e.g. '127.0.0.1:4150'", + type: "address", + placeholder: "Enter nsqd_address", + }, + { + name: "topic", + required: true, + label: "Topic", + tooltip: "NSQ topic", + type: "string", + placeholder: "Enter Topic", + }, + { + name: "tls", + label: "TLS", + tooltip: "set to 'on' to enable TLS", + type: "on|off", + }, + { + name: "tls_skip_verify", + label: "TLS Skip Verify", + tooltip: + 'trust server TLS without verification, defaults to "on" (verify)', + type: "on|off", + }, + ...commonFields, + ], +};