cli: display group ports and address in alloc status command output (#6189)

* cli: display group ports and address in alloc status command output

* add assertions for port.To = -1 case and convert assertions to testify
This commit is contained in:
Nick Ethier
2019-08-27 23:59:36 -04:00
committed by GitHub
parent 51750f5732
commit f631ec6c2d
4 changed files with 71 additions and 46 deletions

View File

@@ -99,7 +99,6 @@ type NetworkResource struct {
MBits *int
ReservedPorts []Port
DynamicPorts []Port
Services []*Service
}
func (n *NetworkResource) Canonicalize() {
@@ -108,6 +107,14 @@ func (n *NetworkResource) Canonicalize() {
}
}
func (n *NetworkResource) HasPorts() bool {
if n == nil {
return false
}
return len(n.ReservedPorts)+len(n.DynamicPorts) > 0
}
// NodeDeviceResource captures a set of devices sharing a common
// vendor/type/device_name tuple.
type NodeDeviceResource struct {

View File

@@ -191,6 +191,11 @@ func (c *AllocStatusCommand) Run(args []string) int {
}
c.Ui.Output(output)
if len(alloc.AllocatedResources.Shared.Networks) > 0 && alloc.AllocatedResources.Shared.Networks[0].HasPorts() {
c.Ui.Output("")
c.Ui.Output(formatAllocNetworkInfo(alloc))
}
if short {
c.shortTaskStatus(alloc)
} else {
@@ -299,6 +304,32 @@ func formatAllocBasicInfo(alloc *api.Allocation, client *api.Client, uuidLength
return formatKV(basic), nil
}
func formatAllocNetworkInfo(alloc *api.Allocation) string {
nw := alloc.AllocatedResources.Shared.Networks[0]
addrs := make([]string, len(nw.DynamicPorts)+len(nw.ReservedPorts)+1)
addrs[0] = "Label|Dynamic|Address"
portFmt := func(port *api.Port, dyn string) string {
s := fmt.Sprintf("%s|%s|%s:%d", port.Label, dyn, nw.IP, port.Value)
if port.To > 0 {
s += fmt.Sprintf(" -> %d", port.To)
}
return s
}
for idx, port := range nw.DynamicPorts {
addrs[idx+1] = portFmt(&port, "yes")
}
for idx, port := range nw.ReservedPorts {
addrs[idx+1+len(nw.DynamicPorts)] = portFmt(&port, "yes")
}
var mode string
if nw.Mode != "" {
mode = fmt.Sprintf(" (mode = %q)", nw.Mode)
}
return fmt.Sprintf("Allocation Addresses%s\n%s", mode, formatList(addrs))
}
// futureEvalTimePretty returns when the eval is eligible to reschedule
// relative to current time, based on the WaitUntil field
func futureEvalTimePretty(evalID string, client *api.Client) string {

View File

@@ -286,6 +286,7 @@ func (idx *NetworkIndex) AssignNetwork(ask *NetworkResource) (out *NetworkResour
// Create the offer
offer := &NetworkResource{
Mode: ask.Mode,
Device: n.Device,
IP: ipStr,
MBits: ask.MBits,
@@ -312,6 +313,12 @@ func (idx *NetworkIndex) AssignNetwork(ask *NetworkResource) (out *NetworkResour
BUILD_OFFER:
for i, port := range dynPorts {
offer.DynamicPorts[i].Value = port
// This syntax allows you to set the mapped to port to the same port
// allocated by the scheduler on the host.
if offer.DynamicPorts[i].To == -1 {
offer.DynamicPorts[i].To = port
}
}
// Stop, we have an offer!

View File

@@ -5,6 +5,8 @@ import (
"net"
"reflect"
"testing"
"github.com/stretchr/testify/require"
)
func TestNetworkIndex_Overcommitted(t *testing.T) {
@@ -252,42 +254,30 @@ func TestNetworkIndex_AssignNetwork(t *testing.T) {
ReservedPorts: []Port{{"main", 8000, 0}},
}
offer, err := idx.AssignNetwork(ask)
if err != nil {
t.Fatalf("err: %v", err)
}
if offer == nil {
t.Fatalf("bad")
}
if offer.IP != "192.168.0.101" {
t.Fatalf("bad: %#v", offer)
}
require.NoError(t, err)
require.NotNil(t, offer)
require.Equal(t, "192.168.0.101", offer.IP)
rp := Port{"main", 8000, 0}
if len(offer.ReservedPorts) != 1 || offer.ReservedPorts[0] != rp {
t.Fatalf("bad: %#v", offer)
}
require.Len(t, offer.ReservedPorts, 1)
require.Exactly(t, rp, offer.ReservedPorts[0])
// Ask for dynamic ports
ask = &NetworkResource{
DynamicPorts: []Port{{"http", 0, 80}, {"https", 0, 443}, {"admin", 0, 8080}},
DynamicPorts: []Port{{"http", 0, 80}, {"https", 0, 443}, {"admin", 0, -1}},
}
offer, err = idx.AssignNetwork(ask)
if err != nil {
t.Fatalf("err: %v", err)
}
if offer == nil {
t.Fatalf("bad")
}
if offer.IP != "192.168.0.100" {
t.Fatalf("bad: %#v", offer)
}
if len(offer.DynamicPorts) != 3 {
t.Fatalf("There should be three dynamic ports")
}
require.NoError(t, err)
require.NotNil(t, offer)
require.Equal(t, "192.168.0.100", offer.IP)
require.Len(t, offer.DynamicPorts, 3)
var adminPort Port
for _, port := range offer.DynamicPorts {
if port.Value == 0 {
t.Fatalf("Dynamic Port: %v should have been assigned a host port", port.Label)
require.NotZero(t, port.Value)
if port.Label == "admin" {
adminPort = port
}
}
require.Equal(t, adminPort.Value, adminPort.To)
// Ask for reserved + dynamic ports
ask = &NetworkResource{
@@ -295,32 +285,22 @@ func TestNetworkIndex_AssignNetwork(t *testing.T) {
DynamicPorts: []Port{{"http", 0, 80}, {"https", 0, 443}, {"admin", 0, 8080}},
}
offer, err = idx.AssignNetwork(ask)
if err != nil {
t.Fatalf("err: %v", err)
}
if offer == nil {
t.Fatalf("bad")
}
if offer.IP != "192.168.0.100" {
t.Fatalf("bad: %#v", offer)
}
require.NoError(t, err)
require.NotNil(t, offer)
require.Equal(t, "192.168.0.100", offer.IP)
rp = Port{"main", 2345, 0}
if len(offer.ReservedPorts) != 1 || offer.ReservedPorts[0] != rp {
t.Fatalf("bad: %#v", offer)
}
require.Len(t, offer.ReservedPorts, 1)
require.Exactly(t, rp, offer.ReservedPorts[0])
// Ask for too much bandwidth
ask = &NetworkResource{
MBits: 1000,
}
offer, err = idx.AssignNetwork(ask)
if err.Error() != "bandwidth exceeded" {
t.Fatalf("err: %v", err)
}
if offer != nil {
t.Fatalf("bad")
}
require.Error(t, err)
require.Equal(t, "bandwidth exceeded", err.Error())
require.Nil(t, offer)
}
// This test ensures that even with a small domain of available ports we are