Add /pods HTTP endpoint
This commit is contained in:
@@ -58,7 +58,7 @@ func loadTLSConfig(certPath, keyPath string) (*tls.Config, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupHTTPServer(ctx context.Context, p provider.Provider, cfg *apiServerConfig) (_ func(), retErr error) {
|
func setupHTTPServer(ctx context.Context, p provider.Provider, cfg *apiServerConfig, getPodsFromKubernetes api.PodListerFunc) (_ func(), retErr error) {
|
||||||
var closers []io.Closer
|
var closers []io.Closer
|
||||||
cancel := func() {
|
cancel := func() {
|
||||||
for _, c := range closers {
|
for _, c := range closers {
|
||||||
@@ -91,6 +91,7 @@ func setupHTTPServer(ctx context.Context, p provider.Provider, cfg *apiServerCon
|
|||||||
podRoutes := api.PodHandlerConfig{
|
podRoutes := api.PodHandlerConfig{
|
||||||
RunInContainer: p.RunInContainer,
|
RunInContainer: p.RunInContainer,
|
||||||
GetContainerLogs: p.GetContainerLogs,
|
GetContainerLogs: p.GetContainerLogs,
|
||||||
|
GetPodsFromKubernetes: getPodsFromKubernetes,
|
||||||
GetPods: p.GetPods,
|
GetPods: p.GetPods,
|
||||||
StreamIdleTimeout: cfg.StreamIdleTimeout,
|
StreamIdleTimeout: cfg.StreamIdleTimeout,
|
||||||
StreamCreationTimeout: cfg.StreamCreationTimeout,
|
StreamCreationTimeout: cfg.StreamCreationTimeout,
|
||||||
|
|||||||
@@ -193,7 +193,9 @@ func runRootCommand(ctx context.Context, s *provider.Store, c Opts) error {
|
|||||||
go podInformerFactory.Start(ctx.Done())
|
go podInformerFactory.Start(ctx.Done())
|
||||||
go scmInformerFactory.Start(ctx.Done())
|
go scmInformerFactory.Start(ctx.Done())
|
||||||
|
|
||||||
cancelHTTP, err := setupHTTPServer(ctx, p, apiConfig)
|
cancelHTTP, err := setupHTTPServer(ctx, p, apiConfig, func(context.Context) ([]*corev1.Pod, error) {
|
||||||
|
return rm.GetPods(), nil
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -164,8 +164,8 @@ func (f *Framework) WaitUntilPodEventWithReason(pod *corev1.Pod, reason string)
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRunningPods gets the running pods from the provider of the virtual kubelet
|
// GetRunningPodsFromProvider gets the running pods from the provider of the virtual kubelet
|
||||||
func (f *Framework) GetRunningPods() (*corev1.PodList, error) {
|
func (f *Framework) GetRunningPodsFromProvider() (*corev1.PodList, error) {
|
||||||
result := &corev1.PodList{}
|
result := &corev1.PodList{}
|
||||||
|
|
||||||
err := f.KubeClient.CoreV1().
|
err := f.KubeClient.CoreV1().
|
||||||
@@ -181,6 +181,23 @@ func (f *Framework) GetRunningPods() (*corev1.PodList, error) {
|
|||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetRunningPodsFromProvider gets the running pods from the provider of the virtual kubelet
|
||||||
|
func (f *Framework) GetRunningPodsFromKubernetes() (*corev1.PodList, error) {
|
||||||
|
result := &corev1.PodList{}
|
||||||
|
|
||||||
|
err := f.KubeClient.CoreV1().
|
||||||
|
RESTClient().
|
||||||
|
Get().
|
||||||
|
Resource("nodes").
|
||||||
|
Name(f.NodeName).
|
||||||
|
SubResource("proxy").
|
||||||
|
Suffix("pods").
|
||||||
|
Do().
|
||||||
|
Into(result)
|
||||||
|
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
|
||||||
// stripParentTestName strips out the parent's test name from the input (in the form of 'TestParent/TestChild').
|
// stripParentTestName strips out the parent's test name from the input (in the form of 'TestParent/TestChild').
|
||||||
// Some test cases use their name as the pod name for testing purpose, and sometimes it might exceed 63
|
// Some test cases use their name as the pod name for testing purpose, and sometimes it might exceed 63
|
||||||
// characters (Kubernetes's limit for pod name). This function ensures that we strip out the parent's
|
// characters (Kubernetes's limit for pod name). This function ensures that we strip out the parent's
|
||||||
|
|||||||
@@ -36,7 +36,10 @@ type ServeMux interface {
|
|||||||
type PodHandlerConfig struct {
|
type PodHandlerConfig struct {
|
||||||
RunInContainer ContainerExecHandlerFunc
|
RunInContainer ContainerExecHandlerFunc
|
||||||
GetContainerLogs ContainerLogsHandlerFunc
|
GetContainerLogs ContainerLogsHandlerFunc
|
||||||
|
// GetPods is meant to enumerate the pods that the provider knows about
|
||||||
GetPods PodListerFunc
|
GetPods PodListerFunc
|
||||||
|
// GetPodsFromKubernetes is meant to enumerate the pods that the node is meant to be running
|
||||||
|
GetPodsFromKubernetes PodListerFunc
|
||||||
StreamIdleTimeout time.Duration
|
StreamIdleTimeout time.Duration
|
||||||
StreamCreationTimeout time.Duration
|
StreamCreationTimeout time.Duration
|
||||||
}
|
}
|
||||||
@@ -51,6 +54,7 @@ func PodHandler(p PodHandlerConfig, debug bool) http.Handler {
|
|||||||
r.HandleFunc("/runningpods/", HandleRunningPods(p.GetPods)).Methods("GET")
|
r.HandleFunc("/runningpods/", HandleRunningPods(p.GetPods)).Methods("GET")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r.HandleFunc("/pods", HandleRunningPods(p.GetPodsFromKubernetes)).Methods("GET")
|
||||||
r.HandleFunc("/containerLogs/{namespace}/{pod}/{container}", HandleContainerLogs(p.GetContainerLogs)).Methods("GET")
|
r.HandleFunc("/containerLogs/{namespace}/{pod}/{container}", HandleContainerLogs(p.GetContainerLogs)).Methods("GET")
|
||||||
r.HandleFunc(
|
r.HandleFunc(
|
||||||
"/exec/{namespace}/{pod}/{container}",
|
"/exec/{namespace}/{pod}/{container}",
|
||||||
|
|||||||
@@ -18,6 +18,49 @@ const (
|
|||||||
deleteGracePeriodForProvider = 1 * time.Second
|
deleteGracePeriodForProvider = 1 * time.Second
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// TestGetPods tests that the /pods endpoint works, and only returns pods for our kubelet
|
||||||
|
func (ts *EndToEndTestSuite) TestGetPods(t *testing.T) {
|
||||||
|
// Create a pod with prefix "nginx-" having a single container.
|
||||||
|
podSpec := f.CreateDummyPodObjectWithPrefix(t.Name(), "nginx", "foo")
|
||||||
|
podSpec.Spec.NodeName = f.NodeName
|
||||||
|
|
||||||
|
nginx, err := f.CreatePod(podSpec)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
// Delete the pod after the test finishes.
|
||||||
|
defer func() {
|
||||||
|
if err := f.DeletePodImmediately(nginx.Namespace, nginx.Name); err != nil && !apierrors.IsNotFound(err) {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
t.Logf("Created pod: %s", nginx.Name)
|
||||||
|
|
||||||
|
// Wait for the "nginx-" pod to be reported as running and ready.
|
||||||
|
if _, err := f.WaitUntilPodReady(nginx.Namespace, nginx.Name); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Logf("Pod %s ready", nginx.Name)
|
||||||
|
|
||||||
|
k8sPods, err := f.GetRunningPodsFromKubernetes()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
podFound := false
|
||||||
|
for _, pod := range k8sPods.Items {
|
||||||
|
if pod.Spec.NodeName != f.NodeName {
|
||||||
|
t.Fatalf("Found pod with node name %s, whereas expected %s", pod.Spec.NodeName, f.NodeName)
|
||||||
|
}
|
||||||
|
if pod.UID == nginx.UID {
|
||||||
|
podFound = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !podFound {
|
||||||
|
t.Fatal("Nginx pod not found")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TestGetStatsSummary creates a pod having two containers and queries the /stats/summary endpoint of the virtual-kubelet.
|
// TestGetStatsSummary creates a pod having two containers and queries the /stats/summary endpoint of the virtual-kubelet.
|
||||||
// It expects this endpoint to return stats for the current node, as well as for the aforementioned pod and each of its two containers.
|
// It expects this endpoint to return stats for the current node, as well as for the aforementioned pod and each of its two containers.
|
||||||
func (ts *EndToEndTestSuite) TestGetStatsSummary(t *testing.T) {
|
func (ts *EndToEndTestSuite) TestGetStatsSummary(t *testing.T) {
|
||||||
@@ -91,7 +134,7 @@ func (ts *EndToEndTestSuite) TestPodLifecycleGracefulDelete(t *testing.T) {
|
|||||||
t.Logf("Pod %s ready", pod.Name)
|
t.Logf("Pod %s ready", pod.Name)
|
||||||
|
|
||||||
// Grab the pods from the provider.
|
// Grab the pods from the provider.
|
||||||
pods, err := f.GetRunningPods()
|
pods, err := f.GetRunningPodsFromProvider()
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
// Check if the pod exists in the slice of PodStats.
|
// Check if the pod exists in the slice of PodStats.
|
||||||
@@ -125,7 +168,7 @@ func (ts *EndToEndTestSuite) TestPodLifecycleGracefulDelete(t *testing.T) {
|
|||||||
time.Sleep(deleteGracePeriodForProvider)
|
time.Sleep(deleteGracePeriodForProvider)
|
||||||
// Give the provider some time to react to the MODIFIED/DELETED events before proceeding.
|
// Give the provider some time to react to the MODIFIED/DELETED events before proceeding.
|
||||||
// Grab the pods from the provider.
|
// Grab the pods from the provider.
|
||||||
pods, err = f.GetRunningPods()
|
pods, err = f.GetRunningPodsFromProvider()
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
// Make sure the pod DOES NOT exist in the provider's set of running pods
|
// Make sure the pod DOES NOT exist in the provider's set of running pods
|
||||||
@@ -162,7 +205,7 @@ func (ts *EndToEndTestSuite) TestPodLifecycleForceDelete(t *testing.T) {
|
|||||||
t.Logf("Pod %s ready", pod.Name)
|
t.Logf("Pod %s ready", pod.Name)
|
||||||
|
|
||||||
// Grab the pods from the provider.
|
// Grab the pods from the provider.
|
||||||
pods, err := f.GetRunningPods()
|
pods, err := f.GetRunningPodsFromProvider()
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
// Check if the pod exists in the slice of Pods.
|
// Check if the pod exists in the slice of Pods.
|
||||||
@@ -203,7 +246,7 @@ func (ts *EndToEndTestSuite) TestPodLifecycleForceDelete(t *testing.T) {
|
|||||||
time.Sleep(deleteGracePeriodForProvider)
|
time.Sleep(deleteGracePeriodForProvider)
|
||||||
|
|
||||||
// Grab the pods from the provider.
|
// Grab the pods from the provider.
|
||||||
pods, err = f.GetRunningPods()
|
pods, err = f.GetRunningPodsFromProvider()
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
// Make sure the "nginx-" pod DOES NOT exist in the slice of Pods anymore.
|
// Make sure the "nginx-" pod DOES NOT exist in the slice of Pods anymore.
|
||||||
@@ -240,7 +283,7 @@ func (ts *EndToEndTestSuite) TestCreatePodWithOptionalInexistentSecrets(t *testi
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Grab the pods from the provider.
|
// Grab the pods from the provider.
|
||||||
pods, err := f.GetRunningPods()
|
pods, err := f.GetRunningPodsFromProvider()
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
// Check if the pod exists in the slice of Pods.
|
// Check if the pod exists in the slice of Pods.
|
||||||
@@ -269,7 +312,7 @@ func (ts *EndToEndTestSuite) TestCreatePodWithMandatoryInexistentSecrets(t *test
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Grab the pods from the provider.
|
// Grab the pods from the provider.
|
||||||
pods, err := f.GetRunningPods()
|
pods, err := f.GetRunningPodsFromProvider()
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
// Check if the pod exists in the slice of PodStats.
|
// Check if the pod exists in the slice of PodStats.
|
||||||
@@ -303,7 +346,7 @@ func (ts *EndToEndTestSuite) TestCreatePodWithOptionalInexistentConfigMap(t *tes
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Grab the pods from the provider.
|
// Grab the pods from the provider.
|
||||||
pods, err := f.GetRunningPods()
|
pods, err := f.GetRunningPodsFromProvider()
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
// Check if the pod exists in the slice of PodStats.
|
// Check if the pod exists in the slice of PodStats.
|
||||||
@@ -332,7 +375,7 @@ func (ts *EndToEndTestSuite) TestCreatePodWithMandatoryInexistentConfigMap(t *te
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Grab the pods from the provider.
|
// Grab the pods from the provider.
|
||||||
pods, err := f.GetRunningPods()
|
pods, err := f.GetRunningPodsFromProvider()
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
// Check if the pod exists in the slice of PodStats.
|
// Check if the pod exists in the slice of PodStats.
|
||||||
|
|||||||
Reference in New Issue
Block a user