Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modify Status command to return a ConnTypeLabel in addition to the ConnType byte #471

Open
wants to merge 5 commits into
base: devel
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 29 additions & 6 deletions pkg/netceptor/netceptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,14 +218,24 @@ type routingUpdate struct {
}

const (
// If adding/changing an ConnType, make sure to change ConnTypeStrings as well.
// These are friendly strings printed out in a status command.
// ConnTypeDatagram indicates a packetconn (datagram) service listener.
ConnTypeDatagram = 0
// ConnTypeStream indicates a conn (stream) service listener, without a user-defined TLS.
ConnTypeStream = 1
// ConnTypeStreamTLS indicates the service listens on a packetconn connection, with a user-defined TLS.
ConnTypeStreamTLS = 2
// Default Label for an unknown connection type.
UnknownConnTypeStr = "Unknown"
)

var ConnTypeStrings = map[byte]string{
ConnTypeDatagram: "Datagram",
ConnTypeStream: "Stream",
ConnTypeStreamTLS: "StreamTLS",
}

// WorkCommand tracks available work types and whether they verify work submissions.
type WorkCommand struct {
WorkType string
Expand All @@ -235,12 +245,13 @@ type WorkCommand struct {

// ServiceAdvertisement is the data associated with a service advertisement.
type ServiceAdvertisement struct {
NodeID string
Service string
Time time.Time
ConnType byte
Tags map[string]string
WorkCommands []WorkCommand
NodeID string
Service string
Time time.Time
ConnType byte
ConnTypeLabel string
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This probably shouldn't go here. This is the struct for the low-level advertisements that get sent around the network, so its size matters. If we want another field in the Status response, we should define another struct that inherits this one and adds the field, and populate it at the time the status is being asked for.

Tags map[string]string
WorkCommands []WorkCommand
}

// serviceAdvertisementFull is the whole message from the network.
Expand Down Expand Up @@ -437,6 +448,17 @@ func (s *Netceptor) MaxConnectionIdleTime() time.Duration {
return s.maxConnectionIdleTime
}

// Convert the connection type to a string.
func (s *Netceptor) GetConnectionTypeAsString(connectionType byte) string {
// A byte can't be < 0 so we don't need to check the lower bounds
connTypeString, ok := ConnTypeStrings[connectionType]
if !ok {
connTypeString = UnknownConnTypeStr
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious, under which conditions would this happen?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If someone added a new connection type constant but forgot to add an entry into the map. I was also thinking of some weird upgrade scenario where a newer version of receptor with a new connection type was introduced to an existing mesh.

}

return connTypeString
}

type backendInfo struct {
connectionCost float64
nodeCost map[string]float64
Expand Down Expand Up @@ -579,6 +601,7 @@ func (s *Netceptor) Status() Status {
adCopy.WorkCommands = s.workCommands
}
}
adCopy.ConnTypeLabel = s.GetConnectionTypeAsString(adCopy.ConnType)
serviceAds = append(serviceAds, &adCopy)
}
}
Expand Down
22 changes: 22 additions & 0 deletions pkg/netceptor/netceptor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -782,3 +782,25 @@ func TestAllowedPeers(t *testing.T) {
n1.BackendWait()
n2.BackendWait()
}

func TestConnTypeString(t *testing.T) {
lw := &logWriter{
t: t,
}
log.SetOutput(lw)
logger.SetShowTrace(true)
defer func() {
log.SetOutput(os.Stdout)
logger.SetShowTrace(false)
}()

n1 := New(context.Background(), "node1")
if ConnTypeStrings[ConnTypeDatagram] != n1.GetConnectionTypeAsString(ConnTypeDatagram) {
t.Fatal("The function did not properly return the constant for a datagram type")
}
if n1.GetConnectionTypeAsString(254) != UnknownConnTypeStr {
t.Fatal("Either we now have 254 ConnTypes or GetConnectionTypeAsString did not properly return the string constant")
}
// Shutdown the network
n1.Shutdown()
}
17 changes: 8 additions & 9 deletions pkg/workceptor/kubernetes.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,8 @@ var ErrPodCompleted = fmt.Errorf("pod ran to completion")
// ErrImagePullBackOff is returned when the image for the container in the Pod cannot be pulled.
var ErrImagePullBackOff = fmt.Errorf("container failed to start")


// podRunningAndReady is a completion criterion for pod ready to be attached to.
func podRunningAndReady() func(event watch.Event) (bool, error){
func podRunningAndReady() func(event watch.Event) (bool, error) {
imagePullBackOffRetries := 3
inner := func(event watch.Event) (bool, error) {
if event.Type == watch.Deleted {
Expand All @@ -92,14 +91,14 @@ func podRunningAndReady() func(event watch.Event) (bool, error){
}
if conditions[i].Type == corev1.ContainersReady &&
conditions[i].Status == corev1.ConditionFalse {
statuses := t.Status.ContainerStatuses
for j := range statuses {
if statuses[j].State.Waiting.Reason == "ImagePullBackOff" {
if imagePullBackOffRetries == 0 {
return false, ErrImagePullBackOff
}
imagePullBackOffRetries--
statuses := t.Status.ContainerStatuses
for j := range statuses {
if statuses[j].State.Waiting.Reason == "ImagePullBackOff" {
if imagePullBackOffRetries == 0 {
return false, ErrImagePullBackOff
}
imagePullBackOffRetries--
}
}
}
}
Expand Down
8 changes: 1 addition & 7 deletions receptorctl/receptorctl/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,15 +166,9 @@ def status(ctx, printjson):
)
for ad in ads:
time = dateutil.parser.parse(ad["Time"])
if ad["ConnType"] == 0:
conn_type = "Datagram"
elif ad["ConnType"] == 1:
conn_type = "Stream"
elif ad["ConnType"] == 2:
conn_type = "StreamTLS"
last_seen = f"{time:%Y-%m-%d %H:%M:%S}"
print_message(
f"{ad['NodeID']:<{longest_node}} {ad['Service']:<9} {conn_type:<10} {last_seen:<21} {'-' if (ad['Tags'] is None) else str(ad['Tags']):<16}" # noqa: E501
f"{ad['NodeID']:<{longest_node}} {ad['Service']:<9} {ad['ConnTypeLabel']:<10} {last_seen:<21} {'-' if (ad['Tags'] is None) else str(ad['Tags']):<16}" # noqa: E501
)

def print_worktypes(header, isSecure):
Expand Down