diff --git a/src/backend/controllers/common/ingress.go b/src/backend/controllers/common/ingress.go new file mode 100644 index 000000000..a4095f7c9 --- /dev/null +++ b/src/backend/controllers/common/ingress.go @@ -0,0 +1,30 @@ +package common + +import ( + kapiv1beta1 "k8s.io/api/extensions/v1beta1" + + "github.com/Qihoo360/wayne/src/backend/models" +) + +func IngressPreDeploy(kubeIngress *kapiv1beta1.Ingress, cluster *models.Cluster, namespace *models.Namespace) { + preDefinedAnnotationMap := make(map[string]string) + + annotationResult := make(map[string]string, 0) + // user defined + for k, v := range kubeIngress.Annotations { + preDefinedAnnotationMap[k] = v + } + // cluster defined, overwrite user defined + for k, v := range cluster.MetaDataObj.IngressAnnotations { + preDefinedAnnotationMap[k] = v + } + // namespace defined, overwrite cluster and user defined + for k, v := range namespace.MetaDataObj.IngressAnnotations { + preDefinedAnnotationMap[k] = v + } + for k, v := range preDefinedAnnotationMap { + annotationResult[k] = v + } + + kubeIngress.Annotations = annotationResult +} diff --git a/src/backend/controllers/common/service.go b/src/backend/controllers/common/service.go new file mode 100644 index 000000000..d678e8e64 --- /dev/null +++ b/src/backend/controllers/common/service.go @@ -0,0 +1,30 @@ +package common + +import ( + "k8s.io/api/core/v1" + + "github.com/Qihoo360/wayne/src/backend/models" +) + +func ServicePreDeploy(kubeService *v1.Service, cluster *models.Cluster, namespace *models.Namespace) { + preDefinedAnnotationMap := make(map[string]string) + + annotationResult := make(map[string]string, 0) + // user defined + for k, v := range kubeService.Annotations { + preDefinedAnnotationMap[k] = v + } + // cluster defined, overwrite user defined + for k, v := range cluster.MetaDataObj.ServiceAnnotations { + preDefinedAnnotationMap[k] = v + } + // namespace defined, overwrite cluster and user defined + for k, v := range namespace.MetaDataObj.ServiceAnnotations { + preDefinedAnnotationMap[k] = v + } + for k, v := range preDefinedAnnotationMap { + annotationResult[k] = v + } + + kubeService.Annotations = annotationResult +} diff --git a/src/backend/controllers/kubernetes/deployment/deployment.go b/src/backend/controllers/kubernetes/deployment/deployment.go index 2a7d036b0..7c41ccc57 100644 --- a/src/backend/controllers/kubernetes/deployment/deployment.go +++ b/src/backend/controllers/kubernetes/deployment/deployment.go @@ -18,7 +18,6 @@ import ( "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" ) @@ -133,7 +132,7 @@ func (c *KubeDeploymentController) Deploy() { cluster := c.Ctx.Input.Param(":cluster") cli, err := client.Client(cluster) if err == nil { - namespaceModel, err := getNamespace(c.AppId) + namespaceModel, err := models.NamespaceModel.GetNamespaceByAppId(c.AppId) if err != nil { logs.Error("get getNamespaceMetaData error.%v", err) c.HandleError(err) @@ -261,28 +260,6 @@ func checkResourceAvailable(ns *models.Namespace, cli *kubernetes.Clientset, kub return nil } -func getNamespace(appId int64) (*models.Namespace, error) { - app, err := models.AppModel.GetById(appId) - if err != nil { - logs.Warning("get app by id (%d) error. %v", appId, err) - return nil, err - } - - ns, err := models.NamespaceModel.GetById(app.Namespace.Id) - if err != nil { - logs.Warning("get namespace by id (%d) error. %v", app.Namespace.Id, err) - return nil, err - } - var namespaceMetaData models.NamespaceMetaData - err = json.Unmarshal(hack.Slice(ns.MetaData), &namespaceMetaData) - if err != nil { - logs.Error("Unmarshal namespace metadata (%s) error. %v", ns.MetaData, err) - return nil, err - } - ns.MetaDataObj = namespaceMetaData - return ns, nil -} - // @Title Get // @Description find Deployment by cluster // @Param cluster path string true "the cluster name" diff --git a/src/backend/controllers/kubernetes/ingress/ingress.go b/src/backend/controllers/kubernetes/ingress/ingress.go index e83bc3949..d53218810 100644 --- a/src/backend/controllers/kubernetes/ingress/ingress.go +++ b/src/backend/controllers/kubernetes/ingress/ingress.go @@ -7,6 +7,7 @@ import ( "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/resources/ingress" @@ -92,6 +93,24 @@ func (c *KubeIngressController) Deploy() { c.AbortBadRequestFormat("Cluster") return } + + namespaceModel, err := models.NamespaceModel.GetNamespaceByAppId(c.AppId) + if err != nil { + logs.Error("get getNamespaceMetaData error.%v", err) + c.HandleError(err) + return + } + + clusterModel, err := models.ClusterModel.GetParsedMetaDataByName(clusterName) + if err != nil { + logs.Error("get cluster error.%v", err) + c.HandleError(err) + return + } + + // add ingress predeploy + common.IngressPreDeploy(&kubeIngress, clusterModel, namespaceModel) + publishHistory := &models.PublishHistory{ Type: models.PublishTypeIngress, ResourceId: int64(ingressId), diff --git a/src/backend/controllers/kubernetes/service/service.go b/src/backend/controllers/kubernetes/service/service.go index e24634707..cb0b88902 100644 --- a/src/backend/controllers/kubernetes/service/service.go +++ b/src/backend/controllers/kubernetes/service/service.go @@ -12,6 +12,7 @@ import ( "github.com/Qihoo360/wayne/src/backend/resources/service" "github.com/Qihoo360/wayne/src/backend/util/logs" "github.com/Qihoo360/wayne/src/backend/workers/webhook" + "github.com/Qihoo360/wayne/src/backend/controllers/common" ) type KubeServiceController struct { @@ -113,6 +114,24 @@ func (c *KubeServiceController) Deploy() { cluster := c.Ctx.Input.Param(":cluster") cli, err := client.Client(cluster) if err == nil { + namespaceModel, err := models.NamespaceModel.GetNamespaceByAppId(c.AppId) + if err != nil { + logs.Error("get getNamespaceMetaData error.%v", err) + c.HandleError(err) + return + } + + clusterModel, err := models.ClusterModel.GetParsedMetaDataByName(cluster) + if err != nil { + logs.Error("get cluster error.%v", err) + c.HandleError(err) + return + } + + // add service predeploy + common.ServicePreDeploy(&kubeService, clusterModel, namespaceModel) + + publishHistory := &models.PublishHistory{ Type: models.PublishTypeService, ResourceId: int64(serviceId), diff --git a/src/backend/models/cluster.go b/src/backend/models/cluster.go index 02411db7e..b51d9e929 100644 --- a/src/backend/models/cluster.go +++ b/src/backend/models/cluster.go @@ -79,10 +79,14 @@ type ClusterMetaData struct { RBD *v1.RBDVolumeSource `json:"rbd"` // cephfs默认配置,创建或修改cephfs类型的PV时会使用此配置填充 CephFS *v1.CephFSVolumeSource `json:"cephfs"` - // 默认添加环境变量,会在发布资源时在每个Container添加此环境变量, will be overwrite by namespace's ImagePullSecrets + // 默认添加环境变量,会在发布资源时在每个Container添加此环境变量, will be overwrite by namespace's Env Env []v1.EnvVar // current cluster image pull secrets, will be overwrite by namespace's ImagePullSecrets ImagePullSecrets []v1.LocalObjectReference `json:"imagePullSecrets"` + // 默认添加service注解,会在发布资源时在每个service添加此Annotations, will be overwrite by namespace's Annotations + ServiceAnnotations map[string]string `json:"serviceAnnotations,omitempty"` + // 默认添加ingress注解,会在发布资源时在每个ingress添加此Annotations, will be overwrite by namespace's Annotations + IngressAnnotations map[string]string `json:"ingressAnnotations,omitempty"` } type ClusterRobinMetaData struct { diff --git a/src/backend/models/namespace.go b/src/backend/models/namespace.go index 3cb437101..180252142 100644 --- a/src/backend/models/namespace.go +++ b/src/backend/models/namespace.go @@ -1,10 +1,15 @@ package models import ( + "encoding/json" "fmt" "time" "k8s.io/api/core/v1" + + "github.com/Qihoo360/wayne/src/backend/util/hack" + "github.com/Qihoo360/wayne/src/backend/util/logs" + ) const ( @@ -49,6 +54,10 @@ type NamespaceMetaData struct { Env []v1.EnvVar `json:"env,omitempty"` // current namespace image pull secrets, will overwrite cluster's ImagePullSecrets ImagePullSecrets []v1.LocalObjectReference `json:"imagePullSecrets"` + // current namespace service annotation, will overwrite cluster service's Annotation + ServiceAnnotations map[string]string `json:"serviceAnnotations,omitempty"` + // current namespace ingress annotation, will overwrite cluster ingress's Annotation + IngressAnnotations map[string]string `json:"ingressAnnotations,omitempty"` } type ClusterMeta struct { @@ -160,3 +169,25 @@ func (*namespaceModel) InitNamespace() (err error) { _, _, err = Ormer().ReadOrCreate(&defaultNS, "Name") return } + +func (*namespaceModel) GetNamespaceByAppId(appId int64) (*Namespace, error) { + app, err := AppModel.GetById(appId) + if err != nil { + logs.Warning("get app by id (%d) error. %v", appId, err) + return nil, err + } + + ns, err := NamespaceModel.GetById(app.Namespace.Id) + if err != nil { + logs.Warning("get namespace by id (%d) error. %v", app.Namespace.Id, err) + return nil, err + } + var namespaceMetaData NamespaceMetaData + err = json.Unmarshal(hack.Slice(ns.MetaData), &namespaceMetaData) + if err != nil { + logs.Error("Unmarshal namespace metadata (%s) error. %v", ns.MetaData, err) + return nil, err + } + ns.MetaDataObj = namespaceMetaData + return ns, nil +}