Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unified processing of resources #160

Merged
10 changes: 6 additions & 4 deletions src/backend/controllers/auth/authenticator.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,17 @@ import (
"strings"
"time"

"github.com/astaxie/beego"
"github.com/dgrijalva/jwt-go"
"golang.org/x/oauth2"

rsakey "github.com/Qihoo360/wayne/src/backend/apikey"
"github.com/Qihoo360/wayne/src/backend/controllers/base"
"github.com/Qihoo360/wayne/src/backend/models"
"github.com/Qihoo360/wayne/src/backend/models/response/errors"
selfoauth "github.com/Qihoo360/wayne/src/backend/oauth2"
"github.com/Qihoo360/wayne/src/backend/util/hack"
"github.com/Qihoo360/wayne/src/backend/util/logs"
"github.com/astaxie/beego"
"github.com/dgrijalva/jwt-go"
"golang.org/x/oauth2"
)

// Authenticator provides interface to authenticate user credentials.
Expand Down Expand Up @@ -172,7 +174,7 @@ func (c *AuthController) CurrentUser() {
// we also only use its public counter part to verify
return rsakey.RsaPublicKey, nil
})
errResult := base.ErrorResult{}
errResult := errors.ErrorResult{}
switch err.(type) {
case nil: // no error
if !token.Valid { // but may still be invalid
Expand Down
6 changes: 4 additions & 2 deletions src/backend/controllers/base/logged.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ import (
"net/http"
"strings"

"github.com/dgrijalva/jwt-go"

rsakey "github.com/Qihoo360/wayne/src/backend/apikey"
"github.com/Qihoo360/wayne/src/backend/bus"
"github.com/Qihoo360/wayne/src/backend/bus/message"
"github.com/Qihoo360/wayne/src/backend/models"
"github.com/Qihoo360/wayne/src/backend/models/response/errors"
"github.com/Qihoo360/wayne/src/backend/util/hack"
"github.com/Qihoo360/wayne/src/backend/util/logs"
"github.com/dgrijalva/jwt-go"
)

var (
Expand Down Expand Up @@ -45,7 +47,7 @@ func (c *LoggedInController) Prepare() {
return rsakey.RsaPublicKey, nil
})

errResult := ErrorResult{}
errResult := errors.ErrorResult{}
switch err.(type) {
case nil: // no error
if !token.Valid { // but may still be invalid
Expand Down
27 changes: 7 additions & 20 deletions src/backend/controllers/base/resulthandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ import (
"fmt"
"net/http"

"github.com/Qihoo360/wayne/src/backend/util/hack"
"github.com/Qihoo360/wayne/src/backend/util/logs"
"github.com/astaxie/beego"
"github.com/astaxie/beego/orm"
"github.com/go-sql-driver/mysql"
"k8s.io/apimachinery/pkg/api/errors"

erroresult "github.com/Qihoo360/wayne/src/backend/models/response/errors"
"github.com/Qihoo360/wayne/src/backend/util/hack"
"github.com/Qihoo360/wayne/src/backend/util/logs"
)

type ResultHandlerController struct {
Expand All @@ -21,21 +23,6 @@ type Result struct {
Data interface{} `json:"data"`
}

var _ error = &ErrorResult{}

// Error implements the Error interface.
func (e *ErrorResult) Error() string {
return fmt.Sprintf("code:%d,subCode:%d,msg:%s", e.Code, e.SubCode, e.Msg)
}

type ErrorResult struct {
// http code
Code int `json:"code"`
// The custom code
SubCode int `json:"subCode"`
Msg string `json:"msg"`
}

func (c *ResultHandlerController) Success(data interface{}) {
c.Ctx.Output.SetStatus(http.StatusOK)
c.Data["json"] = Result{Data: data}
Expand Down Expand Up @@ -72,7 +59,7 @@ func (c *ResultHandlerController) AbortUnauthorized(msg string) {

// Handle return http code and body normally, need return
func (c *ResultHandlerController) HandleError(err error) int {
errorResult := &ErrorResult{
errorResult := &erroresult.ErrorResult{
Code: http.StatusInternalServerError,
}
switch e := err.(type) {
Expand All @@ -91,7 +78,7 @@ func (c *ResultHandlerController) HandleError(err error) int {
} else {
errorResult.Msg = e.Message
}
case *ErrorResult:
case *erroresult.ErrorResult:
errorResult = e
default:
if err == orm.ErrNoRows {
Expand Down Expand Up @@ -120,7 +107,7 @@ func (c *ResultHandlerController) HandleError(err error) int {
}

func (c *ResultHandlerController) errorResult(code int, msg string) []byte {
errorResult := ErrorResult{
errorResult := erroresult.ErrorResult{
Code: code,
Msg: msg,
}
Expand Down
14 changes: 8 additions & 6 deletions src/backend/controllers/kubernetes/deployment/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,22 @@ import (
"fmt"
"net/http"

"k8s.io/api/apps/v1beta1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/kubernetes"

"github.com/Qihoo360/wayne/src/backend/client"
"github.com/Qihoo360/wayne/src/backend/controllers/base"
"github.com/Qihoo360/wayne/src/backend/controllers/common"
"github.com/Qihoo360/wayne/src/backend/models"
"github.com/Qihoo360/wayne/src/backend/models/response"
"github.com/Qihoo360/wayne/src/backend/models/response/errors"
"github.com/Qihoo360/wayne/src/backend/resources/deployment"
"github.com/Qihoo360/wayne/src/backend/resources/namespace"
"github.com/Qihoo360/wayne/src/backend/util"
"github.com/Qihoo360/wayne/src/backend/util/hack"
"github.com/Qihoo360/wayne/src/backend/util/logs"
"github.com/Qihoo360/wayne/src/backend/workers/webhook"
"k8s.io/api/apps/v1beta1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/kubernetes"
)

type KubeDeploymentController struct {
Expand Down Expand Up @@ -218,7 +220,7 @@ func checkResourceAvailable(ns *models.Namespace, cli *kubernetes.Clientset, kub
// this namespace can't use current cluster.
clusterMetas, ok := ns.MetaDataObj.ClusterMetas[cluster]
if !ok {
return &base.ErrorResult{
return &errors.ErrorResult{
Code: http.StatusForbidden,
SubCode: http.StatusForbidden,
Msg: fmt.Sprintf("Current namespace (%s) can't use current cluster (%s).Please contact administrator. ", ns.Name, cluster),
Expand All @@ -240,7 +242,7 @@ func checkResourceAvailable(ns *models.Namespace, cli *kubernetes.Clientset, kub

if clusterMetas.ResourcesLimit.Memory != 0 &&
clusterMetas.ResourcesLimit.Memory-(namespaceResourceUsed.Memory+requestResourceList.Memory)/1024 < 0 {
return &base.ErrorResult{
return &errors.ErrorResult{
Code: http.StatusForbidden,
SubCode: base.ErrorSubCodeInsufficientResource,
Msg: fmt.Sprintf("request namespace resource (memory:%dGi) is not enough for this deploy", requestResourceList.Memory/1024),
Expand All @@ -249,7 +251,7 @@ func checkResourceAvailable(ns *models.Namespace, cli *kubernetes.Clientset, kub

if clusterMetas.ResourcesLimit.Cpu != 0 &&
clusterMetas.ResourcesLimit.Cpu-(namespaceResourceUsed.Cpu+requestResourceList.Cpu)/1000 < 0 {
return &base.ErrorResult{
return &errors.ErrorResult{
Code: http.StatusForbidden,
SubCode: base.ErrorSubCodeInsufficientResource,
Msg: fmt.Sprintf("request namespace resource (cpu:%d) is not enough for this deploy", requestResourceList.Cpu/1000),
Expand Down
14 changes: 8 additions & 6 deletions src/backend/controllers/kubernetes/statefulset/statefulset.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,19 @@ import (
"fmt"
"net/http"

"k8s.io/api/apps/v1beta1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/kubernetes"

"github.com/Qihoo360/wayne/src/backend/client"
"github.com/Qihoo360/wayne/src/backend/controllers/base"
"github.com/Qihoo360/wayne/src/backend/models"
"github.com/Qihoo360/wayne/src/backend/models/response/errors"
"github.com/Qihoo360/wayne/src/backend/resources/namespace"
"github.com/Qihoo360/wayne/src/backend/resources/statefulset"
"github.com/Qihoo360/wayne/src/backend/util"
"github.com/Qihoo360/wayne/src/backend/util/hack"
"github.com/Qihoo360/wayne/src/backend/util/logs"
"k8s.io/api/apps/v1beta1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/kubernetes"
)

type KubeStatefulsetController struct {
Expand Down Expand Up @@ -154,7 +156,7 @@ func checkResourceAvailable(ns *models.Namespace, cli *kubernetes.Clientset, kub
// this namespace can't use current cluster.
clusterMetas, ok := ns.MetaDataObj.ClusterMetas[cluster]
if !ok {
return &base.ErrorResult{
return &errors.ErrorResult{
Code: http.StatusForbidden,
SubCode: http.StatusForbidden,
Msg: fmt.Sprintf("Current namespace (%s) can't use current cluster (%s).Please contact administrator. ", ns.Name, cluster),
Expand All @@ -175,7 +177,7 @@ func checkResourceAvailable(ns *models.Namespace, cli *kubernetes.Clientset, kub

if clusterMetas.ResourcesLimit.Memory != 0 &&
clusterMetas.ResourcesLimit.Memory-(namespaceResourceUsed.Memory+requestResourceList.Memory)/1024 < 0 {
return &base.ErrorResult{
return &errors.ErrorResult{
Code: http.StatusForbidden,
SubCode: base.ErrorSubCodeInsufficientResource,
Msg: fmt.Sprintf("request namespace resource (memory:%dGi) is not enough for this deploy", requestResourceList.Memory/1024),
Expand All @@ -184,7 +186,7 @@ func checkResourceAvailable(ns *models.Namespace, cli *kubernetes.Clientset, kub

if clusterMetas.ResourcesLimit.Cpu != 0 &&
clusterMetas.ResourcesLimit.Cpu-(namespaceResourceUsed.Cpu+requestResourceList.Cpu)/1000 < 0 {
return &base.ErrorResult{
return &errors.ErrorResult{
Code: http.StatusForbidden,
SubCode: base.ErrorSubCodeInsufficientResource,
Msg: fmt.Sprintf("request namespace resource (cpu:%d) is not enough for this deploy", requestResourceList.Cpu/1000),
Expand Down
18 changes: 18 additions & 0 deletions src/backend/models/response/errors/errorresult.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package errors

import "fmt"

var _ error = &ErrorResult{}

// Error implements the Error interface.
func (e *ErrorResult) Error() string {
return fmt.Sprintf("code:%d,subCode:%d,msg:%s", e.Code, e.SubCode, e.Msg)
}

type ErrorResult struct {
// http code
Code int `json:"code"`
// The custom code
SubCode int `json:"subCode"`
Msg string `json:"msg"`
}
50 changes: 46 additions & 4 deletions src/backend/resources/deployment/deployment.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
package deployment

import (
"github.com/Qihoo360/wayne/src/backend/client"
"github.com/Qihoo360/wayne/src/backend/resources/common"
"github.com/Qihoo360/wayne/src/backend/resources/event"
"github.com/Qihoo360/wayne/src/backend/resources/pod"
"fmt"
"net/http"

"k8s.io/api/apps/v1beta1"
"k8s.io/apimachinery/pkg/api/errors"
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"

"github.com/Qihoo360/wayne/src/backend/client"
erroresult "github.com/Qihoo360/wayne/src/backend/models/response/errors"
"github.com/Qihoo360/wayne/src/backend/resources/common"
"github.com/Qihoo360/wayne/src/backend/resources/event"
"github.com/Qihoo360/wayne/src/backend/resources/pod"
"github.com/Qihoo360/wayne/src/backend/util/maps"
)

type Deployment struct {
Expand Down Expand Up @@ -51,16 +57,52 @@ func CreateOrUpdateDeployment(cli *kubernetes.Clientset, deployment *v1beta1.Dep
}
return nil, err
}
err = checkDeploymentLabelSelector(deployment, old)
if err != nil {
return nil, err
}

old.Labels = deployment.Labels
old.Annotations = deployment.Annotations
old.Spec = deployment.Spec

return cli.AppsV1beta1().Deployments(deployment.Namespace).Update(old)
}

func UpdateDeployment(cli *kubernetes.Clientset, deployment *v1beta1.Deployment) (*v1beta1.Deployment, error) {
old, err := cli.AppsV1beta1().Deployments(deployment.Namespace).Get(deployment.Name, metaV1.GetOptions{})
if err != nil {
return nil, err
}

err = checkDeploymentLabelSelector(deployment, old)
if err != nil {
return nil, err
}

return cli.AppsV1beta1().Deployments(deployment.Namespace).Update(deployment)
}

// check Deployment .Spec.Selector.MatchLabels, prevent orphan ReplicaSet
// old deployment .Spec.Selector.MatchLabels labels should contain all new deployment .Spec.Selector.MatchLabels labels
// e.g. old Deployment .Spec.Selector.MatchLabels is app = infra-wayne,wayne-app = infra
// new Deployment .Spec.Selector.MatchLabels valid labels is
// app = infra-wayne or wayne-app = infra or app = infra-wayne,wayne-app = infra
func checkDeploymentLabelSelector(new *v1beta1.Deployment, old *v1beta1.Deployment) error {
for key, value := range new.Spec.Selector.MatchLabels {
oldValue, ok := old.Spec.Selector.MatchLabels[key]
if !ok || oldValue != value {
return &erroresult.ErrorResult{
Code: http.StatusBadRequest,
Msg: fmt.Sprintf("New's Deployment MatchLabels(%s) not match old MatchLabels(%s), do not allow deploy to prevent the orphan ReplicaSet. ",
maps.LabelsToString(new.Spec.Selector.MatchLabels), maps.LabelsToString(old.Spec.Selector.MatchLabels)),
}
}
}

return nil
}

func GetDeployment(cli *kubernetes.Clientset, name, namespace string) (*v1beta1.Deployment, error) {
return cli.AppsV1beta1().Deployments(namespace).Get(name, metaV1.GetOptions{})
}
Expand Down
15 changes: 15 additions & 0 deletions src/backend/util/maps/maps.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package maps

import (
"fmt"
"strings"
)

// merge label
// the new map will overwrite the old one.
// e.g. new: {"foo": "newbar"} old: {"foo": "bar"} will return {"foo": "newbar"}
Expand All @@ -17,3 +22,13 @@ func MergeLabels(old map[string]string, new map[string]string) map[string]string
}
return old
}

func LabelsToString(labels map[string]string) string {
wilhelmguo marked this conversation as resolved.
Show resolved Hide resolved
result := make([]string, 0)
for k, v := range labels {
result = append(result, fmt.Sprintf("%s=%s", k, v))

}

return strings.Join(result, ",")
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,6 @@ <h3 class="modal-title">迁移部署到[{{cluster}}]机房
<wayne-modal-operate [modal]="modal" *ngIf="modalOpened"></wayne-modal-operate>
</h3>
<div class="modal-body">
<div class="alert alert-warning" *ngIf="warningMsg">
<div class="alert-items">
<div class="alert-item static">
<div class="alert-icon-wrapper">
<clr-icon class="alert-icon" shape="exclamation-circle"></clr-icon>
</div>
<span class="alert-text">
{{warningMsg}}
</span>
</div>
</div>
</div>
<form #ngForm="ngForm">
<section class="form-block">
<div class="form-group" style="padding-left: 135px;">
Expand Down
Loading