Add support for correctly displaying node and pod IP address + fix make clean
This commit is contained in:
@@ -12,6 +12,7 @@ import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"fmt"
|
||||
|
||||
"github.com/virtual-kubelet/virtual-kubelet/providers/vic/cache"
|
||||
"github.com/virtual-kubelet/virtual-kubelet/providers/vic/proxy"
|
||||
proxymocks "github.com/virtual-kubelet/virtual-kubelet/providers/vic/proxy/mocks"
|
||||
@@ -30,7 +31,13 @@ const (
|
||||
podName = "busybox-sleep"
|
||||
podHandle = "fakehandle"
|
||||
|
||||
fakeEP = "fake-endpoint"
|
||||
fakeEP = "fake-endpoint"
|
||||
stateRunning = "Running"
|
||||
stateStarting = "Starting"
|
||||
stateStopping = "Stopping"
|
||||
stateStopped = "Stopped"
|
||||
stateRemoving = "Removing"
|
||||
stateRemoved = "Removed"
|
||||
)
|
||||
|
||||
func createMocks(t *testing.T) (*proxymocks.ImageStore, *proxymocks.IsolationProxy, cache.PodCache, trace.Operation) {
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/kr/pretty"
|
||||
|
||||
@@ -17,6 +18,7 @@ import (
|
||||
"github.com/vmware/vic/pkg/trace"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
type PodCreator interface {
|
||||
@@ -143,6 +145,8 @@ func (v *VicPodCreator) CreatePod(op trace.Operation, pod *v1.Pod, start bool) e
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
now := metav1.NewTime(time.Now())
|
||||
vp.Pod.Status.StartTime = &now
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
151
providers/vic/operations/pod_status.go
Normal file
151
providers/vic/operations/pod_status.go
Normal file
@@ -0,0 +1,151 @@
|
||||
package operations
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/virtual-kubelet/virtual-kubelet/providers/vic/proxy"
|
||||
|
||||
"github.com/vmware/vic/lib/apiservers/portlayer/client"
|
||||
"github.com/vmware/vic/pkg/trace"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
type PodStatus interface {
|
||||
GetStatus(op trace.Operation, namespace string, name string, hostAddress string) (*v1.PodStatus, error)
|
||||
}
|
||||
|
||||
type VicPodStatus struct {
|
||||
client *client.PortLayer
|
||||
isolationProxy proxy.IsolationProxy
|
||||
}
|
||||
|
||||
type VicPodStatusError string
|
||||
|
||||
func (e VicPodStatusError) Error() string { return string(e) }
|
||||
|
||||
const (
|
||||
PodStatusPortlayerClientError = VicPodStatusError("PodStatus called with an invalid portlayer client")
|
||||
PodStatusIsolationProxyError = VicPodStatusError("PodStatus called with an invalid isolation proxy")
|
||||
PodStatusInvalidPodIDError = VicPodStatusError("PodStatus called with invalid PodID")
|
||||
PodStatusInvalidPodNameError = VicPodStatusError("PodStatus called with invalid PodName")
|
||||
)
|
||||
|
||||
func NewPodStatus(client *client.PortLayer, isolationProxy proxy.IsolationProxy) (PodStatus, error) {
|
||||
if client == nil {
|
||||
return nil, PodStatusPortlayerClientError
|
||||
} else if isolationProxy == nil {
|
||||
return nil, PodStatusIsolationProxyError
|
||||
}
|
||||
|
||||
return &VicPodStatus{
|
||||
client: client,
|
||||
isolationProxy: isolationProxy,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Gets pod status does not delete it
|
||||
//
|
||||
// arguments:
|
||||
// op operation trace logger
|
||||
// id pod id
|
||||
// name pod name
|
||||
// returns:
|
||||
// error
|
||||
func (v *VicPodStatus) GetStatus(op trace.Operation, id, name string, hostAddress string) (*v1.PodStatus, error) {
|
||||
defer trace.End(trace.Begin(fmt.Sprintf("id(%s), name(%s)", id, name), op))
|
||||
|
||||
return v.getStatus(op, id, name, hostAddress)
|
||||
}
|
||||
|
||||
func (v *VicPodStatus) getStatus(op trace.Operation, id, name string, hostAddress string) (*v1.PodStatus, error) {
|
||||
defer trace.End(trace.Begin(fmt.Sprintf("id(%s), name(%s)", id, name), op))
|
||||
// Start out with unknown
|
||||
phase := v1.PodUnknown
|
||||
podReady := v1.ConditionUnknown
|
||||
podInitialized := v1.ConditionUnknown
|
||||
podScheduled := v1.ConditionUnknown
|
||||
|
||||
// Get current state
|
||||
state, err := v.isolationProxy.State(op, id, name)
|
||||
if err == nil {
|
||||
podScheduled = v1.ConditionTrue
|
||||
switch state {
|
||||
case "Starting":
|
||||
// if we are starting let the user know they must use the force
|
||||
phase = v1.PodPending
|
||||
podInitialized = v1.ConditionFalse
|
||||
podReady = v1.ConditionFalse
|
||||
case "Running":
|
||||
phase = v1.PodRunning
|
||||
podInitialized = v1.ConditionTrue
|
||||
podReady = v1.ConditionTrue
|
||||
case "Stopping":
|
||||
phase = v1.PodRunning
|
||||
podReady = v1.ConditionFalse
|
||||
podInitialized = v1.ConditionTrue
|
||||
case "Stopped":
|
||||
phase = v1.PodSucceeded
|
||||
podReady = v1.ConditionFalse
|
||||
podInitialized = v1.ConditionTrue
|
||||
case "Removing":
|
||||
phase = v1.PodSucceeded
|
||||
podReady = v1.ConditionFalse
|
||||
podInitialized = v1.ConditionTrue
|
||||
case "Removed":
|
||||
phase = v1.PodSucceeded
|
||||
podReady = v1.ConditionFalse
|
||||
podInitialized = v1.ConditionTrue
|
||||
}
|
||||
}
|
||||
|
||||
status := &v1.PodStatus{
|
||||
Phase: phase,
|
||||
Conditions: []v1.PodCondition{
|
||||
{
|
||||
Type: v1.PodInitialized,
|
||||
Status: podInitialized,
|
||||
},
|
||||
{
|
||||
Type: v1.PodReady,
|
||||
Status: podReady,
|
||||
},
|
||||
{
|
||||
Type: v1.PodScheduled,
|
||||
Status: podScheduled,
|
||||
},
|
||||
},
|
||||
}
|
||||
addresses, err := v.getIPAddresses(op, id, name)
|
||||
if err == nil && len(addresses) > 0 {
|
||||
status.HostIP = hostAddress
|
||||
status.PodIP = addresses[0]
|
||||
} else {
|
||||
status.HostIP = "0.0.0.0"
|
||||
status.PodIP = "0.0.0.0"
|
||||
}
|
||||
|
||||
return status, nil
|
||||
}
|
||||
|
||||
func (v *VicPodStatus) getIPAddresses(op trace.Operation, id, name string) ([]string, error) {
|
||||
defer trace.End(trace.Begin(id, op))
|
||||
|
||||
apAddresses, err := v.isolationProxy.EpAddresses(op, id, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
IPAddresses := make([]string, 0)
|
||||
for _, epAddr := range apAddresses {
|
||||
if epAddr != "" {
|
||||
ip, _, err := net.ParseCIDR(epAddr)
|
||||
if err == nil {
|
||||
IPAddresses = append(IPAddresses, ip.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return IPAddresses, err
|
||||
}
|
||||
225
providers/vic/operations/pod_status_test.go
Normal file
225
providers/vic/operations/pod_status_test.go
Normal file
@@ -0,0 +1,225 @@
|
||||
package operations
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/vmware/vic/lib/apiservers/portlayer/client"
|
||||
"k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
func TestNewPodStatus(t *testing.T) {
|
||||
_, ip, _, _ := createMocks(t)
|
||||
client := client.Default
|
||||
|
||||
// Positive Cases
|
||||
s, err := NewPodStatus(client, ip)
|
||||
assert.NotNil(t, s, "Expected non-nil creating a pod Status but received nil")
|
||||
|
||||
// Negative Cases
|
||||
s, err = NewPodStatus(nil, ip)
|
||||
assert.Nil(t, s, "Expected nil")
|
||||
assert.Equal(t, err, PodStatusPortlayerClientError)
|
||||
|
||||
s, err = NewPodStatus(client, nil)
|
||||
assert.Nil(t, s, "Expected nil")
|
||||
assert.Equal(t, err, PodStatusIsolationProxyError)
|
||||
}
|
||||
|
||||
func TestStatusPodStarting(t *testing.T) {
|
||||
client := client.Default
|
||||
_, ip, _, op := createMocks(t)
|
||||
|
||||
s, err := NewPodStatus(client, ip)
|
||||
assert.NotNil(t, s, "Expected non-nil creating a pod Status but received nil")
|
||||
assert.Nil(t, err, "Expected nil")
|
||||
|
||||
HostAddress := "1.2.3.4"
|
||||
EndpointAddresses := []string{
|
||||
"5.6.7.8/24",
|
||||
}
|
||||
|
||||
// Set up the mocks for this test
|
||||
ip.On("State", op, podID, podName).Return(stateStarting, nil)
|
||||
ip.On("EpAddresses", op, podID, podName).Return(EndpointAddresses, nil)
|
||||
|
||||
// Positive case
|
||||
status, err := s.GetStatus(op, podID, podName, HostAddress)
|
||||
assert.Nil(t, err, "Expected nil")
|
||||
assert.Equal(t, status.Phase, v1.PodPending, "Expected Phase Pending")
|
||||
verifyConditions(t, status.Conditions, v1.ConditionTrue, v1.ConditionFalse, v1.ConditionFalse)
|
||||
assert.Equal(t, status.HostIP, "1.2.3.4", "Expected Host IP Address")
|
||||
assert.Equal(t, status.PodIP, "5.6.7.8", "Expected Pod IP Address")
|
||||
}
|
||||
|
||||
func TestStatusPodRunning(t *testing.T) {
|
||||
client := client.Default
|
||||
_, ip, _, op := createMocks(t)
|
||||
|
||||
s, err := NewPodStatus(client, ip)
|
||||
assert.NotNil(t, s, "Expected non-nil creating a pod Status but received nil")
|
||||
assert.Nil(t, err, "Expected nil")
|
||||
|
||||
HostAddress := "1.2.3.4"
|
||||
EndpointAddresses := []string{
|
||||
"5.6.7.8/24",
|
||||
}
|
||||
|
||||
// Set up the mocks for this test
|
||||
ip.On("State", op, podID, podName).Return(stateRunning, nil)
|
||||
ip.On("EpAddresses", op, podID, podName).Return(EndpointAddresses, nil)
|
||||
|
||||
// Pod Running case
|
||||
status, err := s.GetStatus(op, podID, podName, HostAddress)
|
||||
assert.Nil(t, err, "Expected nil")
|
||||
assert.Equal(t, status.Phase, v1.PodRunning, "Expected Phase PodRunning")
|
||||
verifyConditions(t, status.Conditions, v1.ConditionTrue, v1.ConditionTrue, v1.ConditionTrue)
|
||||
assert.Equal(t, status.HostIP, "1.2.3.4", "Expected Host IP Address")
|
||||
assert.Equal(t, status.PodIP, "5.6.7.8", "Expected Pod IP Address")
|
||||
}
|
||||
|
||||
func TestStatusPodStopping(t *testing.T) {
|
||||
client := client.Default
|
||||
_, ip, _, op := createMocks(t)
|
||||
|
||||
s, err := NewPodStatus(client, ip)
|
||||
assert.NotNil(t, s, "Expected non-nil creating a pod Status but received nil")
|
||||
assert.Nil(t, err, "Expected nil")
|
||||
|
||||
HostAddress := "1.2.3.4"
|
||||
EndpointAddresses := []string{
|
||||
"5.6.7.8/24",
|
||||
}
|
||||
|
||||
// Set up the mocks for this test
|
||||
ip.On("State", op, podID, podName).Return(stateStopping, nil)
|
||||
ip.On("EpAddresses", op, podID, podName).Return(EndpointAddresses, nil)
|
||||
|
||||
// Pod error case
|
||||
status, err := s.GetStatus(op, podID, podName, HostAddress)
|
||||
|
||||
assert.Equal(t, status.Phase, v1.PodRunning, "Expected Phase PodFailed")
|
||||
verifyConditions(t, status.Conditions, v1.ConditionTrue, v1.ConditionTrue, v1.ConditionFalse)
|
||||
assert.Equal(t, status.HostIP, "1.2.3.4", "Expected Host IP Address")
|
||||
assert.Equal(t, status.PodIP, "5.6.7.8", "Expected Pod IP Address")
|
||||
}
|
||||
|
||||
func TestStatusPodStopped(t *testing.T) {
|
||||
client := client.Default
|
||||
_, ip, _, op := createMocks(t)
|
||||
|
||||
s, err := NewPodStatus(client, ip)
|
||||
assert.NotNil(t, s, "Expected non-nil creating a pod Status but received nil")
|
||||
assert.Nil(t, err, "Expected nil")
|
||||
|
||||
HostAddress := "1.2.3.4"
|
||||
EndpointAddresses := []string{
|
||||
"5.6.7.8/24",
|
||||
}
|
||||
|
||||
// Set up the mocks for this test
|
||||
ip.On("State", op, podID, podName).Return(stateStopped, nil)
|
||||
ip.On("EpAddresses", op, podID, podName).Return(EndpointAddresses, nil)
|
||||
|
||||
// Pod error case
|
||||
status, err := s.GetStatus(op, podID, podName, HostAddress)
|
||||
|
||||
assert.Equal(t, status.Phase, v1.PodSucceeded, "Expected Phase PodFailed")
|
||||
verifyConditions(t, status.Conditions, v1.ConditionTrue, v1.ConditionTrue, v1.ConditionFalse)
|
||||
assert.Equal(t, status.HostIP, "1.2.3.4", "Expected Host IP Address")
|
||||
assert.Equal(t, status.PodIP, "5.6.7.8", "Expected Pod IP Address")
|
||||
}
|
||||
|
||||
func TestStatusPodRemoving(t *testing.T) {
|
||||
client := client.Default
|
||||
_, ip, _, op := createMocks(t)
|
||||
|
||||
s, err := NewPodStatus(client, ip)
|
||||
assert.NotNil(t, s, "Expected non-nil creating a pod Status but received nil")
|
||||
assert.Nil(t, err, "Expected nil")
|
||||
|
||||
HostAddress := "1.2.3.4"
|
||||
EndpointAddresses := []string{
|
||||
"5.6.7.8/24",
|
||||
}
|
||||
|
||||
// Set up the mocks for this test
|
||||
ip.On("State", op, podID, podName).Return(stateRemoving, nil)
|
||||
ip.On("EpAddresses", op, podID, podName).Return(EndpointAddresses, nil)
|
||||
|
||||
// Pod error case
|
||||
status, err := s.GetStatus(op, podID, podName, HostAddress)
|
||||
|
||||
assert.Equal(t, status.Phase, v1.PodSucceeded, "Expected Phase PodFailed")
|
||||
verifyConditions(t, status.Conditions, v1.ConditionTrue, v1.ConditionTrue, v1.ConditionFalse)
|
||||
assert.Equal(t, status.HostIP, "1.2.3.4", "Expected Host IP Address")
|
||||
assert.Equal(t, status.PodIP, "5.6.7.8", "Expected Pod IP Address")
|
||||
}
|
||||
|
||||
func TestStatusPodRemoved(t *testing.T) {
|
||||
client := client.Default
|
||||
_, ip, _, op := createMocks(t)
|
||||
|
||||
s, err := NewPodStatus(client, ip)
|
||||
assert.NotNil(t, s, "Expected non-nil creating a pod Status but received nil")
|
||||
assert.Nil(t, err, "Expected nil")
|
||||
|
||||
HostAddress := "1.2.3.4"
|
||||
EndpointAddresses := []string{
|
||||
"5.6.7.8/24",
|
||||
}
|
||||
|
||||
// Set up the mocks for this test
|
||||
ip.On("State", op, podID, podName).Return(stateRemoved, nil)
|
||||
ip.On("EpAddresses", op, podID, podName).Return(EndpointAddresses, nil)
|
||||
|
||||
// Pod error case
|
||||
status, err := s.GetStatus(op, podID, podName, HostAddress)
|
||||
|
||||
assert.Equal(t, status.Phase, v1.PodSucceeded, "Expected Phase PodFailed")
|
||||
verifyConditions(t, status.Conditions, v1.ConditionTrue, v1.ConditionTrue, v1.ConditionFalse)
|
||||
assert.Equal(t, status.HostIP, "1.2.3.4", "Expected Host IP Address")
|
||||
assert.Equal(t, status.PodIP, "5.6.7.8", "Expected Pod IP Address")
|
||||
}
|
||||
|
||||
func TestStatusError(t *testing.T) {
|
||||
client := client.Default
|
||||
_, ip, _, op := createMocks(t)
|
||||
|
||||
// Start with arguments
|
||||
s, err := NewPodStatus(client, ip)
|
||||
assert.NotNil(t, s, "Expected non-nil creating a pod Status but received nil")
|
||||
assert.Nil(t, err, "Expected nil")
|
||||
|
||||
HostAddress := "0.0.0.0"
|
||||
|
||||
// Set up the mocks for this test
|
||||
fakeErr := fakeError("invalid Pod")
|
||||
ip.On("State", op, podID, podName).Return("", fakeErr)
|
||||
ip.On("EpAddresses", op, podID, podName).Return(nil, fakeErr)
|
||||
|
||||
// Error case
|
||||
status, err := s.GetStatus(op, podID, podName, HostAddress)
|
||||
assert.Nil(t, err, "Expected nil")
|
||||
assert.Equal(t, status.Phase, v1.PodUnknown, "Expected Phase PodUnknown")
|
||||
verifyConditions(t, status.Conditions, v1.ConditionUnknown, v1.ConditionUnknown, v1.ConditionUnknown)
|
||||
assert.Equal(t, status.HostIP, "0.0.0.0", "Expected Host IP Address")
|
||||
assert.Equal(t, status.PodIP, "0.0.0.0", "Expected Pod IP Address")
|
||||
}
|
||||
|
||||
func verifyConditions(t *testing.T, conditions []v1.PodCondition, scheduled v1.ConditionStatus, initialized v1.ConditionStatus, ready v1.ConditionStatus) {
|
||||
for _, condition := range conditions {
|
||||
switch condition.Type {
|
||||
case v1.PodScheduled:
|
||||
assert.Equal(t, condition.Status, scheduled, "Condition Pod Scheduled")
|
||||
break
|
||||
case v1.PodInitialized:
|
||||
assert.Equal(t, condition.Status, initialized, "Condition Pod Initialized")
|
||||
break
|
||||
case v1.PodReady:
|
||||
assert.Equal(t, condition.Status, ready, "Condition Pod Ready")
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user