ui: Fix server list leader determination for IPv6 (#10530)

This closes #10513, thanks to @bastelfreak for the report.
GET /status/leader returns an IPv6 host with square brackets
around the IP address as expected, but the rpcAddr property
on the agent model does not.

This fixes rpcAddr, updates the Mirage /status/leader mock
to properly format an IPv6 host, and changes the agent
factory to sometimes produce IPv6 addresses.

I added a formatHost utility function to centralise the
conditional square bracket-wrapping that would have
otherwise been further scattered around.
This commit is contained in:
Buck Doyle 2021-05-13 12:29:51 -05:00 committed by GitHub
parent c8ec7aa642
commit 7b42bb0e2d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 25 additions and 11 deletions

View file

@ -3,6 +3,7 @@ import { computed } from '@ember/object';
import Model from '@ember-data/model';
import { attr } from '@ember-data/model';
import classic from 'ember-classic-decorator';
import formatHost from 'nomad-ui/utils/format-host';
@classic
export default class Agent extends Model {
@ -20,7 +21,7 @@ export default class Agent extends Model {
@computed('address', 'port')
get rpcAddr() {
const { address, rpcPort } = this;
return address && rpcPort && `${address}:${rpcPort}`;
return formatHost(address, rpcPort);
}
@computed('rpcAddr', 'system.leader.rpcAddr')

View file

@ -0,0 +1,13 @@
import isIp from 'is-ip';
export default function formatHost(address, port) {
if (!address || !port) {
return undefined;
}
if (isIp.v6(address)) {
return `[${address}]:${port}`;
} else {
return `${address}:${port}`;
}
}

View file

@ -5,10 +5,11 @@ import { logFrames, logEncode } from './data/logs';
import { generateDiff } from './factories/job-version';
import { generateTaskGroupFailures } from './factories/evaluation';
import { copy } from 'ember-copy';
import formatHost from 'nomad-ui/utils/format-host';
export function findLeader(schema) {
const agent = schema.agents.first();
return `${agent.address}:${agent.tags.port}`;
return formatHost(agent.address, agent.tags.port);
}
export function filesForPath(allocFiles, filterPath) {

View file

@ -8,7 +8,7 @@ const AGENT_STATUSES = ['alive', 'leaving', 'left', 'failed'];
export default Factory.extend({
id: i => (i / 100 >= 1 ? `${UUIDS[i]}-${i}` : UUIDS[i]),
name: () => `nomad@${faker.internet.ip()}`,
name: () => `nomad@${faker.random.boolean() ? faker.internet.ip() : faker.internet.ipv6()}`,
status: () => faker.helpers.randomize(AGENT_STATUSES),
serfPort: () => faker.random.number({ min: 4000, max: 4999 }),

View file

@ -7,7 +7,7 @@ import { setupMirage } from 'ember-cli-mirage/test-support';
import a11yAudit from 'nomad-ui/tests/helpers/a11y-audit';
import Allocation from 'nomad-ui/tests/pages/allocations/detail';
import moment from 'moment';
import isIp from 'is-ip';
import formatHost from 'nomad-ui/utils/format-host';
let job;
let node;
@ -223,10 +223,7 @@ module('Acceptance | allocation detail', function(hooks) {
assert.equal(renderedPort.name, serverPort.Label);
assert.equal(renderedPort.to, serverPort.To);
const expectedAddr = isIp.v6(serverPort.HostIP)
? `[${serverPort.HostIP}]:${serverPort.Value}`
: `${serverPort.HostIP}:${serverPort.Value}`;
assert.equal(renderedPort.address, expectedAddr);
assert.equal(renderedPort.address, formatHost(serverPort.HostIP, serverPort.Value));
});
});

View file

@ -4,6 +4,7 @@ import { setupApplicationTest } from 'ember-qunit';
import { setupMirage } from 'ember-cli-mirage/test-support';
import a11yAudit from 'nomad-ui/tests/helpers/a11y-audit';
import ServerDetail from 'nomad-ui/tests/pages/servers/detail';
import formatHost from 'nomad-ui/utils/format-host';
let agent;
@ -33,7 +34,7 @@ module('Acceptance | server detail', function(hooks) {
test('the details ribbon displays basic information about the server', async function(assert) {
assert.ok(ServerDetail.serverStatus.includes(agent.status));
assert.ok(ServerDetail.address.includes(`${agent.address}:${agent.tags.port}`));
assert.ok(ServerDetail.address.includes(formatHost(agent.address, agent.tags.port)));
assert.ok(ServerDetail.datacenter.includes(agent.tags.dc));
});

View file

@ -5,6 +5,7 @@ import { setupMirage } from 'ember-cli-mirage/test-support';
import a11yAudit from 'nomad-ui/tests/helpers/a11y-audit';
import { findLeader } from '../../mirage/config';
import ServersList from 'nomad-ui/tests/pages/servers/list';
import formatHost from 'nomad-ui/utils/format-host';
const minimumSetup = () => {
server.createList('node', 1);
@ -12,9 +13,9 @@ const minimumSetup = () => {
};
const agentSort = leader => (a, b) => {
if (`${a.address}:${a.tags.port}` === leader) {
if (formatHost(a.address, a.tags.port) === leader) {
return 1;
} else if (`${b.address}:${b.tags.port}` === leader) {
} else if (formatHost(b.address, b.tags.port) === leader) {
return -1;
}
return 0;