diff --git a/client/app/scripts/components/node-details/node-details-control-button.js b/client/app/scripts/components/node-details/node-details-control-button.js
index 23323f575..8bca5fbb3 100644
--- a/client/app/scripts/components/node-details/node-details-control-button.js
+++ b/client/app/scripts/components/node-details/node-details-control-button.js
@@ -1,5 +1,6 @@
import React from 'react';
import { connect } from 'react-redux';
+import { isEmpty } from 'lodash';
import classNames from 'classnames';
import { trackAnalyticsEvent } from '../../utils/tracking-utils';
@@ -25,9 +26,11 @@ class NodeDetailsControlButton extends React.Component {
handleClick(ev) {
ev.preventDefault();
- const { id, human } = this.props.control;
+ const { id, human, confirmation } = this.props.control;
trackAnalyticsEvent('scope.node.control.click', { id, title: human });
- this.props.dispatch(doControl(this.props.nodeId, this.props.control));
+ if (isEmpty(confirmation) || window.confirm(confirmation)) { // eslint-disable-line no-alert
+ this.props.dispatch(doControl(this.props.nodeId, this.props.control));
+ }
}
}
diff --git a/client/app/scripts/components/node-details/node-details-controls.js b/client/app/scripts/components/node-details/node-details-controls.js
index edb9029ec..41e08794f 100644
--- a/client/app/scripts/components/node-details/node-details-controls.js
+++ b/client/app/scripts/components/node-details/node-details-controls.js
@@ -22,11 +22,14 @@ export default function NodeDetailsControls({
}
- {sortBy(controls, 'rank').map(control => ())}
+ {sortBy(controls, 'rank').map(control => (
+
+ ))}
{controls && }
diff --git a/probe/kubernetes/reporter.go b/probe/kubernetes/reporter.go
index 2be582e08..e56b3ad0c 100644
--- a/probe/kubernetes/reporter.go
+++ b/probe/kubernetes/reporter.go
@@ -538,10 +538,11 @@ func (r *Reporter) podTopology(services []Service, deployments []Deployment, dae
Rank: 0,
})
pods.Controls.AddControl(report.Control{
- ID: DeletePod,
- Human: "Delete",
- Icon: "far fa-trash-alt",
- Rank: 1,
+ ID: DeletePod,
+ Human: "Delete",
+ Icon: "far fa-trash-alt",
+ Confirmation: "Are you sure you want to delete this pod?",
+ Rank: 1,
})
for _, service := range services {
selectors = append(selectors, match(
diff --git a/render/detailed/node.go b/render/detailed/node.go
index 459cc593f..7b8b29164 100644
--- a/render/detailed/node.go
+++ b/render/detailed/node.go
@@ -41,24 +41,26 @@ func (*ControlInstance) UnmarshalJSON(b []byte) error {
}
type wiredControlInstance struct {
- ProbeID string `json:"probeId"`
- NodeID string `json:"nodeId"`
- ID string `json:"id"`
- Human string `json:"human"`
- Icon string `json:"icon"`
- Rank int `json:"rank"`
+ ProbeID string `json:"probeId"`
+ NodeID string `json:"nodeId"`
+ ID string `json:"id"`
+ Human string `json:"human"`
+ Icon string `json:"icon"`
+ Confirmation string `json:"confirmation,omitempty"`
+ Rank int `json:"rank"`
}
// CodecEncodeSelf marshals this ControlInstance. It takes the basic Metric
// rendering, then adds some row-specific fields.
func (c *ControlInstance) CodecEncodeSelf(encoder *codec.Encoder) {
encoder.Encode(wiredControlInstance{
- ProbeID: c.ProbeID,
- NodeID: c.NodeID,
- ID: c.Control.ID,
- Human: c.Control.Human,
- Icon: c.Control.Icon,
- Rank: c.Control.Rank,
+ ProbeID: c.ProbeID,
+ NodeID: c.NodeID,
+ ID: c.Control.ID,
+ Human: c.Control.Human,
+ Icon: c.Control.Icon,
+ Confirmation: c.Control.Confirmation,
+ Rank: c.Control.Rank,
})
}
@@ -70,10 +72,11 @@ func (c *ControlInstance) CodecDecodeSelf(decoder *codec.Decoder) {
ProbeID: in.ProbeID,
NodeID: in.NodeID,
Control: report.Control{
- ID: in.ID,
- Human: in.Human,
- Icon: in.Icon,
- Rank: in.Rank,
+ ID: in.ID,
+ Human: in.Human,
+ Icon: in.Icon,
+ Confirmation: in.Confirmation,
+ Rank: in.Rank,
},
}
}
diff --git a/report/controls.go b/report/controls.go
index f534de5dd..dcf5cb3a6 100644
--- a/report/controls.go
+++ b/report/controls.go
@@ -12,10 +12,11 @@ type Controls map[string]Control
// A Control basically describes an RPC
type Control struct {
- ID string `json:"id"`
- Human string `json:"human"`
- Icon string `json:"icon"` // from https://fortawesome.github.io/Font-Awesome/cheatsheet/ please
- Rank int `json:"rank"`
+ ID string `json:"id"`
+ Human string `json:"human"`
+ Icon string `json:"icon"` // from https://fortawesome.github.io/Font-Awesome/cheatsheet/ please
+ Confirmation string `json:"confirmation,omitempty"`
+ Rank int `json:"rank"`
}
// Merge merges other with cs, returning a fresh Controls.