Remove deprecated 'authority' references from tap form (#13850)

PR #13578 removes 'authority' from being a pseudo-k8s resource, but the
viz web `/tap` form still expects it to be present, issuing a
`/api/tps-reports?resource_type=authority&all_namespaces=true` call, which
returns 500 `cannot find Kubernetes canonical name from friendly name [authority]`,
breaking the form entirely.

This change removes all references to authorities in the form,
restoring functionality.

This was validated against a edge-25.3.3 linkerd/linkerd-viz install by
performing a successful tap with the new code in the web UI.

Fixes #13841

Signed-off-by: Stephen Muth <smuth4@gmail.com>
This commit is contained in:
Stephen Muth 2025-03-24 12:24:11 -04:00 committed by GitHub
parent 38ec59128e
commit fc7f415e47
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 4 additions and 45 deletions

View File

@ -34,7 +34,6 @@ class Tap extends React.Component {
tapResultsById: this.tapResultsById, tapResultsById: this.tapResultsById,
error: null, error: null,
resourcesByNs: {}, resourcesByNs: {},
authoritiesByNs: {},
query: { query: {
resource: '', resource: '',
namespace: '', namespace: '',
@ -43,7 +42,6 @@ class Tap extends React.Component {
method: '', method: '',
path: '', path: '',
scheme: '', scheme: '',
authority: '',
maxRps: '', maxRps: '',
}, },
maxLinesToDisplay: 40, maxLinesToDisplay: 40,
@ -269,15 +267,12 @@ class Tap extends React.Component {
}); });
const url = this.api.urlsForResourceNoStats('all'); const url = this.api.urlsForResourceNoStats('all');
const authorityUrl = this.api.urlsForResource('authority'); this.api.setCurrentRequests([this.api.fetchMetrics(url)]);
this.api.setCurrentRequests([this.api.fetchMetrics(url), this.api.fetchMetrics(authorityUrl)]);
Promise.all(this.api.getCurrentPromises()) Promise.all(this.api.getCurrentPromises())
.then(rsp => { .then(rsp => {
const { resourcesByNs } = groupResourcesByNs(rsp[0]); const { resourcesByNs } = groupResourcesByNs(rsp[0]);
const { authoritiesByNs } = groupResourcesByNs(rsp[1]);
this.setState({ this.setState({
resourcesByNs, resourcesByNs,
authoritiesByNs,
pendingRequests: false, pendingRequests: false,
}); });
}) })
@ -292,7 +287,7 @@ class Tap extends React.Component {
}; };
render() { render() {
const { tapResultsById, tapRequestInProgress, tapIsClosing, resourcesByNs, authoritiesByNs, query, showTapEnabledWarning, error } = this.state; const { tapResultsById, tapRequestInProgress, tapIsClosing, resourcesByNs, query, showTapEnabledWarning, error } = this.state;
const tableRows = _orderBy(_values(tapResultsById), r => r.lastUpdated, 'desc'); const tableRows = _orderBy(_values(tapResultsById), r => r.lastUpdated, 'desc');
return ( return (
@ -308,7 +303,6 @@ class Tap extends React.Component {
handleTapStop={this.handleTapStop} handleTapStop={this.handleTapStop}
handleTapClear={this.handleTapClear} handleTapClear={this.handleTapClear}
resourcesByNs={resourcesByNs} resourcesByNs={resourcesByNs}
authoritiesByNs={authoritiesByNs}
updateQuery={this.updateQuery} updateQuery={this.updateQuery}
currentQuery={query} /> currentQuery={query} />
{showTapEnabledWarning && {showTapEnabledWarning &&

View File

@ -97,21 +97,17 @@ class TapQueryForm extends React.Component {
static getDerivedStateFromProps(props, state) { static getDerivedStateFromProps(props, state) {
if (!_isEqual(props.resourcesByNs, state.resourcesByNs)) { if (!_isEqual(props.resourcesByNs, state.resourcesByNs)) {
const resourcesByNs = props.resourcesByNs; const resourcesByNs = props.resourcesByNs;
const authoritiesByNs = props.authoritiesByNs;
const namespaces = Object.keys(resourcesByNs).sort(); const namespaces = Object.keys(resourcesByNs).sort();
const resourceNames = getResourceList(resourcesByNs, state.query.namespace); const resourceNames = getResourceList(resourcesByNs, state.query.namespace);
const toResourceNames = getResourceList(resourcesByNs, state.query.toNamespace); const toResourceNames = getResourceList(resourcesByNs, state.query.toNamespace);
const authorities = getResourceList(authoritiesByNs, state.query.namespace);
return _merge(state, { return _merge(state, {
resourcesByNs, resourcesByNs,
authoritiesByNs,
autocomplete: { autocomplete: {
namespace: namespaces, namespace: namespaces,
resource: resourceNames, resource: resourceNames,
toNamespace: namespaces, toNamespace: namespaces,
toResource: toResourceNames, toResource: toResourceNames,
authority: authorities,
}, },
}); });
} else { } else {
@ -133,20 +129,18 @@ class TapQueryForm extends React.Component {
this.state = { this.state = {
query, query,
advancedFormExpanded, advancedFormExpanded,
authoritiesByNs: {},
resourcesByNs: {}, resourcesByNs: {},
autocomplete: { autocomplete: {
namespace: [], namespace: [],
resource: [], resource: [],
toNamespace: [], toNamespace: [],
toResource: [], toResource: [],
authority: [],
}, },
}; };
} }
handleFormChange = (name, scopeResource) => { handleFormChange = (name, scopeResource) => {
const { query, autocomplete, resourcesByNs, authoritiesByNs } = this.state; const { query, autocomplete, resourcesByNs } = this.state;
const { updateQuery } = this.props; const { updateQuery } = this.props;
const state = { const state = {
@ -154,7 +148,6 @@ class TapQueryForm extends React.Component {
autocomplete, autocomplete,
}; };
const shouldScopeAuthority = name === 'namespace';
const newQueryValues = {}; const newQueryValues = {};
return event => { return event => {
@ -169,10 +162,6 @@ class TapQueryForm extends React.Component {
newQueryValues[scopeResource] = `namespace/${formVal}`; newQueryValues[scopeResource] = `namespace/${formVal}`;
} }
if (shouldScopeAuthority) {
state.autocomplete.authority = authoritiesByNs[formVal];
}
this.setState(state); this.setState(state);
updateQuery(state.query); updateQuery(state.query);
this.handleUrlUpdate(newQueryValues); this.handleUrlUpdate(newQueryValues);
@ -320,7 +309,7 @@ class TapQueryForm extends React.Component {
}; };
renderAdvancedTapFormContent() { renderAdvancedTapFormContent() {
const { autocomplete, query } = this.state; const { query } = this.state;
const { classes } = this.props; const { classes } = this.props;
return ( return (
@ -339,29 +328,6 @@ class TapQueryForm extends React.Component {
</Grid> </Grid>
</Grid> </Grid>
<Grid container spacing={3}>
<Grid item xs={6} md={3} classes={{ item: classes.formControlWrapper }}>
<FormControl className={classes.formControl}>
<InputLabel htmlFor="authority"><Trans>formAuthority</Trans></InputLabel>
<Select
value={query.authority}
onChange={this.handleFormChange('authority')}
inputProps={{ name: 'authority', id: 'authority' }}
className={classes.selectEmpty}>
{
_map(autocomplete.authority, (d, i) => (
<MenuItem key={`authority-${i}`} value={d}>{d}</MenuItem>
))
}
</Select>
<FormHelperText><Trans>formAuthorityHelpText</Trans></FormHelperText>
</FormControl>
</Grid>
<Grid item xs={6} md={3} className={classes.formControlWrapper}>
{this.renderTextInput(<Trans>formPath</Trans>, 'path', <Trans>formPathHelpText</Trans>)}
</Grid>
</Grid>
<Grid container spacing={3}> <Grid container spacing={3}>
<Grid item xs={6} md={3} className={classes.formControlWrapper}> <Grid item xs={6} md={3} className={classes.formControlWrapper}>
{this.renderTextInput(<Trans>formScheme</Trans>, 'scheme', <Trans>formSchemeHelpText</Trans>)} {this.renderTextInput(<Trans>formScheme</Trans>, 'scheme', <Trans>formSchemeHelpText</Trans>)}
@ -449,7 +415,6 @@ class TapQueryForm extends React.Component {
} }
TapQueryForm.propTypes = { TapQueryForm.propTypes = {
authoritiesByNs: PropTypes.shape({}).isRequired,
cmdName: PropTypes.string.isRequired, cmdName: PropTypes.string.isRequired,
currentQuery: tapQueryPropType.isRequired, currentQuery: tapQueryPropType.isRequired,
enableAdvancedForm: PropTypes.bool, enableAdvancedForm: PropTypes.bool,