Skip to content
Merged
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
46 changes: 46 additions & 0 deletions src/backend/controllers/kubernetes/pod/pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@ package pod

import (
"fmt"
"net/http"
"sync"

"github.com/Qihoo360/wayne/src/backend/client"
"github.com/Qihoo360/wayne/src/backend/client/api"
"github.com/Qihoo360/wayne/src/backend/common"
"github.com/Qihoo360/wayne/src/backend/controllers/base"
"github.com/Qihoo360/wayne/src/backend/models"
erroresult "github.com/Qihoo360/wayne/src/backend/models/response/errors"
"github.com/Qihoo360/wayne/src/backend/resources/pod"
"github.com/Qihoo360/wayne/src/backend/util/logs"
)
Expand Down Expand Up @@ -92,6 +96,48 @@ func (c *KubePodController) PodStatistics() {
c.Success(pod.PodStatistics{Total: total, Details: countMap})
}

// @Title List
// @Description find pods by resource type
// @Param pageNo query int false "the page current no"
// @Param pageSize query int false "the page size"
// @Param type query string true "the query type. deployment, statefulset, daemonSet, job, pod"
// @Param name query string true "the query resource name."
// @Success 200 {object} models.Deployment success
// @router /namespaces/:namespace/clusters/:cluster/page [get]
func (c *KubePodController) ListPage() {
cluster := c.Ctx.Input.Param(":cluster")
namespace := c.Ctx.Input.Param(":namespace")
resourceType := c.Input().Get("type")
resourceName := c.Input().Get("name")
param := c.BuildKubernetesQueryParam()
manager := c.Manager(cluster)
var result *common.Page
var err error
switch resourceType {
case api.ResourceNameDeployment:
result, err = pod.GetPodsByDeploymentPage(manager.KubeClient, namespace, resourceName, param)
case api.ResourceNameStatefulSet:
result, err = pod.GetRelatedPodByType(manager.KubeClient, namespace, resourceName, api.ResourceNameStatefulSet, param)
case api.ResourceNameDaemonSet:
result, err = pod.GetRelatedPodByType(manager.KubeClient, namespace, resourceName, api.ResourceNameDaemonSet, param)
case api.ResourceNameJob:
result, err = pod.GetRelatedPodByType(manager.KubeClient, namespace, resourceName, api.ResourceNameJob, param)
case api.ResourceNamePod:
result, err = pod.GetRelatedPodByType(manager.KubeClient, namespace, resourceName, api.ResourceNamePod, param)
default:
err = &erroresult.ErrorResult{
Code: http.StatusBadRequest,
Msg: fmt.Sprintf("Unsupported resource type (%s). ", resourceType),
}
}
if err != nil {
logs.Error("Get kubernetes pod by type error.", cluster, namespace, resourceType, resourceName, err)
c.HandleError(err)
return
}
c.Success(result)
}

// @Title List
// @Description find pods by deployment
// @Param deployment query string true "the deployment name."
Expand Down
30 changes: 30 additions & 0 deletions src/backend/resources/pod/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package pod

import (
"k8s.io/api/core/v1"

"github.com/Qihoo360/wayne/src/backend/resources/dataselector"
)

// implements dataselector.DataCell
type ObjectCell v1.Pod

// implements dataselector.DataCell
func (cell ObjectCell) GetProperty(name dataselector.PropertyName) dataselector.ComparableValue {
switch name {
case dataselector.NameProperty:
cell.GetObjectKind()
return dataselector.StdComparableString(cell.ObjectMeta.Name)
case dataselector.CreationTimestampProperty:
return dataselector.StdComparableTime(cell.ObjectMeta.CreationTimestamp.Time)
case dataselector.NamespaceProperty:
return dataselector.StdComparableString(cell.ObjectMeta.Namespace)
case dataselector.StatusProperty:
return dataselector.StdComparableString(cell.Status.Phase)
case "podIP":
return dataselector.StdComparableString(cell.Status.PodIP)
default:
// if name is not supported then just return a constant dummy value, sort will have no effect.
return nil
}
}
96 changes: 96 additions & 0 deletions src/backend/resources/pod/pod.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
package pod

import (
"fmt"
"sort"
"time"

"k8s.io/api/core/v1"
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/kubernetes"

"github.com/Qihoo360/wayne/src/backend/client"
"github.com/Qihoo360/wayne/src/backend/client/api"
"github.com/Qihoo360/wayne/src/backend/common"
"github.com/Qihoo360/wayne/src/backend/models"
"github.com/Qihoo360/wayne/src/backend/resources/dataselector"
"github.com/Qihoo360/wayne/src/backend/util/slice"
)

type PodStatistics struct {
Expand Down Expand Up @@ -113,6 +121,94 @@ func filterPodByApiType(pods []*v1.Pod, apiType models.KubeApiType) []*v1.Pod {
return filteredPod
}

func GetPodsByDeploymentPage(kubeClient client.ResourceHandler, namespace, name string, q *common.QueryParam) (*common.Page, error) {
rss, err := kubeClient.List(api.ResourceNameReplicaSet, namespace, labels.Everything().String())
if err != nil {
return nil, err
}
relateRs := make([]string, 0)
for _, obj := range rss {
rs, ok := obj.(*extensionsv1beta1.ReplicaSet)
if !ok {
return nil, fmt.Errorf("Convert rs obj (%v) error. ", obj)
}
for _, ref := range rs.OwnerReferences {
if ref.Kind == api.KindNameDeployment && ref.Name == name {
relateRs = append(relateRs, rs.Name)
}
}

}
pods, err := kubeClient.List(api.ResourceNamePod, namespace, labels.Everything().String())
if err != nil {
return nil, err
}
relatePod := make([]*v1.Pod, 0)
for _, obj := range pods {
pod, ok := obj.(*v1.Pod)
if !ok {
return nil, fmt.Errorf("Convert pod obj (%v) error. ", obj)
}
for _, ref := range pod.OwnerReferences {
if ref.Kind == api.KindNameReplicaSet && slice.StrSliceContains(relateRs, ref.Name) {
relatePod = append(relatePod, pod)
}
}

}
return pageResult(relatePod, q), nil
}

func GetRelatedPodByType(kubeClient client.ResourceHandler, namespace, resourceName string, resourceType api.ResourceName, q *common.QueryParam) (*common.Page, error) {
var objs = make([]runtime.Object, 0)
var err error
if resourceType == api.ResourceNamePod {
pod, err := kubeClient.Get(api.ResourceNamePod, namespace, resourceName)
if err != nil {
return nil, err
}
objs = append(objs, pod)
} else {
objs, err = kubeClient.List(api.ResourceNamePod, namespace, labels.Everything().String())
if err != nil {
return nil, err
}
}

relatePod := make([]*v1.Pod, 0)
for _, obj := range objs {
pod, ok := obj.(*v1.Pod)
if !ok {
return nil, fmt.Errorf("Convert pod obj (%v) error. ", obj)
}
for _, ref := range pod.OwnerReferences {
groupVersionResourceKind, ok := api.KindToResourceMap[resourceType]
if !ok {
continue
}
if ref.Kind == groupVersionResourceKind.GroupVersionResourceKind.Kind && resourceName == ref.Name {
relatePod = append(relatePod, pod)
}
}

}
return pageResult(relatePod, q), nil
}

func pageResult(relatePod []*v1.Pod, q *common.QueryParam) *common.Page {
commonObjs := make([]dataselector.DataCell, 0)
for _, pod := range relatePod {
commonObjs = append(commonObjs, ObjectCell(*pod))
}

sort.Slice(commonObjs, func(i, j int) bool {
return commonObjs[j].GetProperty(dataselector.CreationTimestampProperty).
Compare(commonObjs[i].GetProperty(dataselector.CreationTimestampProperty)) == -1
})

return dataselector.DataSelectPage(commonObjs, q)
}

func GetPodsByDaemonSet(indexer *client.CacheFactory, namespace, name string) ([]*Pod, error) {
podSelector := map[string]string{"app": name}
pods, err := ListKubePod(indexer, namespace, podSelector)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,12 @@ func init() {
MethodParams: param.Make(),
Params: nil})

beego.GlobalControllerRouter["github.com/Qihoo360/wayne/src/backend/controllers/kubernetes/pod:KubePodController"] = append(beego.GlobalControllerRouter["github.com/Qihoo360/wayne/src/backend/controllers/kubernetes/pod:KubePodController"],
beego.ControllerComments{
Method: "ListPage",
Router: `/namespaces/:namespace/clusters/:cluster/page`,
AllowHTTPMethods: []string{"get"},
MethodParams: param.Make(),
Params: nil})

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Component, Input } from '@angular/core';
import { KubernetesListResource } from '../../../../shared/base/kubernetes-namespaced/kubernetes-list-resource';
import { TplDetailService } from '../../../../shared/tpl-detail/tpl-detail.service';
import { KubePod } from '../../../../shared/model/v1/kubernetes/kubepod';
import { KubePodUtil } from '../../../../shared/utils';


@Component({
Expand Down Expand Up @@ -32,39 +33,7 @@ export class ListPodComponent extends KubernetesListResource {

// getPodStatus returns the pod state
getPodStatus(pod: KubePod): string {
// Terminating
if (pod.metadata.deletionTimestamp) {
return 'Terminating';
}

// not running
if (pod.status.phase !== 'Running') {
return pod.status.phase;
}

let ready = false;
let notReadyReason = '';
for (const c of pod.status.conditions) {
if (c.type === 'Ready') {
ready = c.status === 'True';
notReadyReason = c.reason;
}
}

if (pod.status.reason) {
return pod.status.reason;
}

if (notReadyReason) {
return notReadyReason;
}

if (ready) {
return 'Running';
}

// Unknown?
return 'Unknown';
return KubePodUtil.getPodStatus(pod);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -66,5 +66,5 @@
</wayne-paginate>
</clr-dg-footer>
</clr-datagrid>
<list-pod [Type]="'job'"></list-pod>
<list-pod></list-pod>
<list-event></list-event>
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { ListEventComponent } from '../../../shared/list-event/list-event.compon
import { Event } from '../../../shared/model/v1/deploymenttpl';
import { Page } from '../../../shared/page/page-state';
import { StorageService } from '../../../shared/client/v1/storage.service';
import { KubeResourceJob } from '../../../shared/shared.const';

@Component({
selector: 'list-job',
Expand Down Expand Up @@ -84,7 +85,7 @@ export class ListJobComponent implements OnInit, OnDestroy {

listPod(job: Job) {
// 只允许查看非完成的pod列表?
this.listPodComponent.openModal(job.cluster, job.kubeJob.metadata.name);
this.listPodComponent.openModal(job.cluster, job.kubeJob.metadata.name, KubeResourceJob);
}

refresh(state?: ClrDatagridStateInterface) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,5 +108,5 @@
</clr-datagrid>
<wayne-ace-editor></wayne-ace-editor>
<list-event></list-event>
<list-pod [Type]="'daemonSet'"></list-pod>
<list-pod></list-pod>
<daemonset-publish-tpl (published)="published($event)"></daemonset-publish-tpl>
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
ConfirmationButtons,
ConfirmationState,
ConfirmationTargets,
KubeResourceDaemonSet,
ResourcesActionType,
TemplateState
} from '../../../shared/shared.const';
Expand Down Expand Up @@ -172,7 +173,7 @@ export class ListDaemonSetComponent implements OnInit, OnDestroy {

listPod(status: TemplateStatus, tpl: DaemonSetTemplate) {
if (status.cluster && status.state !== TemplateState.NOT_FOUND) {
this.listPodComponent.openModal(status.cluster, tpl.name);
this.listPodComponent.openModal(status.cluster, tpl.name, KubeResourceDaemonSet);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@
</clr-dg-footer>
</clr-datagrid>
<list-event></list-event>
<list-pod [Type]="'deployment'"></list-pod>
<list-pod></list-pod>
<wayne-ace-editor></wayne-ace-editor>

<publish-tpl (published)="published($event)"></publish-tpl>
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
ConfirmationButtons,
ConfirmationState,
ConfirmationTargets,
KubeResourceDeployment,
ResourcesActionType,
TemplateState
} from '../../../shared/shared.const';
Expand Down Expand Up @@ -94,10 +95,11 @@ export class ListDeploymentComponent implements OnInit, OnDestroy {

/**
* diff template
*/
*/
diffTpl() {
this.diffService.diff(this.selected);
}

// --------------------------------

pageSizeChange(pageSize: number) {
Expand Down Expand Up @@ -186,7 +188,7 @@ export class ListDeploymentComponent implements OnInit, OnDestroy {

listPod(status: DeploymentStatus, tpl: DeploymentTpl) {
if (status.cluster && status.state !== TemplateState.NOT_FOUND) {
this.listPodComponent.openModal(status.cluster, tpl.name);
this.listPodComponent.openModal(status.cluster, tpl.name, KubeResourceDeployment);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,5 +107,5 @@
</clr-datagrid>
<wayne-ace-editor></wayne-ace-editor>
<list-event></list-event>
<list-pod [Type]="'statefulset'"></list-pod>
<list-pod></list-pod>
<statefulset-publish-tpl (published)="published($event)"></statefulset-publish-tpl>
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
ConfirmationButtons,
ConfirmationState,
ConfirmationTargets,
KubeResourceStatefulSet,
ResourcesActionType,
TemplateState
} from '../../../shared/shared.const';
Expand Down Expand Up @@ -173,7 +174,7 @@ export class ListStatefulsetComponent implements OnInit, OnDestroy {

listPod(status: TemplateStatus, tpl: StatefulsetTemplate) {
if (status.cluster && status.state !== TemplateState.NOT_FOUND) {
this.listPodComponent.openModal(status.cluster, tpl.name);
this.listPodComponent.openModal(status.cluster, tpl.name, KubeResourceStatefulSet);
}
}

Expand Down
Loading