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
79 changes: 77 additions & 2 deletions src/backend/controllers/kubernetes/ingress/ingress.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ func (c *KubeIngressController) URLMapping() {
c.Mapping("Get", c.Get)
c.Mapping("Offline", c.Offline)
c.Mapping("Deploy", c.Deploy)
c.Mapping("List", c.List)
c.Mapping("GetDetail", c.GetDetail)
}

func (c *KubeIngressController) Prepare() {
Expand All @@ -40,6 +42,39 @@ func (c *KubeIngressController) Prepare() {
}
}

// @Title List ingress
// @Description get all ingress in a kubernetes cluster
// @Param pageNo query int false "the page current no"
// @Param pageSize query int false "the page size"
// @Param filter query string false "column filter, ex. filter=name=test"
// @Param sortby query string false "column sorted by, ex. sortby=-id, '-' representation desc, and sortby=id representation asc"
// @Param cluster path string true "the cluster name"
// @Param namespace path string true "the namespace name"
// @Success 200 {object} common.Page success
// @router /namespaces/:namespace/clusters/:cluster [get]
func (c *KubeIngressController) List() {
param := c.BuildQueryParam()
cluster := c.Ctx.Input.Param(":cluster")
namespace := c.Ctx.Input.Param(":namespace")

k8sClient, err := client.Client(cluster)
if err != nil {
c.AbortBadRequestFormat("Cluster")
}
res, err := ingress.GetIngressPage(k8sClient, namespace, param)
if err != nil {
logs.Error("list kubernetes(%s) namespace(%s) ingresses error %v", cluster, namespace, err)
c.HandleError(err)
return
}
c.Success(res)
}

// @Title deploy
// @Description deploy tpl
// @Param body body string true "The tpl content"
// @Success 200 return ok success
// @router /:ingressId([0-9]+)/tpls/:tplId([0-9]+)/clusters/:cluster [post]
func (c *KubeIngressController) Deploy() {
ingressId := c.GetIntParamFromURL(":ingressId")
tplId := c.GetIntParamFromURL(":tplId")
Expand Down Expand Up @@ -69,6 +104,7 @@ func (c *KubeIngressController) Deploy() {
logs.Critical("insert log into database failed: %s", err)
}
}()
// ingressDetail include endpoints
_, err = ingress.CreateOrUpdateIngress(k8sClient, &kubeIngress)
if err != nil {
publishHistory.Status = models.ReleaseFailure
Expand All @@ -77,6 +113,7 @@ func (c *KubeIngressController) Deploy() {
c.HandleError(err)
return
}

publishHistory.Status = models.ReleaseSuccess
publishStatus := models.PublishStatus{
ResourceId: int64(ingressId),
Expand All @@ -103,16 +140,47 @@ func (c *KubeIngressController) Deploy() {
c.Success("ok")
}

// @Title GetDetail
// @Description find ingress detail in kubernetes
// @Param ingress path string true "the ingress name"
// @Param cluster path string true "the cluster name"
// @Param namespace path string true "the namespace name"
// @Success 200 {object} ingress.Ingress success
// @router /:ingress/detail/namespaces/:namespace/clusters/:cluster [get]

func (c *KubeIngressController) GetDetail() {
cluster := c.Ctx.Input.Param(":cluster")
namespace := c.Ctx.Input.Param(":namespace")
name := c.Ctx.Input.Param(":ingress")
k8sClient, err := client.Client(cluster)
if err != nil {
c.AbortBadRequest("Cluster")
}
res, err := ingress.GetIngressDetail(k8sClient, name, namespace)
if err != nil {
logs.Error("get kubernetes ingress detail err %v", err)
c.HandleError(err)
return
}
c.Success(res)
}

// @Title Get
// @Description find Deployment by cluster
// @Param cluster path string true "the cluster name"
// @Param namespace path string true "the namespace name"
// @Success 200 {object} models.Deployment success
// @router /:ingress/namespaces/:namespace/clusters/:cluster [get]
func (c *KubeIngressController) Get() {
cluster := c.Ctx.Input.Param(":cluster")
namespace := c.Ctx.Input.Param(":namespace")
name := c.Ctx.Input.Param(":ingress")
k8sClinet, err := client.Client(cluster)
k8sClient, err := client.Client(cluster)
if err != nil {
c.AbortBadRequestFormat("Cluster")
return
}
res, err := ingress.GetIngressDetail(k8sClinet, name, namespace)
res, err := ingress.GetIngress(k8sClient, name, namespace)
if err != nil {
logs.Error("get ingress error cluster: %s, namespace: %s", cluster, namespace)
c.HandleError(err)
Expand All @@ -121,6 +189,13 @@ func (c *KubeIngressController) Get() {
c.Success(res)
}

// @Title Delete
// @Description delete the Ingress
// @Param cluster path string true "the cluster want to delete"
// @Param namespace path string true "the namespace want to delete"
// @Param deployment path string true "the deployment name want to delete"
// @Success 200 {string} delete success!
// @router /:ingress/namespaces/:namespace/clusters/:cluster [delete]
func (c *KubeIngressController) Offline() {
cluster := c.Ctx.Input.Param(":cluster")
namespace := c.Ctx.Input.Param(":namespace")
Expand Down
39 changes: 39 additions & 0 deletions src/backend/resources/ingress/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package ingress

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

// The code below allows to perform complex data section on []extensions.Ingress

type IngressCell Ingress

func (self IngressCell) GetProperty(name dataselector.PropertyName) dataselector.ComparableValue {
switch name {
case dataselector.NameProperty:
return dataselector.StdComparableString(self.ObjectMeta.Name)
case dataselector.CreationTimestampProperty:
return dataselector.StdComparableTime(self.ObjectMeta.CreationTimestamp.Time)
case dataselector.NamespaceProperty:
return dataselector.StdComparableString(self.ObjectMeta.Namespace)
default:
// if name is not supported then just return a constant dummy value, sort will have no effect.
return nil
}
}

func toCells(std []Ingress) []dataselector.DataCell {
cells := make([]dataselector.DataCell, len(std))
for i := range std {
cells[i] = IngressCell(std[i])
}
return cells
}

func fromCells(cells []dataselector.DataCell) []Ingress {
std := make([]Ingress, len(cells))
for i := range std {
std[i] = Ingress(cells[i].(IngressCell))
}
return std
}
39 changes: 33 additions & 6 deletions src/backend/resources/ingress/ingress.go
Original file line number Diff line number Diff line change
@@ -1,32 +1,59 @@
package ingress

import (
k8sv1beta1 "k8s.io/api/extensions/v1beta1"
"k8s.io/api/extensions/v1beta1"
"k8s.io/apimachinery/pkg/api/errors"
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
)

func CreateOrUpdateIngress(c *kubernetes.Clientset, ingress *k8sv1beta1.Ingress) (*k8sv1beta1.Ingress, error) {
func CreateOrUpdateIngress(c *kubernetes.Clientset, ingress *v1beta1.Ingress) (*Ingress, error) {
old, err := c.ExtensionsV1beta1().Ingresses(ingress.Namespace).Get(ingress.Name, metaV1.GetOptions{})
if err != nil {
if errors.IsNotFound(err) {
return c.ExtensionsV1beta1().Ingresses(ingress.Namespace).Create(ingress)
kubeIngress, err := c.ExtensionsV1beta1().Ingresses(ingress.Namespace).Create(ingress)
if err != nil {
return nil, err
}
return toIngress(kubeIngress), nil
}
return nil, err
}
ingress.Spec.DeepCopyInto(&old.Spec)
return c.ExtensionsV1beta1().Ingresses(ingress.Namespace).Update(old)
kubeIngress, err := c.ExtensionsV1beta1().Ingresses(ingress.Namespace).Update(old)
if err != nil {
return nil, err
}
return toIngress(kubeIngress), nil
}

func GetIngressDetail(c *kubernetes.Clientset, name, namespace string) (*k8sv1beta1.Ingress, error) {
func GetIngressDetail(c *kubernetes.Clientset, name, namespace string) (*Ingress, error) {
ingress, err := c.ExtensionsV1beta1().Ingresses(namespace).Get(name, metaV1.GetOptions{})
if err != nil {
return nil, err
}
return ingress, nil
return toIngress(ingress), nil
}

func GetIngress(c *kubernetes.Clientset, name, namespace string) (ingress *v1beta1.Ingress, err error) {
ingress, err = c.ExtensionsV1beta1().Ingresses(namespace).Get(name, metaV1.GetOptions{})
if err != nil {
return nil, err
}
return
}

func DeleteIngress(c *kubernetes.Clientset, name, namespace string) error {
return c.ExtensionsV1beta1().Ingresses(namespace).Delete(name, &metaV1.DeleteOptions{})
}

func GetIngressList(cli *kubernetes.Clientset, namespace string, opts metaV1.ListOptions) (list []*Ingress, err error) {
kubeIngressList, err := cli.ExtensionsV1beta1().Ingresses(namespace).List(opts)
if err != nil {
return nil, err
}
for _, kubeIngress := range kubeIngressList.Items {
list = append(list, toIngress(&kubeIngress))
}
return
}
48 changes: 48 additions & 0 deletions src/backend/resources/ingress/list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package ingress

import (
backendCommon "github.com/Qihoo360/wayne/src/backend/common"
"github.com/Qihoo360/wayne/src/backend/resources/common"
"github.com/Qihoo360/wayne/src/backend/resources/dataselector"
extensions "k8s.io/api/extensions/v1beta1"
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
)

type Ingress struct {
common.ObjectMeta `json:"objectMeta"`
common.TypeMeta `json:"typeMeta"`
Endpoints []common.Endpoint `json:"endpoints"`
}

func getEndpoints(ingress *extensions.Ingress) []common.Endpoint {
endpoints := make([]common.Endpoint, 0)
if len(ingress.Status.LoadBalancer.Ingress) > 0 {
for _, status := range ingress.Status.LoadBalancer.Ingress {
endpoint := common.Endpoint{Host: status.IP}
endpoints = append(endpoints, endpoint)
}
}
return endpoints
}

func toIngress(ingress *extensions.Ingress) *Ingress {
modelIngress := &Ingress{
ObjectMeta: common.NewObjectMeta(ingress.ObjectMeta),
TypeMeta: common.NewTypeMeta("ingress"),
Endpoints: getEndpoints(ingress),
}
return modelIngress
}

func GetIngressPage(cli *kubernetes.Clientset, namespace string, q *backendCommon.QueryParam) (page *backendCommon.Page, err error) {
ingressPtrs, err := GetIngressList(cli, namespace, metaV1.ListOptions{})
if err != nil {
return nil, err
}
ingresses := make([]Ingress, len(ingressPtrs))
for i := range ingressPtrs {
ingresses[i] = *ingressPtrs[i]
}
return dataselector.DataSelectPage(toCells(ingresses), q), nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,45 @@ import (
)

func init() {

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

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

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

beego.GlobalControllerRouter["github.com/Qihoo360/wayne/src/backend/controllers/kubernetes/ingress:KubeIngressController"] = append(beego.GlobalControllerRouter["github.com/Qihoo360/wayne/src/backend/controllers/kubernetes/ingress:KubeIngressController"],
beego.ControllerComments{
Method: "Deploy",
Router: `/:ingressId/tpls/:tplId/clusters/:cluster`,
Router: `/:ingressId([0-9]+)/tpls/:tplId([0-9]+)/clusters/:cluster`,
AllowHTTPMethods: []string{"post"},
MethodParams: param.Make(),
Params: nil,
})
Params: nil})

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

}