// allNamespaces returns a list of all the available namespaces in the cluster. func (a *Api) allNamespaces(request *restful.Request, response *restful.Response) { cluster := a.manager.GetCluster() if cluster == nil { response.WriteError(400, errModelNotActivated) } response.WriteEntity(cluster.GetNamespaces()) }
// podContainerMetrics returns a metric timeseries for a metric of the Container entity. // freeContainerMetrics addresses only pod containers, by using the namespace-name/pod-name/container-name path. func (a *Api) podContainerMetrics(request *restful.Request, response *restful.Response) { cluster := a.manager.GetCluster() // Get namespace name namespace := request.PathParameter("namespace-name") // Get pod name pod := request.PathParameter("pod-name") // Get container name container := request.PathParameter("container-name") // Get metric name metric_name := request.PathParameter("metric-name") // Get start time, parse as time.Time req_stamp := parseRequestStartParam(request, response) timeseries, new_stamp, err := cluster.GetPodContainerMetric(namespace, pod, container, metric_name, req_stamp) if err != nil { response.WriteError(http.StatusInternalServerError, err) glog.Errorf("unable to get cluster metric: %s", err) return } response.WriteEntity(exportTimeseries(timeseries, new_stamp)) }
// processMetricNamesRequest retrieves the available metrics for the object at the specified key. func (a *HistoricalApi) processMetricNamesRequest(key core.HistoricalKey, response *restful.Response) { if resp, err := a.historicalSource.GetMetricNames(key); err != nil { response.WriteError(http.StatusInternalServerError, err) } else { response.WriteEntity(resp) } }
func (a *Api) nodeMetricsList(request *restful.Request, response *restful.Response) { selector := request.QueryParameter("labelSelector") labelSelector, err := labels.Parse(selector) if err != nil { errMsg := fmt.Errorf("Error while parsing selector %v: %v", selector, err) glog.Error(errMsg) response.WriteError(http.StatusBadRequest, errMsg) return } nodes, err := a.nodeLister.NodeCondition(func(node *kube_api.Node) bool { if labelSelector.Empty() { return true } return labelSelector.Matches(labels.Set(node.Labels)) }).List() if err != nil { errMsg := fmt.Errorf("Error while listing nodes: %v", err) glog.Error(errMsg) response.WriteError(http.StatusInternalServerError, errMsg) return } res := v1alpha1.NodeMetricsList{} for _, node := range nodes { if m := a.getNodeMetrics(node.Name); m != nil { res.Items = append(res.Items, *m) } } response.WriteEntity(&res) }
// getPortForward handles a new restful port forward request. It determines the // pod name and uid and then calls ServePortForward. func (s *Server) getPortForward(request *restful.Request, response *restful.Response) { params := getRequestParams(request) pod, ok := s.host.GetPodByName(params.podNamespace, params.podName) if !ok { response.WriteError(http.StatusNotFound, fmt.Errorf("pod does not exist")) return } if len(params.podUID) > 0 && pod.UID != params.podUID { response.WriteError(http.StatusNotFound, fmt.Errorf("pod not found")) return } redirect, err := s.host.GetPortForward(pod.Name, pod.Namespace, pod.UID) if err != nil { streaming.WriteError(err, response.ResponseWriter) return } if redirect != nil { http.Redirect(response.ResponseWriter, request.Request, redirect.String(), http.StatusFound) return } portforward.ServePortForward(response.ResponseWriter, request.Request, s.host, kubecontainer.GetPodFullName(pod), params.podUID, s.host.StreamingConnectionIdleTimeout(), remotecommand.DefaultStreamCreationTimeout) }
func (s *server) serveAttach(req *restful.Request, resp *restful.Response) { containerID := req.PathParameter("containerID") if containerID == "" { resp.WriteError(http.StatusBadRequest, errors.New("missing required containerID path parameter")) return } streamOpts, err := remotecommand.NewOptions(req.Request) if err != nil { resp.WriteError(http.StatusBadRequest, err) return } remotecommand.ServeAttach( resp.ResponseWriter, req.Request, s.runtime, "", // unused: podName "", // unusued: podUID containerID, streamOpts, s.config.StreamIdleTimeout, s.config.StreamCreationTimeout, s.config.SupportedProtocols) }
func (a *Api) podListMetrics(request *restful.Request, response *restful.Response) { model := a.manager.GetModel() if model == nil { response.WriteError(400, errModelNotActivated) return } batchResult, new_stamp, err := model.GetBatchPodMetric(model_api.BatchPodRequest{ NamespaceName: request.PathParameter("namespace-name"), PodNames: strings.Split(request.PathParameter("pod-list"), ","), MetricName: request.PathParameter("metric-name"), Start: parseRequestParam("start", request, response), End: parseRequestParam("end", request, response), }) if err != nil { response.WriteError(http.StatusInternalServerError, err) glog.Errorf("unable to get pod list metric: %s", err) return } metricResultList := types.MetricResultList{ Items: make([]types.MetricResult, len(batchResult)), } for i, metrics := range batchResult { metricResultList.Items[i] = exportTimeseries(metrics, new_stamp) } response.WriteEntity(metricResultList) }
// namespaceList lists all namespaces for which we have metrics func (a *HistoricalApi) namespaceList(request *restful.Request, response *restful.Response) { if resp, err := a.historicalSource.GetNamespaces(); err != nil { response.WriteError(http.StatusInternalServerError, err) } else { response.WriteEntity(resp) } }
// getExec handles requests to run a command inside a container. func (s *Server) getExec(request *restful.Request, response *restful.Response) { params := getRequestParams(request) pod, ok := s.host.GetPodByName(params.podNamespace, params.podName) if !ok { response.WriteError(http.StatusNotFound, fmt.Errorf("pod does not exist")) return } podFullName := kubecontainer.GetPodFullName(pod) redirect, err := s.host.GetExec(podFullName, params.podUID, params.containerName, params.cmd, params.streamOpts) if err != nil { response.WriteError(streaming.HTTPStatus(err), err) return } if redirect != nil { http.Redirect(response.ResponseWriter, request.Request, redirect.String(), http.StatusFound) return } remotecommand.ServeExec(response.ResponseWriter, request.Request, s.host, podFullName, params.podUID, params.containerName, s.host.StreamingConnectionIdleTimeout(), remotecommand.DefaultStreamCreationTimeout, remotecommand.SupportedStreamingProtocols) }
// nodeSystemContainerList lists all system containers on a node for which we have metrics func (a *HistoricalApi) nodeSystemContainerList(request *restful.Request, response *restful.Response) { if resp, err := a.historicalSource.GetSystemContainersFromNode(request.PathParameter("node-name")); err != nil { response.WriteError(http.StatusInternalServerError, err) } else { response.WriteEntity(resp) } }
// namespacePodList lists all pods for which we have metrics in a particular namespace func (a *HistoricalApi) namespacePodList(request *restful.Request, response *restful.Response) { if resp, err := a.historicalSource.GetPodsFromNamespace(request.PathParameter("namespace-name")); err != nil { response.WriteError(http.StatusInternalServerError, err) } else { response.WriteEntity(resp) } }
func podMetricsInNamespaceList(a *Api, request *restful.Request, response *restful.Response, namespace string) { selector := request.QueryParameter("labelSelector") labelSelector, err := labels.Parse(selector) if err != nil { errMsg := fmt.Errorf("Error while parsing selector %v: %v", selector, err) glog.Error(errMsg) response.WriteError(http.StatusBadRequest, errMsg) return } pods, err := a.podLister.Pods(namespace).List(labelSelector) if err != nil { errMsg := fmt.Errorf("Error while listing pods for selector %v: %v", selector, err) glog.Error(errMsg) response.WriteError(http.StatusInternalServerError, errMsg) return } res := v1alpha1.PodMetricsList{} for _, pod := range pods.Items { if m := a.getPodMetrics(&pod); m != nil { res.Items = append(res.Items, *m) } else { glog.Infof("No metrics for pod %s/%s", pod.Namespace, pod.Name) } } response.WriteEntity(&res) }
// allFreeContainers returns a list of all the available free containers in the cluster. func (a *Api) allFreeContainers(request *restful.Request, response *restful.Response) { cluster := a.manager.GetCluster() if cluster == nil { response.WriteError(400, errModelNotActivated) } node := request.PathParameter("node-name") response.WriteEntity(cluster.GetFreeContainers(node)) }
// nodePods returns a list of all the available API paths that are available for a node. func (a *Api) nodePods(request *restful.Request, response *restful.Response) { model := a.manager.GetModel() if model == nil { response.WriteError(400, errModelNotActivated) } node := request.PathParameter("node-name") response.WriteEntity(makeExternalEntityList(model.GetNodePods(node))) }
// allNamespaces returns a list of all the available namespaces in the model. func (a *Api) allNamespaces(request *restful.Request, response *restful.Response) { model := a.manager.GetModel() if model == nil { response.WriteError(400, errModelNotActivated) return } response.WriteEntity(makeExternalEntityList(model.GetNamespaces())) }
// availableMetrics returns a list of available metric names. // These metric names can be used to extract metrics from the various model entities. func (a *Api) availableMetrics(request *restful.Request, response *restful.Response) { cluster := a.manager.GetCluster() if cluster == nil { response.WriteError(400, errModelNotActivated) } result := cluster.GetAvailableMetrics() response.WriteEntity(result) }
// getSpec handles spec requests against the Kubelet. func (s *Server) getSpec(request *restful.Request, response *restful.Response) { info, err := s.host.GetCachedMachineInfo() if err != nil { response.WriteError(http.StatusInternalServerError, err) return } response.WriteEntity(info) }
// allPods returns a list of all the available pods in the cluster. func (a *Api) allPods(request *restful.Request, response *restful.Response) { cluster := a.manager.GetCluster() if cluster == nil { response.WriteError(400, errModelNotActivated) } namespace := request.PathParameter("namespace-name") response.WriteEntity(cluster.GetPods(namespace)) }
// availableMetrics returns a list of available metric names. // These metric names can be used to extract metrics from the various model entities. func (a *Api) availableMetrics(request *restful.Request, response *restful.Response) { model := a.manager.GetModel() if model == nil { response.WriteError(400, errModelNotActivated) return } result := model.GetAvailableMetrics() response.WriteEntity(result) }
// getPods returns a list of pods bound to the Kubelet and their spec. func (s *Server) getPods(request *restful.Request, response *restful.Response) { pods := s.host.GetPods() data, err := encodePods(pods) if err != nil { response.WriteError(http.StatusInternalServerError, err) return } response.Write(data) }
func (a *Api) nodeMetrics(request *restful.Request, response *restful.Response) { node := request.PathParameter("node-name") m := a.getNodeMetrics(node) if m == nil { response.WriteError(http.StatusNotFound, fmt.Errorf("No metrics for ode %v", node)) return } response.WriteEntity(m) }
// allPodContainers returns a list of all the available pod containers in the model. func (a *Api) allPodContainers(request *restful.Request, response *restful.Response) { model := a.manager.GetModel() if model == nil { response.WriteError(400, errModelNotActivated) return } namespace := request.PathParameter("namespace-name") pod := request.PathParameter("pod-name") response.WriteEntity(makeExternalEntityList(model.GetPodContainers(namespace, pod))) }
func (a *Api) derivedNodeMetrics(request *restful.Request, response *restful.Response) { model := a.manager.GetModel() if model == nil { response.WriteError(400, errModelNotActivated) } metrics, err := getNodeMetrics(model, request.PathParameter("node-name")) if err != nil { response.WriteError(400, err) } response.WriteEntity(metrics) }
// clusterStats returns a map of StatBundles for each usage metric of the Cluster entity. func (a *Api) clusterStats(request *restful.Request, response *restful.Response) { model := a.manager.GetModel() if model == nil { response.WriteError(400, errModelNotActivated) } res, uptime, err := model.GetClusterStats() if err != nil { response.WriteError(400, err) } response.WriteEntity(exportStatBundle(res, uptime)) }
func (a *Api) processMetricRequest(key string, request *restful.Request, response *restful.Response) { start, end, err := getStartEndTime(request) if err != nil { response.WriteError(http.StatusBadRequest, err) return } metricName := request.PathParameter("metric-name") convertedMetricName := convertMetricName(metricName) metrics := a.metricSink.GetMetric(convertedMetricName, []string{key}, start, end) converted := exportTimestampedMetricValue(metrics[key]) response.WriteEntity(converted) }
// getPortForward handles a new restful port forward request. It determines the // pod name and uid and then calls ServePortForward. func (s *Server) getPortForward(request *restful.Request, response *restful.Response) { podNamespace, podID, uid := getPodCoordinates(request) pod, ok := s.host.GetPodByName(podNamespace, podID) if !ok { response.WriteError(http.StatusNotFound, fmt.Errorf("pod does not exist")) return } podName := kubecontainer.GetPodFullName(pod) ServePortForward(response.ResponseWriter, request.Request, s.host, podName, uid, s.host.StreamingConnectionIdleTimeout(), defaultStreamCreationTimeout) }
// namespaceStats returns a map of StatBundles for each usage metric of a Namespace entity. func (a *Api) namespaceStats(request *restful.Request, response *restful.Response) { model := a.manager.GetModel() if model == nil { response.WriteError(400, errModelNotActivated) } res, uptime, err := model.GetNamespaceStats(model_api.NamespaceRequest{ NamespaceName: request.PathParameter("namespace-name"), }) if err != nil { response.WriteError(400, err) } response.WriteEntity(exportStatBundle(res, uptime)) }
// getRunningPods returns a list of pods running on Kubelet. The list is // provided by the container runtime, and is different from the list returned // by getPods, which is a set of desired pods to run. func (s *Server) getRunningPods(request *restful.Request, response *restful.Response) { pods, err := s.host.GetRunningPods() if err != nil { response.WriteError(http.StatusInternalServerError, err) return } data, err := encodePods(pods) if err != nil { response.WriteError(http.StatusInternalServerError, err) return } writeJsonResponse(response, data) }
// freeContainerStats returns a map of StatBundles for each usage metric of a free Container entity. func (a *Api) freeContainerStats(request *restful.Request, response *restful.Response) { model := a.manager.GetModel() if model == nil { response.WriteError(400, errModelNotActivated) } res, uptime, err := model.GetFreeContainerStats(model_api.FreeContainerRequest{ NodeName: request.PathParameter("node-name"), ContainerName: request.PathParameter("container-name"), }) if err != nil { response.WriteError(400, err) } response.WriteEntity(exportStatBundle(res, uptime)) }
// parseRequestParam parses a time.Time from a named QueryParam. // parseRequestParam receives a request and a response as inputs, and returns the parsed time. func parseRequestParam(param string, request *restful.Request, response *restful.Response) time.Time { var err error query_param := request.QueryParameter(param) req_stamp := time.Time{} if query_param != "" { req_stamp, err = time.Parse(time.RFC3339, query_param) if err != nil { // Timestamp parameter cannot be parsed response.WriteError(http.StatusInternalServerError, err) glog.Errorf("timestamp argument cannot be parsed: %s", err) return time.Time{} } } return req_stamp }