diff --git a/api/controller/application.go b/api/controller/application.go index fafff80a9..a3bb2befa 100644 --- a/api/controller/application.go +++ b/api/controller/application.go @@ -1,6 +1,8 @@ package controller import ( + "fmt" + k8svalidation "k8s.io/apimachinery/pkg/util/validation" "net/http" "strconv" @@ -40,12 +42,17 @@ func (a *ApplicationController) CreateApp(w http.ResponseWriter, r *http.Request httputil.ReturnBcodeError(r, w, bcode.NewBadRequest("the field 'version' is required")) return } + tenantReq.K8sApp = tenantReq.AppTemplateName + } + if tenantReq.K8sApp != "" { + if len(k8svalidation.IsQualifiedName(tenantReq.K8sApp)) > 0 { + httputil.ReturnBcodeError(r, w, bcode.ErrInvaildK8sApp) + return + } } - // get current tenant tenant := r.Context().Value(ctxutil.ContextKey("tenant")).(*dbmodel.Tenants) tenantReq.TenantID = tenant.UUID - // create app app, err := handler.GetApplicationHandler().CreateApp(r.Context(), &tenantReq) if err != nil { @@ -81,7 +88,13 @@ func (a *ApplicationController) UpdateApp(w http.ResponseWriter, r *http.Request return } app := r.Context().Value(ctxutil.ContextKey("application")).(*dbmodel.Application) - + if app.K8sApp == "" && updateAppReq.K8sApp == "" { + updateAppReq.K8sApp = fmt.Sprintf("app-%s", app.AppID[:8]) + } + if updateAppReq.K8sApp != "" && len(k8svalidation.IsQualifiedName(updateAppReq.K8sApp)) > 0 { + httputil.ReturnBcodeError(r, w, bcode.ErrInvaildK8sApp) + return + } // update app app, err := handler.GetApplicationHandler().UpdateApp(r.Context(), app, updateAppReq) if err != nil { diff --git a/api/controller/pods.go b/api/controller/pods.go index 87a6f8ee4..1311d52e6 100644 --- a/api/controller/pods.go +++ b/api/controller/pods.go @@ -99,8 +99,8 @@ func PodNums(w http.ResponseWriter, r *http.Request) { // PodDetail - func (p *PodController) PodDetail(w http.ResponseWriter, r *http.Request) { podName := chi.URLParam(r, "pod_name") - namespace := r.Context().Value(ctxutil.ContextKey("tenant_id")).(string) - pd, err := handler.GetPodHandler().PodDetail(namespace, podName) + tenant := r.Context().Value(ctxutil.ContextKey("tenant")).(*model.Tenants) + pd, err := handler.GetPodHandler().PodDetail(tenant.Namespace, podName) if err != nil { logrus.Errorf("error getting pod detail: %v", err) if err == server.ErrPodNotFound { diff --git a/api/controller/resources.go b/api/controller/resources.go index 308482e78..2ca7e5eeb 100644 --- a/api/controller/resources.go +++ b/api/controller/resources.go @@ -457,6 +457,10 @@ func (t *TenantStruct) AddTenant(w http.ResponseWriter, r *http.Request) { id = ts.Body.TenantID } dbts.LimitMemory = ts.Body.LimitMemory + dbts.Namespace = dbts.UUID + if ts.Body.Namespace != "" { + dbts.Namespace = ts.Body.Namespace + } if err := handler.GetServiceManager().CreateTenant(&dbts); err != nil { if strings.HasSuffix(err.Error(), "is exist") { httputil.ReturnError(r, w, 400, err.Error()) @@ -469,6 +473,7 @@ func (t *TenantStruct) AddTenant(w http.ResponseWriter, r *http.Request) { rc["tenant_id"] = id rc["tenang_name"] = name rc["eid"] = ts.Body.Eid + rc["namespace"] = dbts.Namespace httputil.ReturnSuccess(r, w, rc) return } @@ -476,6 +481,10 @@ func (t *TenantStruct) AddTenant(w http.ResponseWriter, r *http.Request) { //兼容旧接口 dbts.Name = ts.Body.TenantName dbts.UUID = ts.Body.TenantID + dbts.Namespace = ts.Body.TenantID + if ts.Body.Namespace != "" { + dbts.Namespace = ts.Body.Namespace + } if err := handler.GetServiceManager().CreateTenant(&dbts); err != nil { if strings.HasSuffix(err.Error(), "is exist") { httputil.ReturnError(r, w, 400, err.Error()) @@ -716,12 +725,13 @@ func (t *TenantStruct) UpdateService(w http.ResponseWriter, r *http.Request) { // description: 统一返回格式 //目前提供三个元素的修改 rules := validator.MapData{ - "container_cmd": []string{}, - "image_name": []string{}, - "container_memory": []string{}, - "service_name": []string{}, - "extend_method": []string{}, - "app_id": []string{}, + "container_cmd": []string{}, + "image_name": []string{}, + "container_memory": []string{}, + "service_name": []string{}, + "extend_method": []string{}, + "app_id": []string{}, + "k8s_component_name": []string{}, } data, ok := httputil.ValidatorRequestMapAndErrorResponse(r, w, rules, nil) if !ok { diff --git a/api/handler/application_handler.go b/api/handler/application_handler.go index 96772126c..17286c35d 100644 --- a/api/handler/application_handler.go +++ b/api/handler/application_handler.go @@ -77,20 +77,28 @@ func NewApplicationHandler(statusCli *client.AppRuntimeSyncClient, promClient pr // CreateApp - func (a *ApplicationAction) CreateApp(ctx context.Context, req *model.Application) (*model.Application, error) { + appID := util.NewUUID() + if req.K8sApp == "" { + req.K8sApp = fmt.Sprintf("app-%s", appID[:8]) + } appReq := &dbmodel.Application{ EID: req.EID, TenantID: req.TenantID, - AppID: util.NewUUID(), + AppID: appID, AppName: req.AppName, AppType: req.AppType, AppStoreName: req.AppStoreName, AppStoreURL: req.AppStoreURL, AppTemplateName: req.AppTemplateName, Version: req.Version, + K8sApp: req.K8sApp, } req.AppID = appReq.AppID err := db.GetManager().DB().Transaction(func(tx *gorm.DB) error { + if db.GetManager().ApplicationDaoTransactions(tx).IsK8sAppDuplicate(appReq.TenantID, appID, appReq.K8sApp) { + return bcode.ErrK8sAppExists + } if err := db.GetManager().ApplicationDaoTransactions(tx).AddModel(appReq); err != nil { return err } @@ -114,10 +122,14 @@ func (a *ApplicationAction) createHelmApp(ctx context.Context, app *dbmodel.Appl labels := map[string]string{ constants.ResourceManagedByLabel: constants.Rainbond, } + tenant, err := GetTenantManager().GetTenantsByUUID(app.TenantID) + if err != nil { + return errors.Wrap(err, "get tenant for helm app failed") + } helmApp := &v1alpha1.HelmApp{ ObjectMeta: metav1.ObjectMeta{ Name: app.AppName, - Namespace: app.TenantID, + Namespace: tenant.Namespace, Labels: labels, }, Spec: v1alpha1.HelmAppSpec{ @@ -129,12 +141,11 @@ func (a *ApplicationAction) createHelmApp(ctx context.Context, app *dbmodel.Appl URL: app.AppStoreURL, }, }} - ctx1, cancel := context.WithTimeout(ctx, 3*time.Second) defer cancel() - _, err := a.kubeClient.CoreV1().Namespaces().Create(ctx1, &corev1.Namespace{ + _, err = a.kubeClient.CoreV1().Namespaces().Create(ctx1, &corev1.Namespace{ ObjectMeta: metav1.ObjectMeta{ - Name: app.TenantID, + Name: tenant.Namespace, Labels: labels, }, }, metav1.CreateOptions{}) @@ -186,12 +197,15 @@ func (a *ApplicationAction) UpdateApp(ctx context.Context, app *dbmodel.Applicat } app.GovernanceMode = req.GovernanceMode } + app.K8sApp = req.K8sApp err := db.GetManager().DB().Transaction(func(tx *gorm.DB) error { - if err := db.GetManager().ApplicationDao().UpdateModel(app); err != nil { + if db.GetManager().ApplicationDaoTransactions(tx).IsK8sAppDuplicate(app.TenantID, app.AppID, req.K8sApp) { + return bcode.ErrK8sAppExists + } + if err := db.GetManager().ApplicationDaoTransactions(tx).UpdateModel(app); err != nil { return err } - if req.NeedUpdateHelmApp() { if err := a.updateHelmApp(ctx, app, req); err != nil { return err @@ -205,9 +219,13 @@ func (a *ApplicationAction) UpdateApp(ctx context.Context, app *dbmodel.Applicat } func (a *ApplicationAction) updateHelmApp(ctx context.Context, app *dbmodel.Application, req model.UpdateAppRequest) error { + tenant, err := GetTenantManager().GetTenantsByUUID(app.TenantID) + if err != nil { + return errors.Wrap(err, "get tenant for helm app failed") + } ctx, cancel := context.WithTimeout(ctx, 5*time.Second) defer cancel() - helmApp, err := a.rainbondClient.RainbondV1alpha1().HelmApps(app.TenantID).Get(ctx, app.AppName, metav1.GetOptions{}) + helmApp, err := a.rainbondClient.RainbondV1alpha1().HelmApps(tenant.Namespace).Get(ctx, app.AppName, metav1.GetOptions{}) if err != nil { if k8sErrors.IsNotFound(err) { return errors.Wrap(bcode.ErrApplicationNotFound, "update app") @@ -221,7 +239,7 @@ func (a *ApplicationAction) updateHelmApp(ctx context.Context, app *dbmodel.Appl if req.Revision != 0 { helmApp.Spec.Revision = req.Revision } - _, err = a.rainbondClient.RainbondV1alpha1().HelmApps(app.TenantID).Update(ctx, helmApp, metav1.UpdateOptions{}) + _, err = a.rainbondClient.RainbondV1alpha1().HelmApps(tenant.Namespace).Update(ctx, helmApp, metav1.UpdateOptions{}) return err } @@ -288,13 +306,16 @@ func (a *ApplicationAction) isContainComponents(appID string) error { func (a *ApplicationAction) deleteHelmApp(ctx context.Context, app *dbmodel.Application) error { ctx, cancel := context.WithTimeout(ctx, 5*time.Second) defer cancel() - + tenant, err := GetTenantManager().GetTenantsByUUID(app.TenantID) + if err != nil { + return errors.Wrap(err, "get tenant for helm app failed") + } return db.GetManager().DB().Transaction(func(tx *gorm.DB) error { if err := a.deleteApp(tx, app); err != nil { return err } - if err := a.rainbondClient.RainbondV1alpha1().HelmApps(app.TenantID).Delete(ctx, app.AppName, metav1.DeleteOptions{}); err != nil { + if err := a.rainbondClient.RainbondV1alpha1().HelmApps(tenant.Namespace).Delete(ctx, app.AppName, metav1.DeleteOptions{}); err != nil { if !k8sErrors.IsNotFound(err) { return err } @@ -450,8 +471,11 @@ func (a *ApplicationAction) GetStatus(ctx context.Context, app *dbmodel.Applicat func (a *ApplicationAction) Install(ctx context.Context, app *dbmodel.Application, overrides []string) error { ctx1, cancel := context.WithTimeout(ctx, 3*time.Second) defer cancel() - - helmApp, err := a.rainbondClient.RainbondV1alpha1().HelmApps(app.TenantID).Get(ctx1, app.AppName, metav1.GetOptions{}) + tenant, err := db.GetManager().TenantDao().GetTenantByUUID(app.TenantID) + if err != nil { + return errors.Wrap(err, "install app") + } + helmApp, err := a.rainbondClient.RainbondV1alpha1().HelmApps(tenant.Namespace).Get(ctx1, app.AppName, metav1.GetOptions{}) if err != nil { if k8sErrors.IsNotFound(err) { return errors.Wrap(bcode.ErrApplicationNotFound, "install app") @@ -463,7 +487,7 @@ func (a *ApplicationAction) Install(ctx context.Context, app *dbmodel.Applicatio defer cancel() helmApp.Spec.Overrides = overrides helmApp.Spec.PreStatus = v1alpha1.HelmAppPreStatusConfigured - _, err = a.rainbondClient.RainbondV1alpha1().HelmApps(app.TenantID).Update(ctx3, helmApp, metav1.UpdateOptions{}) + _, err = a.rainbondClient.RainbondV1alpha1().HelmApps(tenant.Namespace).Update(ctx3, helmApp, metav1.UpdateOptions{}) if err != nil { return err } diff --git a/api/handler/service.go b/api/handler/service.go index dbcf796e5..51ff7a86a 100644 --- a/api/handler/service.go +++ b/api/handler/service.go @@ -22,6 +22,7 @@ import ( "context" "encoding/json" "fmt" + "github.com/goodrain/rainbond/util/constants" "io" "net/http" "os" @@ -548,6 +549,11 @@ func (s *ServiceAction) ServiceCreate(sc *api_model.ServiceStruct) error { if ts.ContainerGPU < 0 { ts.ContainerGPU = 0 } + if ts.K8sComponentName != "" { + if db.GetManager().TenantServiceDao().IsK8sComponentNameDuplicate(ts.AppID, ts.ServiceID, ts.K8sComponentName) { + return bcode.ErrK8sComponentNameExists + } + } ts.UpdateTime = time.Now() var ( ports = sc.PortsInfo @@ -896,6 +902,12 @@ func (s *ServiceAction) ServiceUpdate(sc map[string]interface{}) error { if appID, ok := sc["app_id"].(string); ok && appID != "" { ts.AppID = appID } + if k8s_component_name, ok := sc["k8s_component_name"].(string); ok && k8s_component_name != "" { + if db.GetManager().TenantServiceDao().IsK8sComponentNameDuplicate(ts.AppID, ts.ServiceID, k8s_component_name) { + return bcode.ErrK8sComponentNameExists + } + ts.K8sComponentName = k8s_component_name + } if sc["extend_method"] != nil { extendMethod := sc["extend_method"].(string) ts.ExtendMethod = extendMethod @@ -1996,27 +2008,32 @@ func (s *ServiceAction) GetEnterpriseRunningServices(enterpriseID string) ([]str //CreateTenant create tenant func (s *ServiceAction) CreateTenant(t *dbmodel.Tenants) error { - if ten, _ := db.GetManager().TenantDao().GetTenantIDByName(t.Name); ten != nil { + tenant, _ := db.GetManager().TenantDao().GetTenantIDByName(t.Name) + if tenant != nil { return fmt.Errorf("tenant name %s is exist", t.Name) } - tx := db.GetManager().Begin() - defer func() { - if r := recover(); r != nil { - logrus.Errorf("Unexpected panic occurred, rollback transaction: %v", r) - tx.Rollback() + labels := map[string]string{ + constants.ResourceManagedByLabel: constants.Rainbond, + } + return db.GetManager().DB().Transaction(func(tx *gorm.DB) error { + if err := db.GetManager().TenantDaoTransactions(tx).AddModel(t); err != nil { + if !strings.HasSuffix(err.Error(), "is exist") { + return err + } } - }() - if err := db.GetManager().TenantDaoTransactions(tx).AddModel(t); err != nil { - if !strings.HasSuffix(err.Error(), "is exist") { - tx.Rollback() + if _, err := s.kubeClient.CoreV1().Namespaces().Create(context.Background(), &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: t.Namespace, + Labels: labels, + }, + }, metav1.CreateOptions{}); err != nil { + if k8sErrors.IsAlreadyExists(err) { + return bcode.ErrNamespaceExists + } return err } - } - if err := tx.Commit().Error; err != nil { - tx.Rollback() - return err - } - return nil + return nil + }) } //CreateTenandIDAndName create tenant_id and tenant_name @@ -2276,7 +2293,10 @@ func (s *ServiceAction) deleteThirdComponent(ctx context.Context, component *dbm if component.Kind != "third_party" { return nil } - + tenant, err := db.GetManager().TenantDao().GetTenantByUUID(component.TenantID) + if err != nil { + return err + } thirdPartySvcDiscoveryCfg, err := db.GetManager().ThirdPartySvcDiscoveryCfgDao().GetByServiceID(component.ServiceID) if err != nil { return err @@ -2291,7 +2311,7 @@ func (s *ServiceAction) deleteThirdComponent(ctx context.Context, component *dbm newCtx, cancel := context.WithTimeout(ctx, 3*time.Second) defer cancel() - err = s.rainbondClient.RainbondV1alpha1().ThirdComponents(component.TenantID).Delete(newCtx, component.ServiceID, metav1.DeleteOptions{}) + err = s.rainbondClient.RainbondV1alpha1().ThirdComponents(tenant.Namespace).Delete(newCtx, component.ServiceID, metav1.DeleteOptions{}) if err != nil && !k8sErrors.IsNotFound(err) { return err } @@ -2893,8 +2913,11 @@ func (s *ServiceAction) Log(w http.ResponseWriter, r *http.Request, component *d // Only support return the logs reader for a container now. return errors.WithStack(bcode.NewBadRequest("the field 'podName' and 'containerName' is required")) } - - request := s.kubeClient.CoreV1().Pods(component.TenantID).GetLogs(podName, &corev1.PodLogOptions{ + tenant, err := db.GetManager().TenantDao().GetTenantByUUID(component.TenantID) + if err != nil { + return fmt.Errorf("get tenant info failure %s", err.Error()) + } + request := s.kubeClient.CoreV1().Pods(tenant.Namespace).GetLogs(podName, &corev1.PodLogOptions{ Container: containerName, Follow: follow, }) diff --git a/api/model/component.go b/api/model/component.go index 1ec584b52..ac3435b4d 100644 --- a/api/model/component.go +++ b/api/model/component.go @@ -67,32 +67,34 @@ type ComponentBase struct { // 服务创建类型cloud云市服务,assistant云帮服务 // in: body // required: false - ServiceOrigin string `json:"service_origin" validate:"service_origin"` - Kind string `json:"kind" validate:"kind|in:internal,third_party"` + ServiceOrigin string `json:"service_origin" validate:"service_origin"` + Kind string `json:"kind" validate:"kind|in:internal,third_party"` + K8sComponentName string `json:"k8s_component_name" validate:"k8s_component_name"` } // DbModel return database model func (c *ComponentBase) DbModel(tenantID, appID, deployVersion string) *dbmodel.TenantServices { return &dbmodel.TenantServices{ - TenantID: tenantID, - ServiceID: c.ComponentID, - ServiceAlias: c.ComponentAlias, - ServiceName: c.ComponentName, - ServiceType: c.ExtendMethod, - Comment: c.Comment, - ContainerCPU: c.ContainerCPU, - ContainerMemory: c.ContainerMemory, - ContainerGPU: c.ContainerGPU, - ExtendMethod: c.ExtendMethod, - Replicas: c.Replicas, - DeployVersion: deployVersion, - Category: c.Category, - EventID: c.EventID, - Namespace: tenantID, - ServiceOrigin: c.ServiceOrigin, - Kind: c.Kind, - AppID: appID, - UpdateTime: time.Now(), + TenantID: tenantID, + ServiceID: c.ComponentID, + ServiceAlias: c.ComponentAlias, + ServiceName: c.ComponentName, + ServiceType: c.ExtendMethod, + Comment: c.Comment, + ContainerCPU: c.ContainerCPU, + ContainerMemory: c.ContainerMemory, + ContainerGPU: c.ContainerGPU, + ExtendMethod: c.ExtendMethod, + Replicas: c.Replicas, + DeployVersion: deployVersion, + Category: c.Category, + EventID: c.EventID, + Namespace: tenantID, + ServiceOrigin: c.ServiceOrigin, + Kind: c.Kind, + AppID: appID, + UpdateTime: time.Now(), + K8sComponentName: c.K8sComponentName, } } diff --git a/api/model/model.go b/api/model/model.go index 728d8355e..fd8112390 100644 --- a/api/model/model.go +++ b/api/model/model.go @@ -358,6 +358,7 @@ type ServiceStruct struct { ComponentMonitors []AddServiceMonitorRequestStruct `json:"component_monitors" validate:"component_monitors"` HTTPRules []AddHTTPRuleStruct `json:"http_rules" validate:"http_rules"` TCPRules []AddTCPRuleStruct `json:"tcp_rules" validate:"tcp_rules"` + K8sComponentName string `json:"k8s_component_name" validate:"k8s_component_name"` } // Endpoints holds third-party service endpoints or configuraion to get endpoints. @@ -609,6 +610,7 @@ type AddTenantStruct struct { Eid string `json:"eid" validata:"eid"` Token string `json:"token" validate:"token"` LimitMemory int `json:"limit_memory" validate:"limit_memory"` + Namespace string `json:"namespace" validate:"namespace"` } } @@ -1818,6 +1820,7 @@ type Application struct { AppStoreURL string `json:"app_store_url"` AppTemplateName string `json:"app_template_name"` Version string `json:"version"` + K8sApp string `json:"k8s_app" validate:"required"` } // CreateAppRequest - @@ -1854,6 +1857,7 @@ type UpdateAppRequest struct { Overrides []string `json:"overrides"` Version string `json:"version"` Revision int `json:"revision"` + K8sApp string `json:"k8s_app"` } // NeedUpdateHelmApp check if necessary to update the helm app. diff --git a/api/util/bcode/application.go b/api/util/bcode/application.go index 1f2ed64ec..fac7c37b5 100644 --- a/api/util/bcode/application.go +++ b/api/util/bcode/application.go @@ -12,7 +12,7 @@ var ( ErrUpdateNeedCorrectAppID = newByMessage(404, 11004, "update service need correct application ID") //ErrDeleteDueToBindService - ErrDeleteDueToBindService = newByMessage(400, 11005, "the application cannot be deleted because there are bound services") - // ErrK8sServiceNameExists - + // ErrK8sServiceNameExists - ErrK8sServiceNameExists = newByMessage(400, 11006, "kubernetes service name already exists") // ErrInvalidHelmAppValues - ErrInvalidHelmAppValues = newByMessage(400, 11007, "invalid helm app values") @@ -20,6 +20,10 @@ var ( ErrInvalidGovernanceMode = newByMessage(400, 11008, "invalid governance mode") // ErrControlPlaneNotInstall - ErrControlPlaneNotInstall = newByMessage(400, 11009, "control plane not install") + // ErrInvaildK8sApp - + ErrInvaildK8sApp = newByMessage(400, 11010, "invalid k8s app name") + // ErrK8sAppExists - + ErrK8sAppExists = newByMessage(400, 11011, "k8s app name exists") ) // app config group 11100~11199 diff --git a/api/util/bcode/ingress.go b/api/util/bcode/ingress.go index e73b9594b..acaabb57b 100644 --- a/api/util/bcode/ingress.go +++ b/api/util/bcode/ingress.go @@ -1,6 +1,6 @@ package bcode -// service: 11200~11299 +// ingress: 11200~11299 var ( ErrIngressHTTPRuleNotFound = newByMessage(404, 11200, "http rule not found") ErrIngressTCPRuleNotFound = newByMessage(404, 11201, "tcp rule not found") diff --git a/api/util/bcode/service.go b/api/util/bcode/service.go index 4cccee5ed..64cf4c38f 100644 --- a/api/util/bcode/service.go +++ b/api/util/bcode/service.go @@ -13,4 +13,5 @@ var ( // ErrHorizontalDueToNoChange ErrHorizontalDueToNoChange = newByMessage(400, 10104, "The number of components has not changed, no need to scale") ErrPodNotFound = newByMessage(404, 10105, "pod not found") + ErrK8sComponentNameExists = newByMessage(400, 10106, "k8s component name exists") ) diff --git a/api/util/bcode/tenant.go b/api/util/bcode/tenant.go new file mode 100644 index 000000000..7f2f7afa7 --- /dev/null +++ b/api/util/bcode/tenant.go @@ -0,0 +1,6 @@ +package bcode + +// tenant 11300~11399 +var ( + ErrNamespaceExists = newByMessage(400, 11300, "tenant namespace exists") +) diff --git a/cmd/init-probe/healthy/depends_health.go b/cmd/init-probe/healthy/depends_health.go index cd64a64ce..e2f8f9edc 100644 --- a/cmd/init-probe/healthy/depends_health.go +++ b/cmd/init-probe/healthy/depends_health.go @@ -58,7 +58,7 @@ type DependServiceHealthController struct { func NewDependServiceHealthController() (*DependServiceHealthController, error) { clusterID := os.Getenv("ENVOY_NODE_ID") if clusterID == "" { - clusterID = fmt.Sprintf("%s_%s_%s", os.Getenv("TENANT_ID"), os.Getenv("PLUGIN_ID"), os.Getenv("SERVICE_NAME")) + clusterID = fmt.Sprintf("%s_%s_%s", os.Getenv("NAMESPACE"), os.Getenv("PLUGIN_ID"), os.Getenv("SERVICE_NAME")) } dsc := DependServiceHealthController{ interval: time.Second * 5, diff --git a/cmd/mesh-data-panel/sidecar.go b/cmd/mesh-data-panel/sidecar.go index 22a9122a1..c6d7d3718 100644 --- a/cmd/mesh-data-panel/sidecar.go +++ b/cmd/mesh-data-panel/sidecar.go @@ -138,7 +138,7 @@ func run() error { } func discoverConfig() *api_model.ResourceSpec { - discoverURL := fmt.Sprintf("http://%s:6100/v1/resources/%s/%s/%s", os.Getenv("XDS_HOST_IP"), os.Getenv("TENANT_ID"), os.Getenv("SERVICE_NAME"), os.Getenv("PLUGIN_ID")) + discoverURL := fmt.Sprintf("http://%s:6100/v1/resources/%s/%s/%s", os.Getenv("XDS_HOST_IP"), os.Getenv("NAMESPACE"), os.Getenv("SERVICE_NAME"), os.Getenv("PLUGIN_ID")) http.DefaultClient.Timeout = time.Second * 5 res, err := http.Get(discoverURL) if err != nil { diff --git a/db/dao/dao.go b/db/dao/dao.go index 735400402..e1e1bad54 100644 --- a/db/dao/dao.go +++ b/db/dao/dao.go @@ -76,6 +76,7 @@ type ApplicationDao interface { DeleteApp(appID string) error GetByServiceID(sid string) (*model.Application, error) ListByAppIDs(appIDs []string) ([]*model.Application, error) + IsK8sAppDuplicate(tenantID, AppID, k8sApp string) bool } //AppConfigGroupDao Application config group Dao @@ -156,6 +157,7 @@ type TenantServiceDao interface { BindAppByServiceIDs(appID string, serviceIDs []string) error CreateOrUpdateComponentsInBatch(components []*model.TenantServices) error DeleteByComponentIDs(tenantID, appID string, componentIDs []string) error + IsK8sComponentNameDuplicate(appID, serviceID, k8sComponentName string) bool } //TenantServiceDeleteDao TenantServiceDeleteDao diff --git a/db/model/application.go b/db/model/application.go index cbd28ac7b..83cc82a7e 100644 --- a/db/model/application.go +++ b/db/model/application.go @@ -28,6 +28,7 @@ type Application struct { AppTemplateName string `gorm:"column:app_template_name" json:"app_template_name"` Version string `gorm:"column:version" json:"version"` GovernanceMode string `gorm:"column:governance_mode;default:'BUILD_IN_SERVICE_MESH'" json:"governance_mode"` + K8sApp string `gorm:"column:k8s_app" json:"k8s_app"` } // TableName return tableName "application" diff --git a/db/model/tenant.go b/db/model/tenant.go index 057edac79..3bb0b7906 100644 --- a/db/model/tenant.go +++ b/db/model/tenant.go @@ -67,6 +67,7 @@ type Tenants struct { EID string `gorm:"column:eid"` LimitMemory int `gorm:"column:limit_memory"` Status string `gorm:"column:status;default:'normal'"` + Namespace string `gorm:"column:namespace;size:32;unique_index"` } //TableName 返回租户表名称 @@ -200,6 +201,8 @@ type TenantServices struct { Kind string `gorm:"column:kind;default:'internal'" json:"kind"` // service bind appID AppID string `gorm:"column:app_id" json:"app_id"` + // Component name in cluster + K8sComponentName string `gorm:"column:k8s_component_name" json:"k8s_component_name"` } //Image 镜像 @@ -311,6 +314,8 @@ type TenantServicesDelete struct { Kind string `gorm:"column:kind;default:'internal'" json:"kind"` // service bind appID AppID string `gorm:"column:app_id" json:"app_id"` + // Component name in cluster + K8sComponentName string `gorm:"column:k8s_component_name" json:"k8s_component_name"` } //TableName 表名 diff --git a/db/mysql/dao/application.go b/db/mysql/dao/application.go index 999a6f4b5..2ae77d772 100644 --- a/db/mysql/dao/application.go +++ b/db/mysql/dao/application.go @@ -5,6 +5,7 @@ import ( "github.com/goodrain/rainbond/db/model" "github.com/jinzhu/gorm" "github.com/pkg/errors" + "github.com/sirupsen/logrus" ) // ApplicationDaoImpl - @@ -94,3 +95,13 @@ func (a *ApplicationDaoImpl) ListByAppIDs(appIDs []string) ([]*model.Application } return datas, nil } + +// IsK8sAppDuplicate Verify whether the k8s app under the same team are duplicate +func (a *ApplicationDaoImpl) IsK8sAppDuplicate(tenantID, AppID, k8sApp string) bool { + var count int64 + if err := a.DB.Model(&model.Application{}).Where("tenant_id=? and app_id <>? and k8s_app=?", tenantID, AppID, k8sApp).Count(&count).Error; err != nil { + logrus.Errorf("judge K8s App Duplicate failed %v", err) + return true + } + return count > 0 +} diff --git a/db/mysql/dao/tenants.go b/db/mysql/dao/tenants.go index 60cf47088..9b10a8ebe 100644 --- a/db/mysql/dao/tenants.go +++ b/db/mysql/dao/tenants.go @@ -573,6 +573,16 @@ func (t *TenantServicesDaoImpl) DeleteByComponentIDs(tenantID, appID string, com return nil } +//IsK8sComponentNameDuplicate - +func (t *TenantServicesDaoImpl) IsK8sComponentNameDuplicate(appID, serviceID, k8sComponentName string) bool { + var count int64 + if err := t.DB.Model(&model.TenantServices{}).Where("app_id=? and service_id<>? and k8s_component_name=?", appID, serviceID, k8sComponentName).Count(&count).Error; err != nil { + logrus.Errorf("judge K8s Component Name Duplicate failed %v", err) + return true + } + return count > 0 +} + //TenantServicesDeleteImpl TenantServiceDeleteImpl type TenantServicesDeleteImpl struct { DB *gorm.DB diff --git a/db/mysql/mysql.go b/db/mysql/mysql.go index 677e8b4b5..086195357 100644 --- a/db/mysql/mysql.go +++ b/db/mysql/mysql.go @@ -201,4 +201,7 @@ func (m *Manager) patchTable() { if err := m.db.Exec("alter table tenant_services_volume modify column volume_type varchar(64);").Error; err != nil { logrus.Errorf("alter table tenant_services_volume error: %s", err.Error()) } + if err := m.db.Exec("update tenants set namespace=uuid where namespace is NULL;").Error; err != nil { + logrus.Errorf("update tenants namespace error: %s", err.Error()) + } } diff --git a/grctl/cmd/service.go b/grctl/cmd/service.go index 00b616a44..9b14b56a8 100644 --- a/grctl/cmd/service.go +++ b/grctl/cmd/service.go @@ -356,12 +356,15 @@ func showServiceDeployInfo(c *cli.Context) error { } deployInfo, err := clients.RegionClient.Tenants(tenantName).Services(serviceAlias).GetDeployInfo() handleErr(err) - + tenant, err := clients.RegionClient.Tenants(tenantName).Get() + handleErr(err) + if tenant == nil { + return errors.New("Tenant not exist:" + tenantName) + } table := uitable.New() table.Wrap = true // wrap columns - tenantID := service.TenantID serviceID := service.ServiceID - table.AddRow("Namespace:", tenantID) + table.AddRow("Namespace:", tenant.Namespace) table.AddRow("ServiceID:", serviceID) if deployInfo.Deployment != "" { table.AddRow("ReplicationType:", "deployment") @@ -377,7 +380,7 @@ func showServiceDeployInfo(c *cli.Context) error { serviceTable.AddHeaders("Name", "IP", "Port") for serviceID := range deployInfo.Services { if clients.K8SClient != nil { - service, _ := clients.K8SClient.CoreV1().Services(tenantID).Get(context.Background(), serviceID, metav1.GetOptions{}) + service, _ := clients.K8SClient.CoreV1().Services(tenant.Namespace).Get(context.Background(), serviceID, metav1.GetOptions{}) if service != nil { var ports string if service.Spec.Ports != nil && len(service.Spec.Ports) > 0 { @@ -399,7 +402,7 @@ func showServiceDeployInfo(c *cli.Context) error { epTable.AddHeaders("Name", "IP", "Port", "Protocol") for epname := range deployInfo.Endpoints { if clients.K8SClient != nil { - ep, _ := clients.K8SClient.CoreV1().Endpoints(tenantID).Get(context.Background(), epname, metav1.GetOptions{}) + ep, _ := clients.K8SClient.CoreV1().Endpoints(tenant.Namespace).Get(context.Background(), epname, metav1.GetOptions{}) if ep != nil { for i := range ep.Subsets { ss := &ep.Subsets[i] @@ -428,7 +431,7 @@ func showServiceDeployInfo(c *cli.Context) error { ingressTable.AddHeaders("Name", "Host") for ingressID := range deployInfo.Ingresses { if clients.K8SClient != nil { - ingress, _ := clients.K8SClient.ExtensionsV1beta1().Ingresses(tenantID).Get(context.Background(), ingressID, metav1.GetOptions{}) + ingress, _ := clients.K8SClient.ExtensionsV1beta1().Ingresses(tenant.Namespace).Get(context.Background(), ingressID, metav1.GetOptions{}) if ingress != nil { for _, rule := range ingress.Spec.Rules { ingressTable.AddRow(ingress.Name, rule.Host) @@ -445,7 +448,7 @@ func showServiceDeployInfo(c *cli.Context) error { for podID := range deployInfo.Pods { i++ if clients.K8SClient != nil { - pod, err := clients.K8SClient.CoreV1().Pods(tenantID).Get(context.Background(), podID, metav1.GetOptions{}) + pod, err := clients.K8SClient.CoreV1().Pods(tenant.Namespace).Get(context.Background(), podID, metav1.GetOptions{}) if err != nil { return err } @@ -485,7 +488,7 @@ func showServiceDeployInfo(c *cli.Context) error { } claimName := vol.PersistentVolumeClaim.ClaimName - pvc, _ := clients.K8SClient.CoreV1().PersistentVolumeClaims(tenantID).Get(context.Background(), claimName, metav1.GetOptions{}) + pvc, _ := clients.K8SClient.CoreV1().PersistentVolumeClaims(tenant.Namespace).Get(context.Background(), claimName, metav1.GetOptions{}) if pvc != nil { pvn := pvc.Spec.VolumeName volumeMount := name2Path[vol.Name] diff --git a/hack/contrib/docker/mesh-data-panel/start.sh b/hack/contrib/docker/mesh-data-panel/start.sh index 2a8df4593..cfc749f29 100755 --- a/hack/contrib/docker/mesh-data-panel/start.sh +++ b/hack/contrib/docker/mesh-data-panel/start.sh @@ -9,7 +9,7 @@ elif [ "$1" = "run" ]; then /root/rainbond-mesh-data-panel run || exit 1 else env2file conversion -f /root/envoy_config.yaml - cluster_name=${TENANT_ID}_${PLUGIN_ID}_${SERVICE_NAME} + cluster_name=${NAMESPACE}_${PLUGIN_ID}_${SERVICE_NAME} # start sidecar process /root/rainbond-mesh-data-panel & # start envoy process diff --git a/webcli/app/app.go b/webcli/app/app.go index ed07d33ee..bc644b9a6 100644 --- a/webcli/app/app.go +++ b/webcli/app/app.go @@ -110,6 +110,7 @@ type InitMessage struct { PodName string `json:"C_id"` ContainerName string `json:"containerName"` Md5 string `json:"Md5"` + Namespace string `json:"namespace"` } func checkSameOrigin(r *http.Request) bool { @@ -233,14 +234,17 @@ func (app *App) handleWS(w http.ResponseWriter, r *http.Request) { return } // base kubernetes api create exec slave - containerName, ip, args, err := app.GetContainerArgs(init.TenantID, init.PodName, init.ContainerName) + if init.Namespace == "" { + init.Namespace = init.TenantID + } + containerName, ip, args, err := app.GetContainerArgs(init.Namespace, init.PodName, init.ContainerName) if err != nil { logrus.Errorf("get default container failure %s", err.Error()) conn.WriteMessage(websocket.TextMessage, []byte("Get default container name failure!")) ExecuteCommandFailed++ return } - request := app.NewRequest(init.PodName, init.TenantID, containerName, args) + request := app.NewRequest(init.PodName, init.Namespace, containerName, args) var slave server.Slave slave, err = NewExecContext(request, app.config) if err != nil { diff --git a/worker/appm/componentdefinition/parse.go b/worker/appm/componentdefinition/parse.go index 89ee9b5ca..32e458973 100644 --- a/worker/appm/componentdefinition/parse.go +++ b/worker/appm/componentdefinition/parse.go @@ -71,7 +71,7 @@ func NewTemplateContext(as *v1.AppService, template string, params interface{}) appName: as.AppID, componentID: as.ServiceID, appID: as.AppID, - namespace: as.TenantID, + namespace: as.GetNamespace(), template: template, params: params, } diff --git a/worker/appm/controller/apply_plugin_config.go b/worker/appm/controller/apply_plugin_config.go index 293e99a14..d6b7d773e 100644 --- a/worker/appm/controller/apply_plugin_config.go +++ b/worker/appm/controller/apply_plugin_config.go @@ -47,7 +47,7 @@ func (a *applyConfigController) Begin() { for _, new := range newConfigMaps { if nowConfig, ok := nowConfigMapMaps[new.Name]; ok { new.UID = nowConfig.UID - newc, err := a.manager.client.CoreV1().ConfigMaps(nowApp.TenantID).Update(context.Background(), new, metav1.UpdateOptions{}) + newc, err := a.manager.client.CoreV1().ConfigMaps(nowApp.GetNamespace()).Update(context.Background(), new, metav1.UpdateOptions{}) if err != nil { logrus.Errorf("update config map failure %s", err.Error()) } @@ -55,7 +55,7 @@ func (a *applyConfigController) Begin() { nowConfigMapMaps[new.Name] = nil logrus.Debugf("update configmap %s for service %s", new.Name, a.appService.ServiceID) } else { - newc, err := a.manager.client.CoreV1().ConfigMaps(nowApp.TenantID).Create(context.Background(), new, metav1.CreateOptions{}) + newc, err := a.manager.client.CoreV1().ConfigMaps(nowApp.GetNamespace()).Create(context.Background(), new, metav1.CreateOptions{}) if err != nil { logrus.Errorf("update config map failure %s", err.Error()) } @@ -65,7 +65,7 @@ func (a *applyConfigController) Begin() { } for name, handle := range nowConfigMapMaps { if handle != nil { - if err := a.manager.client.CoreV1().ConfigMaps(nowApp.TenantID).Delete(context.Background(), name, metav1.DeleteOptions{}); err != nil { + if err := a.manager.client.CoreV1().ConfigMaps(nowApp.GetNamespace()).Delete(context.Background(), name, metav1.DeleteOptions{}); err != nil { logrus.Errorf("delete config map failure %s", err.Error()) } logrus.Debugf("delete configmap %s for service %s", name, a.appService.ServiceID) diff --git a/worker/appm/controller/start.go b/worker/appm/controller/start.go index ed315020a..288c383bc 100644 --- a/worker/appm/controller/start.go +++ b/worker/appm/controller/start.go @@ -93,7 +93,7 @@ func (s *startController) errorCallback(app v1.AppService) error { } func (s *startController) startOne(app v1.AppService) error { //first: check and create namespace - _, err := s.manager.client.CoreV1().Namespaces().Get(s.ctx, app.TenantID, metav1.GetOptions{}) + _, err := s.manager.client.CoreV1().Namespaces().Get(s.ctx, app.GetNamespace(), metav1.GetOptions{}) if err != nil { if errors.IsNotFound(err) { _, err = s.manager.client.CoreV1().Namespaces().Create(s.ctx, app.GetTenant(), metav1.CreateOptions{}) @@ -114,7 +114,7 @@ func (s *startController) startOne(app v1.AppService) error { //step 1: create configmap if configs := app.GetConfigMaps(); configs != nil { for _, config := range configs { - _, err := s.manager.client.CoreV1().ConfigMaps(app.TenantID).Create(s.ctx, config, metav1.CreateOptions{}) + _, err := s.manager.client.CoreV1().ConfigMaps(app.GetNamespace()).Create(s.ctx, config, metav1.CreateOptions{}) if err != nil && !errors.IsAlreadyExists(err) { return fmt.Errorf("create config map failure:%s", err.Error()) } @@ -123,27 +123,27 @@ func (s *startController) startOne(app v1.AppService) error { // create claims for _, claim := range app.GetClaimsManually() { logrus.Debugf("create claim: %s", claim.Name) - _, err := s.manager.client.CoreV1().PersistentVolumeClaims(app.TenantID).Create(s.ctx, claim, metav1.CreateOptions{}) + _, err := s.manager.client.CoreV1().PersistentVolumeClaims(app.GetNamespace()).Create(s.ctx, claim, metav1.CreateOptions{}) if err != nil && !errors.IsAlreadyExists(err) { return fmt.Errorf("create claims: %v", err) } } //step 2: create statefulset or deployment if statefulset := app.GetStatefulSet(); statefulset != nil { - _, err = s.manager.client.AppsV1().StatefulSets(app.TenantID).Create(s.ctx, statefulset, metav1.CreateOptions{}) + _, err = s.manager.client.AppsV1().StatefulSets(app.GetNamespace()).Create(s.ctx, statefulset, metav1.CreateOptions{}) if err != nil { return fmt.Errorf("create statefulset failure:%s", err.Error()) } } if deployment := app.GetDeployment(); deployment != nil { - _, err = s.manager.client.AppsV1().Deployments(app.TenantID).Create(s.ctx, deployment, metav1.CreateOptions{}) + _, err = s.manager.client.AppsV1().Deployments(app.GetNamespace()).Create(s.ctx, deployment, metav1.CreateOptions{}) if err != nil { return fmt.Errorf("create deployment failure:%s;", err.Error()) } } //step 3: create services if services := app.GetServices(true); services != nil { - if err := CreateKubeService(s.manager.client, app.TenantID, services...); err != nil { + if err := CreateKubeService(s.manager.client, app.GetNamespace(), services...); err != nil { return fmt.Errorf("create service failure %s", err.Error()) } } @@ -151,7 +151,7 @@ func (s *startController) startOne(app v1.AppService) error { if secrets := append(app.GetSecrets(true), app.GetEnvVarSecrets(true)...); secrets != nil { for _, secret := range secrets { if len(secret.ResourceVersion) == 0 { - _, err := s.manager.client.CoreV1().Secrets(app.TenantID).Create(s.ctx, secret, metav1.CreateOptions{}) + _, err := s.manager.client.CoreV1().Secrets(app.GetNamespace()).Create(s.ctx, secret, metav1.CreateOptions{}) if err != nil && !errors.IsAlreadyExists(err) { return fmt.Errorf("create secret failure:%s", err.Error()) } @@ -162,7 +162,7 @@ func (s *startController) startOne(app v1.AppService) error { ingresses, betaIngresses := app.GetIngress(true) for _, ingress := range ingresses { if len(ingress.ResourceVersion) == 0 { - _, err := s.manager.client.NetworkingV1().Ingresses(app.TenantID).Create(s.ctx, ingress, metav1.CreateOptions{}) + _, err := s.manager.client.NetworkingV1().Ingresses(app.GetNamespace()).Create(s.ctx, ingress, metav1.CreateOptions{}) if err != nil && !errors.IsAlreadyExists(err) { return fmt.Errorf("create ingress failure:%s", err.Error()) } @@ -170,7 +170,7 @@ func (s *startController) startOne(app v1.AppService) error { } for _, ingress := range betaIngresses { if len(ingress.ResourceVersion) == 0 { - _, err := s.manager.client.NetworkingV1beta1().Ingresses(app.TenantID).Create(s.ctx, ingress, metav1.CreateOptions{}) + _, err := s.manager.client.NetworkingV1beta1().Ingresses(app.GetNamespace()).Create(s.ctx, ingress, metav1.CreateOptions{}) if err != nil && !errors.IsAlreadyExists(err) { return fmt.Errorf("create ingress failure:%s", err.Error()) } diff --git a/worker/appm/controller/stop.go b/worker/appm/controller/stop.go index 12e0072d3..9351e54b7 100644 --- a/worker/appm/controller/stop.go +++ b/worker/appm/controller/stop.go @@ -72,7 +72,7 @@ func (s *stopController) stopOne(app v1.AppService) error { if services := app.GetServices(true); services != nil { for _, service := range services { if service != nil && service.Name != "" { - err := s.manager.client.CoreV1().Services(app.TenantID).Delete(s.ctx, service.Name, metav1.DeleteOptions{ + err := s.manager.client.CoreV1().Services(app.GetNamespace()).Delete(s.ctx, service.Name, metav1.DeleteOptions{ GracePeriodSeconds: &zero, }) if err != nil && !errors.IsNotFound(err) { @@ -85,7 +85,7 @@ func (s *stopController) stopOne(app v1.AppService) error { if secrets := app.GetSecrets(true); secrets != nil { for _, secret := range secrets { if secret != nil && secret.Name != "" { - err := s.manager.client.CoreV1().Secrets(app.TenantID).Delete(s.ctx, secret.Name, metav1.DeleteOptions{ + err := s.manager.client.CoreV1().Secrets(app.GetNamespace()).Delete(s.ctx, secret.Name, metav1.DeleteOptions{ GracePeriodSeconds: &zero, }) if err != nil && !errors.IsNotFound(err) { @@ -99,7 +99,7 @@ func (s *stopController) stopOne(app v1.AppService) error { if ingresses != nil { for _, ingress := range ingresses { if ingress != nil && ingress.Name != "" { - err := s.deleteIngress(app.TenantID, ingress.Name, zero) + err := s.deleteIngress(app.GetNamespace(), ingress.Name, zero) if err != nil { return err } @@ -108,7 +108,7 @@ func (s *stopController) stopOne(app v1.AppService) error { } else { for _, ingress := range betaIngresses { if ingress != nil && ingress.Name != "" { - err := s.deleteIngress(app.TenantID, ingress.Name, zero) + err := s.deleteBetaIngress(app.GetNamespace(), ingress.Name, zero) if err != nil { return err } @@ -121,7 +121,7 @@ func (s *stopController) stopOne(app v1.AppService) error { if configs := app.GetConfigMaps(); configs != nil { for _, config := range configs { if config != nil && config.Name != "" { - err := s.manager.client.CoreV1().ConfigMaps(app.TenantID).Delete(s.ctx, config.Name, metav1.DeleteOptions{ + err := s.manager.client.CoreV1().ConfigMaps(app.GetNamespace()).Delete(s.ctx, config.Name, metav1.DeleteOptions{ GracePeriodSeconds: &zero, }) if err != nil && !errors.IsNotFound(err) { @@ -149,14 +149,14 @@ func (s *stopController) stopOne(app v1.AppService) error { } //step 5: delete statefulset or deployment if statefulset := app.GetStatefulSet(); statefulset != nil { - err := s.manager.client.AppsV1().StatefulSets(app.TenantID).Delete(s.ctx, statefulset.Name, metav1.DeleteOptions{}) + err := s.manager.client.AppsV1().StatefulSets(app.GetNamespace()).Delete(s.ctx, statefulset.Name, metav1.DeleteOptions{}) if err != nil && !errors.IsNotFound(err) { return fmt.Errorf("delete statefulset failure:%s", err.Error()) } s.manager.store.OnDeletes(statefulset) } if deployment := app.GetDeployment(); deployment != nil && deployment.Name != "" { - err := s.manager.client.AppsV1().Deployments(app.TenantID).Delete(s.ctx, deployment.Name, metav1.DeleteOptions{}) + err := s.manager.client.AppsV1().Deployments(app.GetNamespace()).Delete(s.ctx, deployment.Name, metav1.DeleteOptions{}) if err != nil && !errors.IsNotFound(err) { return fmt.Errorf("delete deployment failure:%s", err.Error()) } @@ -167,7 +167,7 @@ func (s *stopController) stopOne(app v1.AppService) error { if pods := app.GetPods(true); pods != nil { for _, pod := range pods { if pod != nil && pod.Name != "" { - err := s.manager.client.CoreV1().Pods(app.TenantID).Delete(s.ctx, pod.Name, metav1.DeleteOptions{ + err := s.manager.client.CoreV1().Pods(app.GetNamespace()).Delete(s.ctx, pod.Name, metav1.DeleteOptions{ GracePeriodSeconds: &gracePeriodSeconds, }) if err != nil && !errors.IsNotFound(err) { @@ -230,8 +230,18 @@ func (s *stopController) WaitingReady(app v1.AppService) error { return nil } -func (s *stopController) deleteIngress(tenantID, ingressName string, zero int64) error { - err := s.manager.client.ExtensionsV1beta1().Ingresses(tenantID).Delete(s.ctx, ingressName, metav1.DeleteOptions{ +func (s *stopController) deleteIngress(namespace, ingressName string, zero int64) error { + err := s.manager.client.NetworkingV1().Ingresses(namespace).Delete(s.ctx, ingressName, metav1.DeleteOptions{ + GracePeriodSeconds: &zero, + }) + if err != nil && !errors.IsNotFound(err) { + return fmt.Errorf("delete ingress failure:%s", err.Error()) + } + return nil +} + +func (s *stopController) deleteBetaIngress(namespace, ingressName string, zero int64) error { + err := s.manager.client.ExtensionsV1beta1().Ingresses(namespace).Delete(s.ctx, ingressName, metav1.DeleteOptions{ GracePeriodSeconds: &zero, }) if err != nil && !errors.IsNotFound(err) { diff --git a/worker/appm/controller/upgrade.go b/worker/appm/controller/upgrade.go index 0804a1557..85879a4e6 100644 --- a/worker/appm/controller/upgrade.go +++ b/worker/appm/controller/upgrade.go @@ -80,7 +80,7 @@ func (s *upgradeController) upgradeConfigMap(newapp v1.AppService) { for _, new := range newConfigMaps { if nowConfig, ok := nowConfigMapMaps[new.Name]; ok { new.UID = nowConfig.UID - newc, err := s.manager.client.CoreV1().ConfigMaps(nowApp.TenantID).Update(s.ctx, new, metav1.UpdateOptions{}) + newc, err := s.manager.client.CoreV1().ConfigMaps(nowApp.GetNamespace()).Update(s.ctx, new, metav1.UpdateOptions{}) if err != nil { logrus.Errorf("update config map failure %s", err.Error()) } @@ -88,7 +88,7 @@ func (s *upgradeController) upgradeConfigMap(newapp v1.AppService) { nowConfigMapMaps[new.Name] = nil logrus.Debugf("update configmap %s for service %s", new.Name, newapp.ServiceID) } else { - newc, err := s.manager.client.CoreV1().ConfigMaps(nowApp.TenantID).Create(s.ctx, new, metav1.CreateOptions{}) + newc, err := s.manager.client.CoreV1().ConfigMaps(nowApp.GetNamespace()).Create(s.ctx, new, metav1.CreateOptions{}) if err != nil { logrus.Errorf("update config map failure %s", err.Error()) } @@ -98,7 +98,7 @@ func (s *upgradeController) upgradeConfigMap(newapp v1.AppService) { } for name, handle := range nowConfigMapMaps { if handle != nil { - if err := s.manager.client.CoreV1().ConfigMaps(nowApp.TenantID).Delete(s.ctx, name, metav1.DeleteOptions{}); err != nil { + if err := s.manager.client.CoreV1().ConfigMaps(nowApp.GetNamespace()).Delete(s.ctx, name, metav1.DeleteOptions{}); err != nil { logrus.Errorf("delete config map failure %s", err.Error()) } logrus.Debugf("delete configmap %s for service %s", name, newapp.ServiceID) @@ -120,7 +120,7 @@ func (s *upgradeController) upgradeService(newapp v1.AppService) { nowConfig.Spec.Ports = new.Spec.Ports nowConfig.Spec.Type = new.Spec.Type nowConfig.Labels = new.Labels - newc, err := s.manager.client.CoreV1().Services(nowApp.TenantID).Update(s.ctx, nowConfig, metav1.UpdateOptions{}) + newc, err := s.manager.client.CoreV1().Services(nowApp.GetNamespace()).Update(s.ctx, nowConfig, metav1.UpdateOptions{}) if err != nil { logrus.Errorf("update service failure %s", err.Error()) } @@ -128,7 +128,7 @@ func (s *upgradeController) upgradeService(newapp v1.AppService) { nowServiceMaps[new.Name] = nil logrus.Debugf("update service %s for service %s", new.Name, newapp.ServiceID) } else { - err := CreateKubeService(s.manager.client, nowApp.TenantID, new) + err := CreateKubeService(s.manager.client, nowApp.GetNamespace(), new) if err != nil { logrus.Errorf("update service failure %s", err.Error()) } @@ -138,7 +138,7 @@ func (s *upgradeController) upgradeService(newapp v1.AppService) { } for name, handle := range nowServiceMaps { if handle != nil { - if err := s.manager.client.CoreV1().Services(nowApp.TenantID).Delete(s.ctx, name, metav1.DeleteOptions{}); err != nil { + if err := s.manager.client.CoreV1().Services(nowApp.GetNamespace()).Delete(s.ctx, name, metav1.DeleteOptions{}); err != nil { logrus.Errorf("delete service failure %s", err.Error()) } logrus.Debugf("delete service %s for service %s", name, newapp.ServiceID) @@ -148,7 +148,7 @@ func (s *upgradeController) upgradeService(newapp v1.AppService) { func (s *upgradeController) upgradeOne(app v1.AppService) error { //first: check and create namespace - _, err := s.manager.client.CoreV1().Namespaces().Get(s.ctx, app.TenantID, metav1.GetOptions{}) + _, err := s.manager.client.CoreV1().Namespaces().Get(s.ctx, app.GetNamespace(), metav1.GetOptions{}) if err != nil { if errors.IsNotFound(err) { _, err = s.manager.client.CoreV1().Namespaces().Create(s.ctx, app.GetTenant(), metav1.CreateOptions{}) @@ -177,7 +177,7 @@ func (s *upgradeController) upgradeOne(app v1.AppService) error { // create claims for _, claim := range app.GetClaimsManually() { logrus.Debugf("create claim: %s", claim.Name) - _, err := s.manager.client.CoreV1().PersistentVolumeClaims(app.TenantID).Create(s.ctx, claim, metav1.CreateOptions{}) + _, err := s.manager.client.CoreV1().PersistentVolumeClaims(app.GetNamespace()).Create(s.ctx, claim, metav1.CreateOptions{}) if err != nil && !errors.IsAlreadyExists(err) { return fmt.Errorf("create claims: %v", err) } diff --git a/worker/appm/conversion/autoscaler.go b/worker/appm/conversion/autoscaler.go index 86c28b5db..57f362f4c 100644 --- a/worker/appm/conversion/autoscaler.go +++ b/worker/appm/conversion/autoscaler.go @@ -77,7 +77,7 @@ func newHPAs(as *v1.AppService, dbmanager db.Manager) ([]*autoscalingv2.Horizont "version": as.DeployVersion, }) - hpa := newHPA(as.TenantID, kind, name, labels, rule, metrics) + hpa := newHPA(as.GetNamespace(), kind, name, labels, rule, metrics) hpas = append(hpas, hpa) } diff --git a/worker/appm/conversion/configgroup.go b/worker/appm/conversion/configgroup.go index a8ea0e265..d751914da 100644 --- a/worker/appm/conversion/configgroup.go +++ b/worker/appm/conversion/configgroup.go @@ -19,7 +19,7 @@ func TenantServiceConfigGroup(as *v1.AppService, dbm db.Manager) error { var secrets []*corev1.Secret for _, group := range groups { - cg := createConfigGroup(as, as.TenantID, group.AppID, group.ConfigGroupName) + cg := createConfigGroup(as, as.GetNamespace(), group.AppID, group.ConfigGroupName) secret, err := cg.secretForConfigGroup() if err != nil { return fmt.Errorf("create secret for config group: %v", err) diff --git a/worker/appm/conversion/conversion.go b/worker/appm/conversion/conversion.go index 106f1a4fc..b15698927 100644 --- a/worker/appm/conversion/conversion.go +++ b/worker/appm/conversion/conversion.go @@ -84,6 +84,7 @@ func InitAppService(dbmanager db.Manager, serviceID string, configs map[string]s } if app != nil { appService.AppServiceBase.GovernanceMode = app.GovernanceMode + appService.AppServiceBase.K8sApp = app.K8sApp } if err := TenantServiceBase(appService, dbmanager); err != nil { logrus.Errorf("init component base config failure %s", err.Error()) @@ -131,6 +132,7 @@ func InitCacheAppService(dbm db.Manager, serviceID, creatorID string) (*v1.AppSe } if app != nil { appService.AppServiceBase.GovernanceMode = app.GovernanceMode + appService.AppServiceBase.K8sApp = app.K8sApp } if err := TenantServiceBase(appService, dbm); err != nil { diff --git a/worker/appm/conversion/gateway.go b/worker/appm/conversion/gateway.go index e2684c86d..22a77f1e5 100644 --- a/worker/appm/conversion/gateway.go +++ b/worker/appm/conversion/gateway.go @@ -229,7 +229,7 @@ func (a AppServiceBuild) ApplyRules(serviceID string, containerPort, pluginConta } if len(tcpRules) > 0 { for _, tcpRule := range tcpRules { - ing, err := a.applyTCPRule(tcpRule, service, a.tenant.UUID) + ing, err := a.applyTCPRule(tcpRule, service, a.appService.GetNamespace()) if err != nil { logrus.Errorf("Unexpected error occurred while applying tcp rule: %v", err) // skip the failed rule @@ -257,7 +257,7 @@ func (a *AppServiceBuild) applyHTTPRule(rule *model.HTTPRule, containerPort, plu // create ingress labels := a.appService.GetCommonLabels() name := rule.UUID - namespace := a.tenant.UUID + namespace := a.appService.GetNamespace() serviceName := service.Name logrus.Infof("applyHTTPRule serviceName %s", serviceName) @@ -412,7 +412,7 @@ func (a *AppServiceBuild) createKubernetesNativeService(port *model.TenantServic svc := a.createInnerService(port) svc.Name = port.K8sServiceName if svc.Name == "" { - svc.Name = fmt.Sprintf("%s-%d", a.service.ServiceAlias, port.ContainerPort) + svc.Name = fmt.Sprintf("%s-%d", a.appService.GetK8sWorkloadName(), port.ContainerPort) } return svc } @@ -421,9 +421,9 @@ func (a *AppServiceBuild) createInnerService(port *model.TenantServicesPort) *co var service corev1.Service service.Name = port.K8sServiceName if service.Name == "" { - service.Name = fmt.Sprintf("service-%d-%d", port.ID, port.ContainerPort) + service.Name = fmt.Sprintf("%s-%d-%d", a.appService.GetK8sWorkloadName(), port.ID, port.ContainerPort) } - service.Namespace = a.service.TenantID + service.Namespace = a.appService.GetNamespace() service.Labels = a.appService.GetCommonLabels(map[string]string{ "service_type": "inner", "name": a.service.ServiceAlias + "Service", @@ -460,8 +460,8 @@ func (a *AppServiceBuild) createInnerService(port *model.TenantServicesPort) *co func (a *AppServiceBuild) createOuterService(port *model.TenantServicesPort) *corev1.Service { var service corev1.Service - service.Name = fmt.Sprintf("service-%d-%dout", port.ID, port.ContainerPort) - service.Namespace = a.service.TenantID + service.Name = fmt.Sprintf("%s-%d-%dout", a.appService.GetK8sWorkloadName(), port.ID, port.ContainerPort) + service.Namespace = a.appService.GetNamespace() service.Labels = a.appService.GetCommonLabels(map[string]string{ "service_type": "outer", "name": a.service.ServiceAlias + "ServiceOUT", @@ -496,9 +496,9 @@ func (a *AppServiceBuild) createOuterService(port *model.TenantServicesPort) *co func (a *AppServiceBuild) createStatefulService(ports []*model.TenantServicesPort) *corev1.Service { var service corev1.Service service.Name = a.service.ServiceName - service.Namespace = a.service.TenantID + service.Namespace = a.appService.GetNamespace() if service.Name == "" { - service.Name = a.service.ServiceAlias + service.Name = a.appService.GetK8sWorkloadName() } service.Labels = a.appService.GetCommonLabels(map[string]string{ "service_type": "stateful", @@ -519,7 +519,7 @@ func (a *AppServiceBuild) createStatefulService(ports []*model.TenantServicesPor } spec := corev1.ServiceSpec{ Ports: serviceports, - Selector: map[string]string{"name": a.service.ServiceAlias}, + Selector: map[string]string{"name": a.appService.GetK8sWorkloadName()}, ClusterIP: "None", PublishNotReadyAddresses: true, } diff --git a/worker/appm/conversion/monitor.go b/worker/appm/conversion/monitor.go index f123a3083..b87d2953c 100644 --- a/worker/appm/conversion/monitor.go +++ b/worker/appm/conversion/monitor.go @@ -70,7 +70,7 @@ func createServiceMonitor(as *v1.AppService, dbmanager db.Manager) []*mv1.Servic sm := mv1.ServiceMonitor{} sm.Name = tsm.Name sm.Labels = as.GetCommonLabels() - sm.Namespace = as.TenantID + sm.Namespace = as.GetNamespace() sm.Spec = mv1.ServiceMonitorSpec{ // service label app_name JobLabel: "app_name", diff --git a/worker/appm/conversion/plugin.go b/worker/appm/conversion/plugin.go index fe5e57946..8174302f7 100644 --- a/worker/appm/conversion/plugin.go +++ b/worker/appm/conversion/plugin.go @@ -92,7 +92,7 @@ func conversionServicePlugin(as *typesv1.AppService, dbmanager db.Manager) ([]v1 logrus.Warnf("Can't not get pod for plugin(plugin_id=%s)", pluginR.PluginID) continue } - envs, err := createPluginEnvs(pluginR.PluginID, as.TenantID, as.ServiceAlias, mainContainer.Env, pluginR.VersionID, as.ServiceID, dbmanager) + envs, err := createPluginEnvs(pluginR.PluginID, as.GetNamespace(), as.ServiceAlias, mainContainer.Env, pluginR.VersionID, as.ServiceID, dbmanager) if err != nil { return nil, nil, nil, err } @@ -208,7 +208,7 @@ func createTCPDefaultPluginContainer(as *typesv1.AppService, pluginID string, en envs = append(envs, v1.EnvVar{Name: "XDS_HOST_PORT", Value: xdsHostPort}) container := v1.Container{ - Name: "default-tcpmesh-" + as.ServiceID[len(as.ServiceID)-20:], + Name: "default-tcpmesh-" + as.GetK8sWorkloadName(), Env: envs, Image: typesv1.GetOnlineTCPMeshImageName(), Resources: createTCPUDPMeshRecources(as), @@ -261,7 +261,7 @@ func createProbeMeshInitContainer(as *typesv1.AppService, pluginID, serviceAlias envs = append(envs, v1.EnvVar{Name: "XDS_HOST_PORT", Value: xdsHostPort}) return v1.Container{ - Name: "probe-mesh-" + as.ServiceID[len(as.ServiceID)-20:], + Name: "probe-mesh-" + as.GetK8sWorkloadName(), Env: envs, Image: typesv1.GetOnlineProbeMeshImageName(), Resources: createTCPUDPMeshRecources(as), diff --git a/worker/appm/conversion/service.go b/worker/appm/conversion/service.go index a9e722dbd..c8030c004 100644 --- a/worker/appm/conversion/service.go +++ b/worker/appm/conversion/service.go @@ -100,6 +100,10 @@ func TenantServiceBase(as *v1.AppService, dbmanager db.Manager) error { as.AppID = tenantService.AppID as.ServiceAlias = tenantService.ServiceAlias as.UpgradeMethod = v1.TypeUpgradeMethod(tenantService.UpgradeMethod) + if tenantService.K8sComponentName == "" { + tenantService.K8sComponentName = tenantService.ServiceAlias + } + as.K8sComponentName = tenantService.K8sComponentName if as.CreaterID == "" { as.CreaterID = string(util.NewTimeVersion()) } @@ -138,12 +142,12 @@ func TenantServiceBase(as *v1.AppService, dbmanager db.Manager) error { } func initTenant(as *v1.AppService, tenant *dbmodel.Tenants) error { - if tenant == nil || tenant.UUID == "" { + if tenant == nil || tenant.Namespace == "" { return fmt.Errorf("tenant is invalid") } namespace := &corev1.Namespace{ ObjectMeta: metav1.ObjectMeta{ - Name: tenant.UUID, + Name: tenant.Namespace, Labels: map[string]string{"creator": "Rainbond"}, }, } @@ -165,7 +169,7 @@ func initBaseStatefulSet(as *v1.AppService, service *dbmodel.TenantServices) { if stateful == nil { stateful = &appsv1.StatefulSet{} } - stateful.Namespace = as.TenantID + stateful.Namespace = as.GetNamespace() stateful.Spec.Replicas = int32Ptr(service.Replicas) if stateful.Spec.Selector == nil { stateful.Spec.Selector = &metav1.LabelSelector{} @@ -174,10 +178,9 @@ func initBaseStatefulSet(as *v1.AppService, service *dbmodel.TenantServices) { stateful.Spec.ServiceName = service.ServiceName stateful.Name = service.ServiceName if stateful.Spec.ServiceName == "" { - stateful.Spec.ServiceName = service.ServiceAlias - stateful.Name = service.ServiceAlias + stateful.Spec.ServiceName = as.GetK8sWorkloadName() + stateful.Name = as.GetK8sWorkloadName() } - stateful.Namespace = service.TenantID stateful.GenerateName = service.ServiceAlias injectLabels := getInjectLabels(as) stateful.Labels = as.GetCommonLabels(stateful.Labels, map[string]string{ @@ -197,14 +200,13 @@ func initBaseDeployment(as *v1.AppService, service *dbmodel.TenantServices) { if deployment == nil { deployment = &appsv1.Deployment{} } - deployment.Namespace = as.TenantID + deployment.Namespace = as.GetNamespace() deployment.Spec.Replicas = int32Ptr(service.Replicas) if deployment.Spec.Selector == nil { deployment.Spec.Selector = &metav1.LabelSelector{} } initSelector(deployment.Spec.Selector, service) - deployment.Namespace = service.TenantID - deployment.Name = service.ServiceID + "-deployment" + deployment.Name = as.GetK8sWorkloadName() deployment.GenerateName = strings.Replace(service.ServiceAlias, "_", "-", -1) injectLabels := getInjectLabels(as) deployment.Labels = as.GetCommonLabels(deployment.Labels, map[string]string{ diff --git a/worker/appm/conversion/version.go b/worker/appm/conversion/version.go index be66da14b..cf7625b36 100644 --- a/worker/appm/conversion/version.go +++ b/worker/appm/conversion/version.go @@ -78,7 +78,7 @@ func TenantServiceVersion(as *v1.AppService, dbmanager db.Manager) error { "version": as.DeployVersion, }), Annotations: createPodAnnotations(as), - Name: as.ServiceID + "-pod-spec", + Name: as.GetK8sWorkloadName() + "-pod-spec", }, Spec: corev1.PodSpec{ ImagePullSecrets: setImagePullSecrets(), @@ -151,7 +151,7 @@ func getMainContainer(as *v1.AppService, version *dbmodel.VersionInfo, dv *volum } c := &corev1.Container{ - Name: as.ServiceID, + Name: as.K8sComponentName, Image: imagename, Args: args, Ports: ports, @@ -313,6 +313,7 @@ func createEnv(as *v1.AppService, dbmanager db.Manager, envVarSecrets []*corev1. } //set default env + envs = append(envs, corev1.EnvVar{Name: "NAMESPACE", Value: as.GetNamespace()}) envs = append(envs, corev1.EnvVar{Name: "TENANT_ID", Value: as.TenantID}) envs = append(envs, corev1.EnvVar{Name: "SERVICE_ID", Value: as.ServiceID}) envs = append(envs, corev1.EnvVar{Name: "MEMORY_SIZE", Value: envutil.GetMemoryType(as.ContainerMemory)}) @@ -702,7 +703,7 @@ func createAffinity(as *v1.AppService, dbmanager db.Manager) *corev1.Affinity { LabelSelector: metav1.SetAsLabelSelector(map[string]string{ "name": l.LabelValue, }), - Namespaces: []string{as.TenantID}, + Namespaces: []string{as.GetNamespace()}, }) } if l.LabelKey == dbmodel.LabelKeyServiceAntyAffinity { @@ -711,7 +712,7 @@ func createAffinity(as *v1.AppService, dbmanager db.Manager) *corev1.Affinity { LabelSelector: metav1.SetAsLabelSelector(map[string]string{ "name": l.LabelValue, }), - Namespaces: []string{as.TenantID}, + Namespaces: []string{as.GetNamespace()}, }) } } diff --git a/worker/appm/f/function.go b/worker/appm/f/function.go index 2ef3da095..62e2af563 100644 --- a/worker/appm/f/function.go +++ b/worker/appm/f/function.go @@ -47,7 +47,7 @@ const ( // ApplyOne applies one rule. func ApplyOne(ctx context.Context, apply apply.Applicator, clientset kubernetes.Interface, app *v1.AppService) error { - _, err := clientset.CoreV1().Namespaces().Get(context.Background(), app.TenantID, metav1.GetOptions{}) + _, err := clientset.CoreV1().Namespaces().Get(context.Background(), app.GetNamespace(), metav1.GetOptions{}) if err != nil { if k8sErrors.IsNotFound(err) { _, err = clientset.CoreV1().Namespaces().Create(context.Background(), app.GetTenant(), metav1.CreateOptions{}) diff --git a/worker/appm/store/resource.go b/worker/appm/store/resource.go index bb89a5349..ad5bb3e45 100644 --- a/worker/appm/store/resource.go +++ b/worker/appm/store/resource.go @@ -66,12 +66,20 @@ func (r *ResourceCache) SetPodResource(pod *corev1.Pod) { defer r.lock.Unlock() namespace := pod.Namespace re := v1.CalculatePodResource(pod) - if nr, ok := r.resources[namespace]; ok && nr != nil { - nr.SetPodResource(pod.Name, re) - } else { - nameR := make(NamespaceResource) - nameR.SetPodResource(pod.Name, re) - r.resources[namespace] = &nameR + // Compatible with resources with tenantID as namespace + nsKeys := []string{namespace} + labels := pod.Labels + if tenantID, ok := labels["tenant_id"]; ok && tenantID != namespace { + nsKeys = append(nsKeys, tenantID) + } + for _, ns := range nsKeys { + if nr, ok := r.resources[ns]; ok && nr != nil { + nr.SetPodResource(pod.Name, re) + } else { + nameR := make(NamespaceResource) + nameR.SetPodResource(pod.Name, re) + r.resources[ns] = &nameR + } } } diff --git a/worker/appm/store/store.go b/worker/appm/store/store.go index b9f77d9fe..822612ed9 100644 --- a/worker/appm/store/store.go +++ b/worker/appm/store/store.go @@ -1229,7 +1229,7 @@ func (a *appRuntimeStore) GetTenantResourceList() []TenantResource { func (a *appRuntimeStore) GetTenantRunningApp(tenantID string) (list []*v1.AppService) { a.appServices.Range(func(k, v interface{}) bool { appService, _ := v.(*v1.AppService) - if appService != nil && (appService.TenantID == tenantID || tenantID == corev1.NamespaceAll) && !appService.IsClosed() { + if appService != nil && (appService.TenantID == tenantID || tenantID == corev1.NamespaceAll || appService.GetNamespace() == tenantID) && !appService.IsClosed() { list = append(list, appService) } return true @@ -1578,7 +1578,7 @@ func filterOutNotRainbondNamespace(ns *corev1.Namespace) bool { if ns.Labels == nil { return false } - return ns.Labels["creator"] == "Rainbond" + return ns.Labels["creator"] == "Rainbond" || ns.Labels[constants.ResourceManagedByLabel] == constants.Rainbond }() return curVersion || oldVersion } diff --git a/worker/appm/types/v1/labels.go b/worker/appm/types/v1/labels.go index 54ebb56d3..2a203c8cd 100644 --- a/worker/appm/types/v1/labels.go +++ b/worker/appm/types/v1/labels.go @@ -33,6 +33,6 @@ func (a *AppService) GetCommonLabels(labels ...map[string]string) map[string]str resultLabel["tenant_name"] = a.TenantName resultLabel["tenant_id"] = a.TenantID resultLabel["app_id"] = a.AppID - resultLabel["app"] = a.ServiceAlias + resultLabel["app"] = a.K8sApp return resultLabel } diff --git a/worker/appm/types/v1/v1.go b/worker/appm/types/v1/v1.go index 5e8b5c9c7..2161cc120 100644 --- a/worker/appm/types/v1/v1.go +++ b/worker/appm/types/v1/v1.go @@ -103,9 +103,11 @@ type AppServiceBase struct { IsWindowsService bool CreaterID string //depend all service id - Dependces []string - ExtensionSet map[string]string - GovernanceMode string + Dependces []string + ExtensionSet map[string]string + GovernanceMode string + K8sApp string + K8sComponentName string } //GetComponentDefinitionName get component definition name by component kind @@ -140,6 +142,11 @@ func (a *AppServiceBase) SetDiscoveryCfg(discoveryCfg *dbmodel.ThirdPartySvcDisc a.discoveryCfg = discoveryCfg } +// SetDiscoveryCfg - +func (a *AppServiceBase) GetK8sWorkloadName() string { + return fmt.Sprintf("%s-%s", a.K8sApp, a.K8sComponentName) +} + //AppService a service of rainbond app state in kubernetes type AppService struct { AppServiceBase @@ -642,6 +649,11 @@ func (a *AppService) GetTenant() *corev1.Namespace { return a.tenant } +//GetNamespace get tenant namespace name +func (a *AppService) GetNamespace() string { + return a.tenant.Name +} + // SetDeletedResources sets the resources that need to be deleted func (a *AppService) SetDeletedResources(old *AppService) { if old == nil { @@ -741,7 +753,7 @@ func (a *AppService) GetClaimsManually() []*corev1.PersistentVolumeClaim { // SetClaim set claim func (a *AppService) SetClaim(claim *corev1.PersistentVolumeClaim) { - claim.Namespace = a.TenantID + claim.Namespace = a.GetNamespace() if len(a.claims) > 0 { for i, c := range a.claims { if c.GetName() == claim.GetName() { @@ -755,7 +767,7 @@ func (a *AppService) SetClaim(claim *corev1.PersistentVolumeClaim) { // SetClaimManually sets claim that needs to be created manually. func (a *AppService) SetClaimManually(claim *corev1.PersistentVolumeClaim) { - claim.Namespace = a.TenantID + claim.Namespace = a.GetNamespace() if len(a.claimsmanual) > 0 { for i, c := range a.claimsmanual { if c.GetName() == claim.GetName() { diff --git a/worker/appm/volume/config-file.go b/worker/appm/volume/config-file.go index fe2ed4b72..28ab2f114 100644 --- a/worker/appm/volume/config-file.go +++ b/worker/appm/volume/config-file.go @@ -60,7 +60,7 @@ func (v *ConfigFileVolume) CreateVolume(define *Define) error { cmap := &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: util.NewUUID(), - Namespace: v.as.TenantID, + Namespace: v.as.GetNamespace(), Labels: v.as.GetCommonLabels(), }, Data: make(map[string]string), @@ -90,7 +90,7 @@ func (v *ConfigFileVolume) CreateDependVolume(define *Define) error { cmap := &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: util.NewUUID(), - Namespace: v.as.TenantID, + Namespace: v.as.GetNamespace(), Labels: v.as.GetCommonLabels(), }, Data: make(map[string]string), diff --git a/worker/gc/gc.go b/worker/gc/gc.go index 753d0d7c4..d2a2af0a3 100644 --- a/worker/gc/gc.go +++ b/worker/gc/gc.go @@ -21,6 +21,7 @@ package gc import ( "context" "fmt" + "github.com/goodrain/rainbond/db" "os" "path" @@ -82,12 +83,20 @@ func (g *GarbageCollector) DelPvPvcByServiceID(serviceGCReq model.ServiceGCTaskB logrus.Infof("service_id: %s", serviceGCReq.ServiceID) deleteOpts := metav1.DeleteOptions{} listOpts := g.listOptionsServiceID(serviceGCReq.ServiceID) + namespace := serviceGCReq.TenantID + tenant, err := db.GetManager().TenantDao().GetTenantByUUID(serviceGCReq.TenantID) + if err != nil { + logrus.Warningf("tenant id: %s; get tenant before delete a collection for PV: %v", serviceGCReq.TenantID, err) + } + if tenant != nil { + namespace = tenant.Namespace + } if err := g.clientset.CoreV1().PersistentVolumes().DeleteCollection(context.Background(), deleteOpts, listOpts); err != nil { - logrus.Warningf("service id: %s; delete a collection fo PV: %v", serviceGCReq.ServiceID, err) + logrus.Warningf("service id: %s; delete a collection for PV: %v", serviceGCReq.ServiceID, err) } - if err := g.clientset.CoreV1().PersistentVolumeClaims(serviceGCReq.TenantID).DeleteCollection(context.Background(), deleteOpts, listOpts); err != nil { - logrus.Warningf("service id: %s; delete a collection fo PVC: %v", serviceGCReq.ServiceID, err) + if err := g.clientset.CoreV1().PersistentVolumeClaims(namespace).DeleteCollection(context.Background(), deleteOpts, listOpts); err != nil { + logrus.Warningf("service id: %s; delete a collection for PVC: %v", serviceGCReq.ServiceID, err) } } @@ -95,38 +104,46 @@ func (g *GarbageCollector) DelPvPvcByServiceID(serviceGCReq model.ServiceGCTaskB func (g *GarbageCollector) DelKubernetesObjects(serviceGCReq model.ServiceGCTaskBody) { deleteOpts := metav1.DeleteOptions{} listOpts := g.listOptionsServiceID(serviceGCReq.ServiceID) - if err := g.clientset.AppsV1().Deployments(serviceGCReq.TenantID).DeleteCollection(context.Background(), deleteOpts, listOpts); err != nil { + namespace := serviceGCReq.TenantID + tenant, err := db.GetManager().TenantDao().GetTenantByUUID(serviceGCReq.TenantID) + if err != nil { + logrus.Warningf("[DelKubernetesObjects] get tenant(%s): %v", serviceGCReq.TenantID, err) + } + if tenant != nil { + namespace = tenant.Namespace + } + if err := g.clientset.AppsV1().Deployments(namespace).DeleteCollection(context.Background(), deleteOpts, listOpts); err != nil { logrus.Warningf("[DelKubernetesObjects] delete deployments(%s): %v", serviceGCReq.ServiceID, err) } - if err := g.clientset.AppsV1().StatefulSets(serviceGCReq.TenantID).DeleteCollection(context.Background(), deleteOpts, listOpts); err != nil { + if err := g.clientset.AppsV1().StatefulSets(namespace).DeleteCollection(context.Background(), deleteOpts, listOpts); err != nil { logrus.Warningf("[DelKubernetesObjects] delete statefulsets(%s): %v", serviceGCReq.ServiceID, err) } - if err := g.clientset.ExtensionsV1beta1().Ingresses(serviceGCReq.TenantID).DeleteCollection(context.Background(), deleteOpts, listOpts); err != nil { + if err := g.clientset.ExtensionsV1beta1().Ingresses(namespace).DeleteCollection(context.Background(), deleteOpts, listOpts); err != nil { logrus.Warningf("[DelKubernetesObjects] delete ingresses(%s): %v", serviceGCReq.ServiceID, err) } - if err := g.clientset.CoreV1().Secrets(serviceGCReq.TenantID).DeleteCollection(context.Background(), deleteOpts, listOpts); err != nil { + if err := g.clientset.CoreV1().Secrets(namespace).DeleteCollection(context.Background(), deleteOpts, listOpts); err != nil { logrus.Warningf("[DelKubernetesObjects] delete secrets(%s): %v", serviceGCReq.ServiceID, err) } - if err := g.clientset.CoreV1().ConfigMaps(serviceGCReq.TenantID).DeleteCollection(context.Background(), deleteOpts, listOpts); err != nil { + if err := g.clientset.CoreV1().ConfigMaps(namespace).DeleteCollection(context.Background(), deleteOpts, listOpts); err != nil { logrus.Warningf("[DelKubernetesObjects] delete configmaps(%s): %v", serviceGCReq.ServiceID, err) } - if err := g.clientset.AutoscalingV2beta2().HorizontalPodAutoscalers(serviceGCReq.TenantID).DeleteCollection(context.Background(), deleteOpts, listOpts); err != nil { + if err := g.clientset.AutoscalingV2beta2().HorizontalPodAutoscalers(namespace).DeleteCollection(context.Background(), deleteOpts, listOpts); err != nil { logrus.Warningf("[DelKubernetesObjects] delete hpas(%s): %v", serviceGCReq.ServiceID, err) } // kubernetes does not support api for deleting collection of service // read: https://github.com/kubernetes/kubernetes/issues/68468#issuecomment-419981870 - serviceList, err := g.clientset.CoreV1().Services(serviceGCReq.TenantID).List(context.Background(), listOpts) + serviceList, err := g.clientset.CoreV1().Services(namespace).List(context.Background(), listOpts) if err != nil { logrus.Warningf("[DelKubernetesObjects] list services(%s): %v", serviceGCReq.ServiceID, err) } else { for _, svc := range serviceList.Items { - if err := g.clientset.CoreV1().Services(serviceGCReq.TenantID).Delete(context.Background(), svc.Name, deleteOpts); err != nil { + if err := g.clientset.CoreV1().Services(namespace).Delete(context.Background(), svc.Name, deleteOpts); err != nil { logrus.Warningf("[DelKubernetesObjects] delete service(%s): %v", svc.GetName(), err) } } } // delete endpoints after deleting services - if err := g.clientset.CoreV1().Endpoints(serviceGCReq.TenantID).DeleteCollection(context.Background(), deleteOpts, listOpts); err != nil { + if err := g.clientset.CoreV1().Endpoints(namespace).DeleteCollection(context.Background(), deleteOpts, listOpts); err != nil { logrus.Warningf("[DelKubernetesObjects] delete endpoints(%s): %v", serviceGCReq.ServiceID, err) } } diff --git a/worker/handle/manager.go b/worker/handle/manager.go index 615e372dd..a0c5e89a5 100644 --- a/worker/handle/manager.go +++ b/worker/handle/manager.go @@ -488,8 +488,12 @@ func (m *Manager) deleteTenant(task *model.Task) (err error) { return } }() - - if err = m.cfg.KubeClient.CoreV1().Namespaces().Delete(context.Background(), body.TenantID, metav1.DeleteOptions{ + tenant, err := db.GetManager().TenantDao().GetTenantByUUID(body.TenantID) + if err != nil { + err = fmt.Errorf("tenant id: %s; find tenant: %v", body.TenantID, err) + return + } + if err = m.cfg.KubeClient.CoreV1().Namespaces().Delete(context.Background(), tenant.Namespace, metav1.DeleteOptions{ GracePeriodSeconds: util.Int64(0), }); err != nil && !k8sErrors.IsNotFound(err) { err = fmt.Errorf("delete namespace: %v", err) diff --git a/worker/server/server.go b/worker/server/server.go index dad16df56..f35f57ec9 100644 --- a/worker/server/server.go +++ b/worker/server/server.go @@ -216,7 +216,11 @@ func (r *RuntimeServer) getHelmAppStatus(app *model.Application) (*pb.AppStatus, //if TenantId is "" will return the sum of the all tenant func (r *RuntimeServer) GetTenantResource(ctx context.Context, re *pb.TenantRequest) (*pb.TenantResource, error) { var tr pb.TenantResource - res := r.store.GetTenantResource(re.TenantId) + tenant, err := db.GetManager().TenantDao().GetTenantByUUID(re.TenantId) + if err != nil { + return nil, err + } + res := r.store.GetTenantResource(tenant.Namespace) runningApps := r.store.GetTenantRunningApp(re.TenantId) for _, app := range runningApps { if app.ServiceKind == model.ServiceKindThirdParty { @@ -698,13 +702,16 @@ func (r *RuntimeServer) ListAppServices(ctx context.Context, in *pb.AppReq) (*pb if err != nil { return nil, err } - + tenant, err := db.GetManager().TenantDao().GetTenantByUUID(app.TenantID) + if err != nil { + return nil, err + } selector := labels.NewSelector() instanceReq, _ := labels.NewRequirement(constants.ResourceInstanceLabel, selection.Equals, []string{app.AppName}) selector = selector.Add(*instanceReq) managedReq, _ := labels.NewRequirement(constants.ResourceManagedByLabel, selection.Equals, []string{"Helm"}) selector = selector.Add(*managedReq) - services, err := r.store.ListServices(app.TenantID, selector) + services, err := r.store.ListServices(tenant.Namespace, selector) if err != nil { return nil, err } @@ -785,8 +792,11 @@ func (r *RuntimeServer) ListHelmAppRelease(ctx context.Context, req *pb.AppReq) if err != nil { return nil, err } - - h, err := helm.NewHelm(app.TenantID, r.conf.Helm.RepoFile, r.conf.Helm.RepoCache) + tenant, err := db.GetManager().TenantDao().GetTenantByUUID(app.TenantID) + if err != nil { + return nil, err + } + h, err := helm.NewHelm(tenant.Namespace, r.conf.Helm.RepoFile, r.conf.Helm.RepoCache) if err != nil { return nil, err }