mirror of
https://github.com/kemko/nomad.git
synced 2026-01-04 17:35:43 +03:00
Merge pull request #10755 from hashicorp/f-ui/nomad-agent-version
Closes Nomad UI showing 'vUnknown' #10672
This commit is contained in:
@@ -39,7 +39,12 @@ export default class SystemService extends Service {
|
||||
.authorizedRawRequest(`/${namespace}/agent/self`)
|
||||
.then(jsonWithDefault({}))
|
||||
.then(agent => {
|
||||
agent.version = agent.member?.Tags?.build || 'Unknown';
|
||||
if (agent?.config?.Version) {
|
||||
const { Version, VersionPrerelease, VersionMetadata } = agent.config.Version;
|
||||
agent.version = Version;
|
||||
if (VersionPrerelease) agent.version = `${agent.version}-${VersionPrerelease}`;
|
||||
if (VersionMetadata) agent.version = `${agent.version}+${VersionMetadata}`;
|
||||
}
|
||||
return agent;
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -68,9 +68,11 @@
|
||||
<li><LinkTo @route="topology" @activeClass="is-active" data-test-gutter-link="topology">Topology</LinkTo></li>
|
||||
</ul>
|
||||
</aside>
|
||||
{{#if this.system.agent.version}}
|
||||
<footer class="gutter-footer">
|
||||
<span class="is-faded">v{{this.system.agent.version}}</span>
|
||||
<span class="is-faded">v{{this.system.agent.version}}</span>
|
||||
</footer>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
<div data-test-page-content class="page-column is-right">
|
||||
|
||||
@@ -9,7 +9,7 @@ import formatHost from 'nomad-ui/utils/format-host';
|
||||
|
||||
export function findLeader(schema) {
|
||||
const agent = schema.agents.first();
|
||||
return formatHost(agent.address, agent.tags.port);
|
||||
return formatHost(agent.member.Address, agent.member.Tags.port);
|
||||
}
|
||||
|
||||
export function filesForPath(allocFiles, filterPath) {
|
||||
@@ -335,14 +335,12 @@ export default function() {
|
||||
const firstRegion = regions.first();
|
||||
return {
|
||||
ServerRegion: firstRegion ? firstRegion.id : null,
|
||||
Members: this.serialize(agents.all()),
|
||||
Members: this.serialize(agents.all()).map(({ member }) => ({ ...member })),
|
||||
};
|
||||
});
|
||||
|
||||
this.get('/agent/self', function({ agents }) {
|
||||
return {
|
||||
member: this.serialize(agents.first()),
|
||||
};
|
||||
return agents.first();
|
||||
});
|
||||
|
||||
this.get('/agent/monitor', function({ agents, nodes }, { queryParams }) {
|
||||
@@ -579,7 +577,10 @@ export default function() {
|
||||
});
|
||||
});
|
||||
|
||||
this.post('/search/fuzzy', function( { allocations, jobs, nodes, taskGroups, csiPlugins }, { requestBody }) {
|
||||
this.post('/search/fuzzy', function(
|
||||
{ allocations, jobs, nodes, taskGroups, csiPlugins },
|
||||
{ requestBody }
|
||||
) {
|
||||
const { Text } = JSON.parse(requestBody);
|
||||
|
||||
const matchedAllocs = allocations.where(allocation => allocation.name.includes(Text));
|
||||
@@ -590,33 +591,22 @@ export default function() {
|
||||
|
||||
const transformedAllocs = matchedAllocs.models.map(alloc => ({
|
||||
ID: alloc.name,
|
||||
Scope: [
|
||||
(alloc.namespace || {}).id,
|
||||
alloc.id,
|
||||
],
|
||||
Scope: [(alloc.namespace || {}).id, alloc.id],
|
||||
}));
|
||||
|
||||
const transformedGroups = matchedGroups.models.map(group => ({
|
||||
ID: group.name,
|
||||
Scope: [
|
||||
group.job.namespace,
|
||||
group.job.id,
|
||||
],
|
||||
Scope: [group.job.namespace, group.job.id],
|
||||
}));
|
||||
|
||||
const transformedJobs = matchedJobs.models.map(job => ({
|
||||
ID: job.name,
|
||||
Scope: [
|
||||
job.namespace,
|
||||
job.id,
|
||||
]
|
||||
Scope: [job.namespace, job.id],
|
||||
}));
|
||||
|
||||
const transformedNodes = matchedNodes.models.map(node => ({
|
||||
ID: node.name,
|
||||
Scope: [
|
||||
node.id,
|
||||
],
|
||||
Scope: [node.id],
|
||||
}));
|
||||
|
||||
const transformedPlugins = matchedPlugins.models.map(plugin => ({
|
||||
@@ -644,7 +634,7 @@ export default function() {
|
||||
nodes: truncatedNodes.length < transformedNodes.length,
|
||||
plugins: truncatedPlugins.length < transformedPlugins.length,
|
||||
},
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
this.get('/recommendations', function(
|
||||
|
||||
@@ -8,20 +8,41 @@ const AGENT_STATUSES = ['alive', 'leaving', 'left', 'failed'];
|
||||
|
||||
export default Factory.extend({
|
||||
id: i => (i / 100 >= 1 ? `${UUIDS[i]}-${i}` : UUIDS[i]),
|
||||
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 }),
|
||||
name: () => generateName(),
|
||||
|
||||
address() {
|
||||
return this.name.split('@')[1];
|
||||
config: {
|
||||
Version: {
|
||||
Version: '1.1.0',
|
||||
VersionMetadata: 'ent',
|
||||
VersionPrerelease: 'dev',
|
||||
},
|
||||
},
|
||||
|
||||
tags() {
|
||||
const rpcPortCandidate = faker.random.number({ min: 4000, max: 4999 });
|
||||
member() {
|
||||
const serfPort = faker.random.number({ min: 4000, max: 4999 });
|
||||
return {
|
||||
port: rpcPortCandidate === this.serfPort ? rpcPortCandidate + 1 : rpcPortCandidate,
|
||||
dc: faker.helpers.randomize(DATACENTERS),
|
||||
Name: this.name,
|
||||
Port: serfPort,
|
||||
Status: faker.helpers.randomize(AGENT_STATUSES),
|
||||
Address: generateAddress(this.name),
|
||||
Tags: generateTags(serfPort),
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
function generateName() {
|
||||
return `nomad@${faker.random.boolean() ? faker.internet.ip() : faker.internet.ipv6()}`;
|
||||
}
|
||||
|
||||
function generateAddress(name) {
|
||||
return name.split('@')[1];
|
||||
}
|
||||
|
||||
function generateTags(serfPort) {
|
||||
const rpcPortCandidate = faker.random.number({ min: 4000, max: 4999 });
|
||||
return {
|
||||
port: rpcPortCandidate === serfPort ? rpcPortCandidate + 1 : rpcPortCandidate,
|
||||
dc: faker.helpers.randomize(DATACENTERS),
|
||||
};
|
||||
}
|
||||
|
||||
10
ui/mirage/serializers/agent.js
Normal file
10
ui/mirage/serializers/agent.js
Normal file
@@ -0,0 +1,10 @@
|
||||
import ApplicationSerializer from './application';
|
||||
|
||||
export default ApplicationSerializer.extend({
|
||||
keyForAttribute(str) {
|
||||
if (str === 'config' || str === 'member') {
|
||||
return str;
|
||||
}
|
||||
return ApplicationSerializer.prototype.keyForAttribute.apply(this, arguments);
|
||||
},
|
||||
});
|
||||
@@ -33,14 +33,16 @@ 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(formatHost(agent.address, agent.tags.port)));
|
||||
assert.ok(ServerDetail.datacenter.includes(agent.tags.dc));
|
||||
assert.ok(ServerDetail.serverStatus.includes(agent.member.Status));
|
||||
assert.ok(
|
||||
ServerDetail.address.includes(formatHost(agent.member.Address, agent.member.Tags.port))
|
||||
);
|
||||
assert.ok(ServerDetail.datacenter.includes(agent.member.Tags.dc));
|
||||
});
|
||||
|
||||
test('the server detail page should list all tags for the server', async function(assert) {
|
||||
const tags = Object.keys(agent.tags)
|
||||
.map(name => ({ name, value: agent.tags[name] }))
|
||||
const tags = Object.keys(agent.member.Tags)
|
||||
.map(name => ({ name, value: agent.member.Tags[name] }))
|
||||
.sortBy('name');
|
||||
|
||||
assert.equal(ServerDetail.tags.length, tags.length, '# of tags');
|
||||
|
||||
@@ -13,9 +13,9 @@ const minimumSetup = () => {
|
||||
};
|
||||
|
||||
const agentSort = leader => (a, b) => {
|
||||
if (formatHost(a.address, a.tags.port) === leader) {
|
||||
if (formatHost(a.member.Address, a.member.Tags.port) === leader) {
|
||||
return 1;
|
||||
} else if (formatHost(b.address, b.tags.port) === leader) {
|
||||
} else if (formatHost(b.member.Address, b.member.Tags.port) === leader) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
@@ -58,11 +58,11 @@ module('Acceptance | servers list', function(hooks) {
|
||||
const agentRow = ServersList.servers.objectAt(0);
|
||||
|
||||
assert.equal(agentRow.name, agent.name, 'Name');
|
||||
assert.equal(agentRow.status, agent.status, 'Status');
|
||||
assert.equal(agentRow.status, agent.member.Status, 'Status');
|
||||
assert.equal(agentRow.leader, 'True', 'Leader?');
|
||||
assert.equal(agentRow.address, agent.address, 'Address');
|
||||
assert.equal(agentRow.serfPort, agent.serfPort, 'Serf Port');
|
||||
assert.equal(agentRow.datacenter, agent.tags.dc, 'Datacenter');
|
||||
assert.equal(agentRow.address, agent.member.Address, 'Address');
|
||||
assert.equal(agentRow.serfPort, agent.member.Port, 'Serf Port');
|
||||
assert.equal(agentRow.datacenter, agent.member.Tags.dc, 'Datacenter');
|
||||
});
|
||||
|
||||
test('each server should link to the server detail page', async function(assert) {
|
||||
|
||||
Reference in New Issue
Block a user