From 4851bc0e8283d3f0c3bc2439d1c239ecad5b9924 Mon Sep 17 00:00:00 2001 From: Victor Cabezas Date: Thu, 21 Apr 2022 11:24:24 +0200 Subject: [PATCH] Add visualization for action reason and replace paths (forces replacement) --- .../src/__tests__/entities/utils.test.jsx | 17 +++++---- cli/template/src/__tests__/plan.json | 5 ++- .../components/focused-view/focused-view.tsx | 36 +++++++++++++++---- cli/template/src/data/entities/entities.ts | 3 ++ cli/template/src/data/entities/utils.ts | 9 +++++ 5 files changed, 55 insertions(+), 15 deletions(-) diff --git a/cli/template/src/__tests__/entities/utils.test.jsx b/cli/template/src/__tests__/entities/utils.test.jsx index 404bda54..783510cf 100644 --- a/cli/template/src/__tests__/entities/utils.test.jsx +++ b/cli/template/src/__tests__/entities/utils.test.jsx @@ -36,7 +36,10 @@ const diffBase = { }, after_unknown: { fff: {} - } + }, + replace_paths: [ + 'eee' + ] } describe('TerraformPlanResourceChangeFieldDiff', () => { @@ -185,12 +188,12 @@ describe('TerraformPlanResourceChangeChange', () => { it('getDiff', () => { const diff = Entities.Utils.TerraformPlanResourceChangeChange.getDiff(diffBase) - expect(diff.aaa).toStrictEqual({src: {value: 'aaa', type: 'string', sensitive: false}, dst: {value: 'aaa', type: 'string', sensitive: false}}) - expect(diff.bbb).toStrictEqual({src: {value: '(sensitive)', type: 'string', sensitive: true}, dst: {value: '(sensitive)', type: 'string', sensitive: true}}) - expect(diff.ccc).toStrictEqual({src: {value: 'ccc', type: 'string', sensitive: false}, dst: {value: 'eee', type: 'string', sensitive: false}}) - expect(diff.ddd).toStrictEqual({src: {value: '(sensitive)', type: 'string', sensitive: true}, dst: {value: '(sensitive)', type: 'string', sensitive: true}}) - expect(diff.eee).toStrictEqual({src: {}, dst: {value: 'zzz', sensitive: false, type: 'string'}}) - expect(diff.fff).toStrictEqual({src: {}, dst: {value: '(known after apply)', unknown_after: true}}) + expect(diff.aaa).toStrictEqual({forces_replacement: false, src: {value: 'aaa', type: 'string', sensitive: false}, dst: {value: 'aaa', type: 'string', sensitive: false}}) + expect(diff.bbb).toStrictEqual({forces_replacement: false, src: {value: '(sensitive)', type: 'string', sensitive: true}, dst: {value: '(sensitive)', type: 'string', sensitive: true}}) + expect(diff.ccc).toStrictEqual({forces_replacement: false, src: {value: 'ccc', type: 'string', sensitive: false}, dst: {value: 'eee', type: 'string', sensitive: false}}) + expect(diff.ddd).toStrictEqual({forces_replacement: false, src: {value: '(sensitive)', type: 'string', sensitive: true}, dst: {value: '(sensitive)', type: 'string', sensitive: true}}) + expect(diff.eee).toStrictEqual({forces_replacement: true, src: {}, dst: {value: 'zzz', sensitive: false, type: 'string'}}) + expect(diff.fff).toStrictEqual({forces_replacement: false, src: {}, dst: {value: '(known after apply)', unknown_after: true}}) expect(diff.multiline.src).toStrictEqual({value: '[\n 1,\n 2,\n 3,\n 4,\n 5\n]', type: 'string', sensitive: false}) expect(diff.multiline.dst).toStrictEqual({value: '[\n 5,\n 4,\n 3,\n 2,\n 1\n]', type: 'string', sensitive: false}) expect(diff.multiline.diff).toBeTruthy() diff --git a/cli/template/src/__tests__/plan.json b/cli/template/src/__tests__/plan.json index f6d9531a..2b834fef 100644 --- a/cli/template/src/__tests__/plan.json +++ b/cli/template/src/__tests__/plan.json @@ -629,7 +629,10 @@ ], "weighted_routing_policy": [] }, - "after_sensitive": false + "after_sensitive": false, + "replace_paths": [ + "records" + ] }, "action_reason": "delete_because_each_key" }, diff --git a/cli/template/src/components/focused-view/focused-view.tsx b/cli/template/src/components/focused-view/focused-view.tsx index d5b809d3..e29ea47b 100644 --- a/cli/template/src/components/focused-view/focused-view.tsx +++ b/cli/template/src/components/focused-view/focused-view.tsx @@ -2,7 +2,7 @@ import styles from '@app/components/focused-view/focused-view.module.css' import React, { useState } from 'react'; import capitalize from 'lodash/capitalize'; import { Entities } from '@app/data' -import { BsLink45Deg, BsCheckCircle, BsSlashCircle, BsHash } from 'react-icons/bs' +import { BsFillInfoSquareFill, BsLink45Deg, BsCheckCircle, BsSlashCircle, BsHash } from 'react-icons/bs' import { RiBracesLine, RiBracketsLine } from "react-icons/ri"; import { FaEquals, FaChevronRight } from 'react-icons/fa' @@ -14,6 +14,7 @@ import Col from 'react-bootstrap/Col' import ToggleButton from 'react-bootstrap/ToggleButton' import OverlayTrigger from 'react-bootstrap/OverlayTrigger' import Tooltip from 'react-bootstrap/Tooltip' +import Button from 'react-bootstrap/Button' interface Props { resource?: Entities.TerraformPlanResourceChange @@ -33,6 +34,7 @@ export const C = (props: Props) => { const diff = Entities.Utils.TerraformPlanResourceChangeChange.getDiff(resource.change) const actionAlias = Entities.Utils.TerraformPlanResourceChangeChange.getActionAlias(resource.change) const unchangedCount = Entities.Utils.TerraformPlanResourceChangeChangeDiff.getUnchangedFields(diff) + const reasonTooltip = resource.action_reason ? resource.action_reason.replaceAll('_', ' ') : null return ( @@ -42,10 +44,28 @@ export const C = (props: Props) => { - - + + + { resource.action_reason ? + ( + + {reasonTooltip}} + > + + + + ) : null + } + + + + - + @@ -79,7 +99,7 @@ const Actions = (props: ActionsProps) => { ) if (i !== actions.length - 1) { - actionElems.push( then ) + actionElems.push( then ) } } @@ -162,12 +182,14 @@ const ChangedField = (props: ChangedFieldProps) => { : + const fieldTitle = changes.forces_replacement ? `${field} (Forces replacement)`: field + return ( -
+
- + {fieldType} {field} diff --git a/cli/template/src/data/entities/entities.ts b/cli/template/src/data/entities/entities.ts index 84577c5e..311117d0 100644 --- a/cli/template/src/data/entities/entities.ts +++ b/cli/template/src/data/entities/entities.ts @@ -30,6 +30,7 @@ export interface TerraformPlan { export interface TerraformPlanResourceChange { address: string module_address?: string + action_reason?: string type: string name: string change: TerraformPlanResourceChangeChange @@ -42,6 +43,7 @@ export interface TerraformPlanResourceChangeChange { after: { [key: string]: unknown } | null after_sensitive: { [key: string]: unknown } | null after_unknown: { [key: string]: unknown } + replace_paths?: string[] } export enum TerraformPlanResourceChangeChangeAction { @@ -71,6 +73,7 @@ export interface TerraformPlanResourceChangeField { export interface TerraformPlanResourceChangeFieldDiff { src: TerraformPlanResourceChangeField dst: TerraformPlanResourceChangeField + forces_replacement: boolean diff?: Diff.ParsedDiff } diff --git a/cli/template/src/data/entities/utils.ts b/cli/template/src/data/entities/utils.ts index 4e7e6ed8..42cf8d0b 100644 --- a/cli/template/src/data/entities/utils.ts +++ b/cli/template/src/data/entities/utils.ts @@ -117,6 +117,7 @@ export const TerraformPlanResourceChangeChange = { diff[field] = { src: {} as Entities.TerraformPlanResourceChangeField, dst: {} as Entities.TerraformPlanResourceChangeField, + forces_replacement: false, } } @@ -134,6 +135,7 @@ export const TerraformPlanResourceChangeChange = { diff[field] = { src: {} as Entities.TerraformPlanResourceChangeField, dst: {} as Entities.TerraformPlanResourceChangeField, + forces_replacement: false, } } diff[field].dst = TerraformPlanResourceChangeField.setValueType( @@ -144,11 +146,18 @@ export const TerraformPlanResourceChangeChange = { } } + if (change.replace_paths) { + for (const field of change.replace_paths) { + diff[field].forces_replacement = true + } + } + for (const field of Object.keys(change.after_unknown)) { if (!diff[field]) { diff[field] = { src: {} as Entities.TerraformPlanResourceChangeField, dst: {} as Entities.TerraformPlanResourceChangeField, + forces_replacement: false, } } diff[field].dst.unknown_after = true