diff --git a/command/agent/alloc_endpoint.go b/command/agent/alloc_endpoint.go index 42d2d761d..5988ae69d 100644 --- a/command/agent/alloc_endpoint.go +++ b/command/agent/alloc_endpoint.go @@ -94,6 +94,7 @@ func (s *HTTPServer) allocGet(allocID string, resp http.ResponseWriter, req *htt } // Decode the payload if there is any + alloc := out.Alloc if alloc.Job != nil && len(alloc.Job.Payload) != 0 { decoded, err := snappy.Decode(nil, alloc.Job.Payload) @@ -105,6 +106,9 @@ func (s *HTTPServer) allocGet(allocID string, resp http.ResponseWriter, req *htt } alloc.SetEventDisplayMessages() + // Handle 0.12 ports upgrade path + alloc.AllocatedResources.Shared.Canonicalize() + return alloc, nil } diff --git a/nomad/structs/structs.go b/nomad/structs/structs.go index 3a77d15dc..0b87f77ea 100644 --- a/nomad/structs/structs.go +++ b/nomad/structs/structs.go @@ -3486,6 +3486,23 @@ func (a *AllocatedSharedResources) Subtract(delta *AllocatedSharedResources) { a.DiskMB -= delta.DiskMB } +func (a *AllocatedSharedResources) Canonicalize() { + if len(a.Networks) > 0 { + if len(a.Networks[0].DynamicPorts)+len(a.Networks[0].ReservedPorts) > 0 && len(a.Ports) == 0 { + for _, ports := range [][]Port{a.Networks[0].DynamicPorts, a.Networks[0].ReservedPorts} { + for _, p := range ports { + a.Ports = append(a.Ports, AllocatedPortMapping{ + Label: p.Label, + Value: p.Value, + To: p.To, + HostIP: a.Networks[0].IP, + }) + } + } + } + } +} + // AllocatedCpuResources captures the allocated CPU resources. type AllocatedCpuResources struct { CpuShares int64 diff --git a/nomad/structs/structs_test.go b/nomad/structs/structs_test.go index 94bbe1cb6..b48a5aeb3 100644 --- a/nomad/structs/structs_test.go +++ b/nomad/structs/structs_test.go @@ -5508,3 +5508,43 @@ func TestNodeResources_Merge(t *testing.T) { }, }, res) } + +func TestAllocatedSharedResources_Canonicalize(t *testing.T) { + a := &AllocatedSharedResources{ + Networks: []*NetworkResource{ + { + IP: "127.0.0.1", + DynamicPorts: []Port{ + { + Label: "http", + Value: 22222, + To: 8080, + }, + }, + ReservedPorts: []Port{ + { + Label: "redis", + Value: 6783, + To: 6783, + }, + }, + }, + }, + } + + a.Canonicalize() + require.Exactly(t, AllocatedPorts{ + { + Label: "http", + Value: 22222, + To: 8080, + HostIP: "127.0.0.1", + }, + { + Label: "redis", + Value: 6783, + To: 6783, + HostIP: "127.0.0.1", + }, + }, a.Ports) +} diff --git a/ui/app/controllers/allocations/allocation/index.js b/ui/app/controllers/allocations/allocation/index.js index e167cdbe6..d70f311a7 100644 --- a/ui/app/controllers/allocations/allocation/index.js +++ b/ui/app/controllers/allocations/allocation/index.js @@ -39,7 +39,10 @@ export default class IndexController extends Controller.extend(Sortable) { }) error; - @alias('model.allocatedResources.networks.firstObject') network; + @computed('model.allocatedResources.ports.@each.label') + get ports() { + return (this.get('model.allocatedResources.ports') || []).sortBy('label'); + } @computed('model.taskGroup.services.@each.name') get services() { diff --git a/ui/app/controllers/allocations/allocation/task/index.js b/ui/app/controllers/allocations/allocation/task/index.js index 994f0319f..6af893dff 100644 --- a/ui/app/controllers/allocations/allocation/task/index.js +++ b/ui/app/controllers/allocations/allocation/task/index.js @@ -1,7 +1,6 @@ import Controller from '@ember/controller'; import { computed } from '@ember/object'; import { computed as overridable } from 'ember-overridable-computed'; -import { alias } from '@ember/object/computed'; import { task } from 'ember-concurrency'; import classic from 'ember-classic-decorator'; @@ -18,26 +17,6 @@ export default class IndexController extends Controller { return this.otherTaskStates.filterBy('task.lifecycle'); } - @alias('model.resources.networks.firstObject') network; - - @computed('network.{reservedPorts.[],dynamicPorts.[]}') - get ports() { - return (this.get('network.reservedPorts') || []) - .map(port => ({ - name: port.Label, - port: port.Value, - isDynamic: false, - })) - .concat( - (this.get('network.dynamicPorts') || []).map(port => ({ - name: port.Label, - port: port.Value, - isDynamic: true, - })) - ) - .sortBy('name'); - } - @overridable(() => { // { title, description } return null; diff --git a/ui/app/models/port.js b/ui/app/models/port.js new file mode 100644 index 000000000..09888274e --- /dev/null +++ b/ui/app/models/port.js @@ -0,0 +1,9 @@ +import attr from 'ember-data/attr'; +import Fragment from 'ember-data-model-fragments/fragment'; + +export default class Port extends Fragment { + @attr('string') hostIp; + @attr('string') label; + @attr('number') to; + @attr('number') value; +} diff --git a/ui/app/models/resources.js b/ui/app/models/resources.js index 9d6082009..0cf455549 100644 --- a/ui/app/models/resources.js +++ b/ui/app/models/resources.js @@ -8,4 +8,5 @@ export default class Resources extends Fragment { @attr('number') disk; @attr('number') iops; @fragmentArray('network', { defaultValue: () => [] }) networks; + @fragmentArray('port', { defaultValue: () => [] }) ports; } diff --git a/ui/app/serializers/port.js b/ui/app/serializers/port.js new file mode 100644 index 000000000..fd3681fa9 --- /dev/null +++ b/ui/app/serializers/port.js @@ -0,0 +1,18 @@ +import ApplicationSerializer from './application'; +import isIp from 'is-ip'; + +export default class PortSerializer extends ApplicationSerializer { + attrs = { + hostIp: 'HostIP', + }; + + normalize(typeHash, hash) { + const ip = hash.HostIP; + + if (isIp.v6(ip)) { + hash.HostIP = `[${ip}]`; + } + + return super.normalize(...arguments); + } +} diff --git a/ui/app/serializers/resources.js b/ui/app/serializers/resources.js index 43c9e23b7..4239a354b 100644 --- a/ui/app/serializers/resources.js +++ b/ui/app/serializers/resources.js @@ -7,4 +7,9 @@ export default class ResourcesSerializer extends ApplicationSerializer { disk: 'DiskMB', iops: 'IOPS', }; + + normalize(typeHash, hash) { + hash.Ports = hash.Ports || []; + return super.normalize(typeHash, hash); + } } diff --git a/ui/app/templates/allocations/allocation/index.hbs b/ui/app/templates/allocations/allocation/index.hbs index 11b9df8a9..f88059deb 100644 --- a/ui/app/templates/allocations/allocation/index.hbs +++ b/ui/app/templates/allocations/allocation/index.hbs @@ -109,7 +109,6 @@