From dbfe3ce5f245167cba578328adfbbd2c8475f776 Mon Sep 17 00:00:00 2001 From: Jelena Date: Mon, 20 Jul 2020 16:00:44 +0000 Subject: [PATCH] Managing redactors updates --- kotsadm/pkg/handlers/redact.go | 2 +- kotsadm/pkg/redact/redact.go | 20 +++--- kotsadm/pkg/redact/redact_test.go | 6 +- .../src/components/redactors/EditRedactor.jsx | 70 ++++++++++++------- .../src/components/redactors/RedactorRow.jsx | 10 +-- .../src/components/redactors/Redactors.jsx | 54 ++++++++++++-- .../troubleshoot/AnalyzerFileTree.jsx | 2 +- .../troubleshoot/SupportBundleList.jsx | 11 +-- .../troubleshoot/TroubleshootContainer.jsx | 8 +-- .../components/redactors/EditRedactor.scss | 16 +++++ 10 files changed, 134 insertions(+), 65 deletions(-) create mode 100644 kotsadm/web/src/scss/components/redactors/EditRedactor.scss diff --git a/kotsadm/pkg/handlers/redact.go b/kotsadm/pkg/handlers/redact.go index 3fefe1e3fd..038fd29911 100644 --- a/kotsadm/pkg/handlers/redact.go +++ b/kotsadm/pkg/handlers/redact.go @@ -309,7 +309,7 @@ func SetRedactMetadataAndYaml(w http.ResponseWriter, r *http.Request) { newRedactor, err := redact.SetRedactYaml(redactorSlug, updateRedactRequest.Description, updateRedactRequest.Enabled, updateRedactRequest.New, []byte(updateRedactRequest.Redactor)) if err != nil { logger.Error(err) - metadataResponse.Error = "failed to update redactor" + metadataResponse.Error = err.Error() JSON(w, 400, metadataResponse) return } diff --git a/kotsadm/pkg/redact/redact.go b/kotsadm/pkg/redact/redact.go index a7ff7727db..c2127f15fb 100644 --- a/kotsadm/pkg/redact/redact.go +++ b/kotsadm/pkg/redact/redact.go @@ -5,11 +5,10 @@ import ( "encoding/json" "fmt" "os" - "regexp" "sort" - "strings" "time" + "github.com/gosimple/slug" "github.com/pkg/errors" "github.com/replicatedhq/kots/pkg/util" "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1" @@ -245,19 +244,19 @@ func setRedactYaml(slug, description string, enabled, newRedact bool, currentTim redactorEntry := RedactorMetadata{} redactString, ok := data[slug] + if !ok || newRedact { - // if name is not set in yaml, autogenerate a name + // if name is not set in yaml throw error // if name is set, create the slug from the name if newRedactorSpec.Name == "" { - newRedactorSpec.Name = fmt.Sprintf("redactor-%d", len(data)+1) - slug = getSlug(newRedactorSpec.Name) + return nil, nil, fmt.Errorf("failed to create new redact spec: name can't be empty") } else { slug = getSlug(newRedactorSpec.Name) } if _, ok := data[slug]; ok { // the target slug already exists - this is an error - return nil, nil, fmt.Errorf("refusing to create new redact spec with name %s - slug %s already exists", newRedactorSpec.Name, slug) + return nil, nil, fmt.Errorf("failed to create new redact spec: name %s - slug %s already exists", newRedactorSpec.Name, slug) } // create the new redactor @@ -278,7 +277,7 @@ func setRedactYaml(slug, description string, enabled, newRedact bool, currentTim if _, ok := data[getSlug(newRedactorSpec.Name)]; ok { // the target slug already exists - this is an error - return nil, nil, fmt.Errorf("refusing to change slug from %s to %s as that already exists", slug, getSlug(newRedactorSpec.Name)) + return nil, nil, fmt.Errorf("failed to update redact spec: refusing to change slug from %s to %s as that already exists", slug, getSlug(newRedactorSpec.Name)) } delete(data, slug) @@ -288,8 +287,7 @@ func setRedactYaml(slug, description string, enabled, newRedact bool, currentTim } if newRedactorSpec.Name == "" { - newRedactorSpec.Name = slug - redactorEntry.Metadata.Name = slug + return nil, nil, fmt.Errorf("failed to update redact spec: name can't be empty") } } @@ -386,9 +384,7 @@ func writeConfigmap(configMap *v1.ConfigMap) (*v1.ConfigMap, error) { } func getSlug(name string) string { - name = strings.ReplaceAll(name, " ", "-") - - name = regexp.MustCompile(`[^\w\d-_]`).ReplaceAllString(name, "") + name = slug.Make(name) if name == "kotsadm-redact" { name = "kotsadm-redact-metadata" diff --git a/kotsadm/pkg/redact/redact_test.go b/kotsadm/pkg/redact/redact_test.go index cdd5dd1842..1faae9cbe5 100644 --- a/kotsadm/pkg/redact/redact_test.go +++ b/kotsadm/pkg/redact/redact_test.go @@ -21,7 +21,7 @@ func Test_getSlug(t *testing.T) { { name: "all alphanumeric", input: "aBC123", - want: "aBC123", + want: "abc123", }, { name: "dashes", @@ -34,9 +34,9 @@ func Test_getSlug(t *testing.T) { want: "abc-123", }, { - name: "aymbols", + name: "symbols", input: "abc%^123!@#", - want: "abc123", + want: "abc-123-at", }, { name: "kotsadm-redact", diff --git a/kotsadm/web/src/components/redactors/EditRedactor.jsx b/kotsadm/web/src/components/redactors/EditRedactor.jsx index 1cadac786f..678a92779d 100644 --- a/kotsadm/web/src/components/redactors/EditRedactor.jsx +++ b/kotsadm/web/src/components/redactors/EditRedactor.jsx @@ -10,6 +10,8 @@ import "brace/theme/chrome"; import Loader from "../shared/Loader"; import { Utilities } from "../../utilities/utilities"; +import "../../scss/components/redactors/EditRedactor.scss" + class EditRedactor extends Component { state = { redactorEnabled: false, @@ -71,7 +73,6 @@ class EditRedactor extends Component { this.setState({ editingRedactor: true, editingErrMsg: "" }); const payload = { - slug: slug, enabled: enabled, redactor: yaml } @@ -106,6 +107,7 @@ class EditRedactor extends Component { setTimeout(() => { this.setState({ editConfirm: false }) }, 3000); + this.props.history.replace(`/app/${this.props.appSlug}/troubleshoot/redactors`) } else { this.setState({ editingRedactor: false, @@ -121,6 +123,22 @@ class EditRedactor extends Component { }); } + getEmptyNameLine = (redactorYaml) => { + const splittedYaml = redactorYaml.split("\n"); + let metadataFound = false; + let namePosition; + for(let i=0; i { this.setState({ creatingRedactor: true, createErrMsg: "" }); @@ -144,8 +162,10 @@ class EditRedactor extends Component { this.setState({ creatingRedactor: false, createErrMsg: createResponse.error - }) - return; + }); + const editor = this.aceEditor.editor; + editor.scrollToLine(this.getEmptyNameLine(this.state.redactorYaml), true, true); + editor.gotoLine(this.getEmptyNameLine(this.state.redactorYaml), 1, true); } if (createResponse.success) { @@ -160,7 +180,7 @@ class EditRedactor extends Component { setTimeout(() => { this.setState({ createConfirm: false }) }, 3000); - this.props.history.replace(`/app/${this.props.appSlug}/troubleshoot/redactors/${createResponse.redactorMetadata.slug}`) + this.props.history.replace(`/app/${this.props.appSlug}/troubleshoot/redactors`) } else { this.setState({ creatingRedactor: false, @@ -189,7 +209,7 @@ class EditRedactor extends Component { const defaultYaml = `kind: Redactor apiVersion: troubleshoot.replicated.com/v1beta1 metadata: - name: kotsadm-redact + name: spec: redactors: - name: myredactor @@ -199,7 +219,7 @@ spec: removals: values: - "removethis"` - this.setState({ redactorEnabled: false, redactorYaml: defaultYaml, redactorName: "New redactor" }); + this.setState({ redactorEnabled: true, redactorYaml: defaultYaml, redactorName: "New redactor" }); } } @@ -233,6 +253,7 @@ spec: Redactors
+ {(createErrMsg || editingErrMsg) &&

{createErrMsg ? createErrMsg : editingErrMsg}

}
Redactors > {this.state.redactorName}
@@ -240,32 +261,30 @@ spec:

{this.state.redactorName}

- {!this.props.isNew && -
-
-
-
- { this.handleEnableRedactor(e) }} - /> -
-
-
-

{this.state.redactorEnabled ? "Enabled" : "Disabled"}

+
+
+
+
+ { this.handleEnableRedactor(e) }} + />
+
+

{this.state.redactorEnabled ? "Enabled" : "Disabled"}

+
- } +

For more information about creating redactors, check out our docs.

this.refAceEditor = input} + ref={el => (this.aceEditor = el)} mode="yaml" theme="chrome" className="flex1 flex" @@ -287,7 +306,7 @@ spec:
- Cancel + Cancel
{createConfirm || editConfirm && @@ -296,7 +315,6 @@ spec: {createConfirm ? "Redactor created" : "Redactor updated"}
} - {(createErrMsg || editingErrMsg) &&

{createErrMsg ? createErrMsg : editingErrMsg}

}
diff --git a/kotsadm/web/src/components/redactors/RedactorRow.jsx b/kotsadm/web/src/components/redactors/RedactorRow.jsx index c9c13ec10f..d31e73ab23 100644 --- a/kotsadm/web/src/components/redactors/RedactorRow.jsx +++ b/kotsadm/web/src/components/redactors/RedactorRow.jsx @@ -2,14 +2,16 @@ import React from "react"; import dayjs from "dayjs"; import { Link } from "react-router-dom" +import { Utilities } from "../../utilities/utilities"; + class RedactorRow extends React.Component { state = { - redactorEnabled: false + redactorEnabled: false, }; handleEnableRedactor = () => { - this.setState({ - redactorEnabled: !this.state.redactorEnabled, + this.setState({ redactorEnabled: !this.state.redactorEnabled }, () => { + this.props.handleSetRedactEnabled(this.props.redactor, this.state.redactorEnabled); }); } @@ -37,7 +39,7 @@ class RedactorRow extends React.Component {

{redactor?.description}

- Edit redactor + Edit this.handleDeleteClick(redactor)}>Delete
{ @@ -81,8 +81,10 @@ class Redactors extends Component { sortRedactors = value => { if (value === "createdAt") { this.setState({ sortedRedactors: this.state.redactors.sort((a, b) => dayjs(b.createdAt) - dayjs(a.createdAt)) }); - } else { + } else if (value === "updatedAt") { this.setState({ sortedRedactors: this.state.redactors.sort((a, b) => dayjs(b.updatedAt) - dayjs(a.updatedAt)) }); + } else { + this.setState({ sortedRedactors: this.state.redactors.sort((a, b) => (a.enabled === b.enabled) ? 0 : a.enabled ? -1 : 1 )}); } } @@ -121,9 +123,42 @@ class Redactors extends Component { }); } + handleSetRedactEnabled = (redactor, redactorEnabled) => { + const payload = { + enabled: redactorEnabled + } + this.setState({ enablingRedactorMsg: "" }); + fetch(`${window.env.API_ENDPOINT}/redact/enabled/${redactor.slug}`, { + method: "POST", + headers: { + "Authorization": Utilities.getToken(), + "Content-Type": "application/json", + }, + body: JSON.stringify(payload) + }) + .then(async (res) => { + const response = await res.json(); + if (!res.ok) { + this.setState({ enablingRedactorMsg: response.error }); + return; + } + if (response.success) { + this.setState({ enablingRedactorMsg: "" }); + } else { + this.setState({ enablingRedactorMsg: response.error }); + } + }) + .catch((err) => { + this.setState({ + enablingRedactorMsg: err.message ? err.message : "Something went wrong, please try again!" + }); + }); + } + + render() { - const { sortedRedactors, selectedOption, deleteRedactorModal, isLoadingRedactors } = this.state; + const { sortedRedactors, selectedOption, deleteRedactorModal, isLoadingRedactors, enablingRedactorMsg } = this.state; if (isLoadingRedactors) { return ( @@ -134,6 +169,10 @@ class Redactors extends Component { } const selectOptions = [ + { + value: "enabled", + label: "Sort by: Status" + }, { value: "createdAt", label: "Sort by: Created At" @@ -189,12 +228,15 @@ class Redactors extends Component {

Define custom rules for sensitive values you need to be redacted when gathering a support bundle. This might include things like Secrets or IP addresses. For help with creating custom redactors, check out our docs.

+ {enablingRedactorMsg &&

{enablingRedactorMsg}

} {sortedRedactors?.map((redactor) => ( ))}
diff --git a/kotsadm/web/src/components/troubleshoot/AnalyzerFileTree.jsx b/kotsadm/web/src/components/troubleshoot/AnalyzerFileTree.jsx index cf3b2359fd..4b6d718efd 100644 --- a/kotsadm/web/src/components/troubleshoot/AnalyzerFileTree.jsx +++ b/kotsadm/web/src/components/troubleshoot/AnalyzerFileTree.jsx @@ -206,7 +206,7 @@ class AnalyzerFileTree extends React.Component { } render() { - const { files, fileContents, selectedFile, fileLoadErr, fileLoadErrMessage, fileLoading, analysisError } = this.state; + const { files, fileContents, selectedFile, fileLoadErr, fileLoadErrMessage, fileLoading } = this.state; const fileToView = find(fileContents, ["key", selectedFile]); const format = getFileFormat(selectedFile); const isOld = files && has(files[0], "size"); diff --git a/kotsadm/web/src/components/troubleshoot/SupportBundleList.jsx b/kotsadm/web/src/components/troubleshoot/SupportBundleList.jsx index e6609319b2..ab6aea2f75 100644 --- a/kotsadm/web/src/components/troubleshoot/SupportBundleList.jsx +++ b/kotsadm/web/src/components/troubleshoot/SupportBundleList.jsx @@ -4,7 +4,7 @@ import { withRouter, Link } from "react-router-dom"; import { graphql, compose, withApollo } from "react-apollo"; import { listSupportBundles } from "../../queries/TroubleshootQueries"; -// import Toggle from "../shared/Toggle"; +import Toggle from "../shared/Toggle"; import Loader from "../shared/Loader"; import SupportBundleRow from "./SupportBundleRow"; import GenerateSupportBundle from "./GenerateSupportBundle"; @@ -69,7 +69,7 @@ class SupportBundleList extends React.Component { {`${appTitle} Troubleshoot`}
- {/*
+
-
*/} +
@@ -129,9 +129,4 @@ export default withRouter(compose( } } }) - // graphql(archiveSupportBundle, { - // props: ({ mutate }) => ({ - // archiveSupportBundle: (id) => mutate({ variables: { id } }) - // }) - // }), )(SupportBundleList)); \ No newline at end of file diff --git a/kotsadm/web/src/components/troubleshoot/TroubleshootContainer.jsx b/kotsadm/web/src/components/troubleshoot/TroubleshootContainer.jsx index 05d09d7b89..567cc6b005 100644 --- a/kotsadm/web/src/components/troubleshoot/TroubleshootContainer.jsx +++ b/kotsadm/web/src/components/troubleshoot/TroubleshootContainer.jsx @@ -4,8 +4,8 @@ import NotFound from "../static/NotFound"; import SupportBundleList from "../troubleshoot/SupportBundleList"; import SupportBundleAnalysis from "../troubleshoot/SupportBundleAnalysis"; import GenerateSupportBundle from "../troubleshoot/GenerateSupportBundle"; -// import Redactors from "../redactors/Redactors"; -// import EditRedactor from "../redactors/EditRedactor"; +import Redactors from "../redactors/Redactors"; +import EditRedactor from "../redactors/EditRedactor"; class TroubleshootContainer extends Component { @@ -24,7 +24,7 @@ class TroubleshootContainer extends Component { } /> - {/* + } /> @@ -32,7 +32,7 @@ class TroubleshootContainer extends Component { /> } - /> */} + />
diff --git a/kotsadm/web/src/scss/components/redactors/EditRedactor.scss b/kotsadm/web/src/scss/components/redactors/EditRedactor.scss new file mode 100644 index 0000000000..6ffc69e710 --- /dev/null +++ b/kotsadm/web/src/scss/components/redactors/EditRedactor.scss @@ -0,0 +1,16 @@ +.ErrorToast { + position: absolute; + left: 50%; + top: 220px; + z-index: 300; + padding: 11px 10px 10px; + line-height: normal; + font-size: 14px; + font-weight: 500; + border-radius: 4px; + transition: transform .3s cubic-bezier(0.285, -0.575, 0.675, 1.440); + transform: translate(-50%, -90px); + background-color: #FFDADA; + color: #863333; + max-width: 400px; +} \ No newline at end of file