Merge pull request #825 from sargun/add-pods-api
Add /pods HTTP endpoint
This commit is contained in:
@@ -58,7 +58,7 @@ func loadTLSConfig(certPath, keyPath string) (*tls.Config, error) {
|
||||
}, 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
|
||||
cancel := func() {
|
||||
for _, c := range closers {
|
||||
@@ -91,6 +91,7 @@ func setupHTTPServer(ctx context.Context, p provider.Provider, cfg *apiServerCon
|
||||
podRoutes := api.PodHandlerConfig{
|
||||
RunInContainer: p.RunInContainer,
|
||||
GetContainerLogs: p.GetContainerLogs,
|
||||
GetPodsFromKubernetes: getPodsFromKubernetes,
|
||||
GetPods: p.GetPods,
|
||||
StreamIdleTimeout: cfg.StreamIdleTimeout,
|
||||
StreamCreationTimeout: cfg.StreamCreationTimeout,
|
||||
|
||||
@@ -193,7 +193,9 @@ func runRootCommand(ctx context.Context, s *provider.Store, c Opts) error {
|
||||
go podInformerFactory.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 {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -164,8 +164,8 @@ func (f *Framework) WaitUntilPodEventWithReason(pod *corev1.Pod, reason string)
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetRunningPods gets the running pods from the provider of the virtual kubelet
|
||||
func (f *Framework) GetRunningPods() (*corev1.PodList, error) {
|
||||
// GetRunningPodsFromProvider gets the running pods from the provider of the virtual kubelet
|
||||
func (f *Framework) GetRunningPodsFromProvider() (*corev1.PodList, error) {
|
||||
result := &corev1.PodList{}
|
||||
|
||||
err := f.KubeClient.CoreV1().
|
||||
@@ -181,6 +181,23 @@ func (f *Framework) GetRunningPods() (*corev1.PodList, error) {
|
||||
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').
|
||||
// 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
|
||||
|
||||
@@ -34,9 +34,12 @@ type ServeMux interface {
|
||||
}
|
||||
|
||||
type PodHandlerConfig struct {
|
||||
RunInContainer ContainerExecHandlerFunc
|
||||
GetContainerLogs ContainerLogsHandlerFunc
|
||||
GetPods PodListerFunc
|
||||
RunInContainer ContainerExecHandlerFunc
|
||||
GetContainerLogs ContainerLogsHandlerFunc
|
||||
// GetPods is meant to enumerate the pods that the provider knows about
|
||||
GetPods PodListerFunc
|
||||
// GetPodsFromKubernetes is meant to enumerate the pods that the node is meant to be running
|
||||
GetPodsFromKubernetes PodListerFunc
|
||||
StreamIdleTimeout 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("/pods", HandleRunningPods(p.GetPodsFromKubernetes)).Methods("GET")
|
||||
r.HandleFunc("/containerLogs/{namespace}/{pod}/{container}", HandleContainerLogs(p.GetContainerLogs)).Methods("GET")
|
||||
r.HandleFunc(
|
||||
"/exec/{namespace}/{pod}/{container}",
|
||||
|
||||
@@ -18,6 +18,49 @@ const (
|
||||
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.
|
||||
// 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) {
|
||||
@@ -91,7 +134,7 @@ func (ts *EndToEndTestSuite) TestPodLifecycleGracefulDelete(t *testing.T) {
|
||||
t.Logf("Pod %s ready", pod.Name)
|
||||
|
||||
// Grab the pods from the provider.
|
||||
pods, err := f.GetRunningPods()
|
||||
pods, err := f.GetRunningPodsFromProvider()
|
||||
assert.NilError(t, err)
|
||||
|
||||
// Check if the pod exists in the slice of PodStats.
|
||||
@@ -125,7 +168,7 @@ func (ts *EndToEndTestSuite) TestPodLifecycleGracefulDelete(t *testing.T) {
|
||||
time.Sleep(deleteGracePeriodForProvider)
|
||||
// Give the provider some time to react to the MODIFIED/DELETED events before proceeding.
|
||||
// Grab the pods from the provider.
|
||||
pods, err = f.GetRunningPods()
|
||||
pods, err = f.GetRunningPodsFromProvider()
|
||||
assert.NilError(t, err)
|
||||
|
||||
// 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)
|
||||
|
||||
// Grab the pods from the provider.
|
||||
pods, err := f.GetRunningPods()
|
||||
pods, err := f.GetRunningPodsFromProvider()
|
||||
assert.NilError(t, err)
|
||||
|
||||
// Check if the pod exists in the slice of Pods.
|
||||
@@ -203,7 +246,7 @@ func (ts *EndToEndTestSuite) TestPodLifecycleForceDelete(t *testing.T) {
|
||||
time.Sleep(deleteGracePeriodForProvider)
|
||||
|
||||
// Grab the pods from the provider.
|
||||
pods, err = f.GetRunningPods()
|
||||
pods, err = f.GetRunningPodsFromProvider()
|
||||
assert.NilError(t, err)
|
||||
|
||||
// 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.
|
||||
pods, err := f.GetRunningPods()
|
||||
pods, err := f.GetRunningPodsFromProvider()
|
||||
assert.NilError(t, err)
|
||||
|
||||
// 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.
|
||||
pods, err := f.GetRunningPods()
|
||||
pods, err := f.GetRunningPodsFromProvider()
|
||||
assert.NilError(t, err)
|
||||
|
||||
// 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.
|
||||
pods, err := f.GetRunningPods()
|
||||
pods, err := f.GetRunningPodsFromProvider()
|
||||
assert.NilError(t, err)
|
||||
|
||||
// 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.
|
||||
pods, err := f.GetRunningPods()
|
||||
pods, err := f.GetRunningPodsFromProvider()
|
||||
assert.NilError(t, err)
|
||||
|
||||
// Check if the pod exists in the slice of PodStats.
|
||||
|
||||
Reference in New Issue
Block a user