From 2033adb3012639b585a4211d8953c98e36f9ed15 Mon Sep 17 00:00:00 2001 From: Robert Choi Date: Mon, 31 Jul 2023 18:06:56 +0900 Subject: [PATCH 01/23] bugfix: validate extraEnv before creating DB record --- internal/usecase/app-serve-app.go | 50 +++++++++++++++---------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/internal/usecase/app-serve-app.go b/internal/usecase/app-serve-app.go index 4b46f41f..501b4580 100644 --- a/internal/usecase/app-serve-app.go +++ b/internal/usecase/app-serve-app.go @@ -89,21 +89,13 @@ func (u *AppServeAppUsecase) CreateAppServeApp(app *domain.AppServeApp) (string, } } - appId, taskId, err := u.repo.CreateAppServeApp(app) - if err != nil { - log.Error(err) - return "", "", errors.Wrap(err, "Failed to create app.") - } - - fmt.Printf("appId = %s, taskId = %s", appId, taskId) - extEnv := app.AppServeAppTasks[0].ExtraEnv if extEnv != "" { /* Preprocess extraEnv param */ log.Debug("extraEnv received: ", extEnv) tempMap := map[string]string{} - err = json.Unmarshal([]byte(extEnv), &tempMap) + err := json.Unmarshal([]byte(extEnv), &tempMap) if err != nil { log.Error(err) return "", "", errors.Wrap(err, "Failed to process extraEnv param.") @@ -122,6 +114,14 @@ func (u *AppServeAppUsecase) CreateAppServeApp(app *domain.AppServeApp) (string, log.Debug("After transform, extraEnv: ", extEnv) } + appId, taskId, err := u.repo.CreateAppServeApp(app) + if err != nil { + log.Error(err) + return "", "", errors.Wrap(err, "Failed to create app.") + } + + fmt.Printf("appId = %s, taskId = %s", appId, taskId) + // TODO: Validate PV params // Call argo workflow @@ -379,22 +379,6 @@ func (u *AppServeAppUsecase) UpdateAppServeApp(app *domain.AppServeApp, appTask } } - taskId, err := u.repo.CreateTask(appTask) - if err != nil { - log.Info("taskId = ", taskId) - return "", fmt.Errorf("failed to update app-serve application. Err: %s", err) - } - - // Sync new task status to the parent app - log.Info("Updating app status to 'PREPARING'..") - - err = u.repo.UpdateStatus(app.ID, taskId, "PREPARING", "") - if err != nil { - log.Debug("appId = ", app.ID) - log.Debug("taskId = ", taskId) - return "", fmt.Errorf("failed to update app status on UpdateAppServeApp. Err: %s", err) - } - extEnv := appTask.ExtraEnv if extEnv != "" { /* Preprocess extraEnv param */ @@ -421,6 +405,22 @@ func (u *AppServeAppUsecase) UpdateAppServeApp(app *domain.AppServeApp, appTask log.Debug("After transform, extraEnv: ", extEnv) } + taskId, err := u.repo.CreateTask(appTask) + if err != nil { + log.Info("taskId = ", taskId) + return "", fmt.Errorf("failed to update app-serve application. Err: %s", err) + } + + // Sync new task status to the parent app + log.Info("Updating app status to 'PREPARING'..") + + err = u.repo.UpdateStatus(app.ID, taskId, "PREPARING", "") + if err != nil { + log.Debug("appId = ", app.ID) + log.Debug("taskId = ", taskId) + return "", fmt.Errorf("failed to update app status on UpdateAppServeApp. Err: %s", err) + } + // Call argo workflow workflow := "serve-java-app" From 2dad91c2d2669d8308ca1756ac62e23922749706 Mon Sep 17 00:00:00 2001 From: Taekyu Date: Mon, 31 Jul 2023 19:19:18 +0900 Subject: [PATCH 02/23] bugfix. fix end date for dashboard ( pod calendar ) --- internal/usecase/dashboard.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/usecase/dashboard.go b/internal/usecase/dashboard.go index f91732ca..bc765f12 100644 --- a/internal/usecase/dashboard.go +++ b/internal/usecase/dashboard.go @@ -277,7 +277,7 @@ func (u *DashboardUsecase) getChartFromPrometheus(organizationId string, chartTy yearInt, _ := strconv.Atoi(year) monthInt, _ := strconv.Atoi(month) startDate := time.Date(yearInt, time.Month(monthInt), 1, 0, 0, 0, 0, time.UTC) - endDate := startDate.Add(time.Hour * 24 * 30) + endDate := time.Date(yearInt, time.Month(monthInt+1), 1, 0, 0, 0, 0, time.UTC) if now.Year() < yearInt { return res, fmt.Errorf("Invalid year") From 4e3e6a76122c58e60853b1210eadb693480ac3c4 Mon Sep 17 00:00:00 2001 From: Taekyu Date: Tue, 1 Aug 2023 15:16:51 +0900 Subject: [PATCH 03/23] bugfix. resource value change GB to GiB in dashboard. --- internal/usecase/dashboard.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/internal/usecase/dashboard.go b/internal/usecase/dashboard.go index bc765f12..a9927cd8 100644 --- a/internal/usecase/dashboard.go +++ b/internal/usecase/dashboard.go @@ -185,36 +185,36 @@ func (u *DashboardUsecase) GetResources(ctx context.Context, organizationId stri if err != nil { return out, err } - memory := 0 + memory := float64(0) for _, val := range result.Data.Result { memoryVal, err := strconv.Atoi(val.Value[1].(string)) if err != nil { continue } if memoryVal > 0 { - memoryVal = memoryVal / 1024 / 1024 / 1024 - memory = memory + memoryVal + memory_ := float64(memoryVal) / float64(1024) / float64(1024) / float64(1024) + memory = memory + memory_ } } - out.Memory = fmt.Sprintf("%d GB", memory) + out.Memory = fmt.Sprintf("%v GiB", math.Round(memory)) // Storage result, err = thanosClient.Get("sum by (taco_cluster) (kubelet_volume_stats_capacity_bytes)") if err != nil { return out, err } - storage := 0 + storage := float64(0) for _, val := range result.Data.Result { storageVal, err := strconv.Atoi(val.Value[1].(string)) if err != nil { continue } if storageVal > 0 { - storageVal = storageVal / 1024 / 1024 / 1024 - storage = storage + storageVal + storage_ := float64(storageVal) / float64(1024) / float64(1024) / float64(1024) + storage = storage + storage_ } } - out.Storage = fmt.Sprintf("%d GB", storage) + out.Storage = fmt.Sprintf("%v GiB", math.Round(storage)) return } From c031a6e3fdc5cd8fa21ac96299313c7106c11152 Mon Sep 17 00:00:00 2001 From: Robert Choi Date: Tue, 1 Aug 2023 16:15:14 +0900 Subject: [PATCH 04/23] app-serving: validate name param --- internal/delivery/http/app-serve-app.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/internal/delivery/http/app-serve-app.go b/internal/delivery/http/app-serve-app.go index 06b8965f..0f81babc 100644 --- a/internal/delivery/http/app-serve-app.go +++ b/internal/delivery/http/app-serve-app.go @@ -3,6 +3,7 @@ package http import ( "fmt" "net/http" + "regexp" "strconv" "strings" "time" @@ -129,6 +130,13 @@ func (h *AppServeAppHandler) CreateAppServeApp(w http.ResponseWriter, r *http.Re app.AppServeAppTasks = append(app.AppServeAppTasks, task) + // Validate name param + re, _ := regexp.Compile("^[a-z][a-z0-9-]*$") + if !(re.MatchString(app.Name)) { + ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("error: name should consist of alphanumeric characters and hyphens only"), "", "")) + return + } + // Validate port param for springboot app if app.AppType == "springboot" { if task.Port == "" { From 9f9d0f01a88e76f007d5e514fbfedc680ff1b23d Mon Sep 17 00:00:00 2001 From: Robert Choi Date: Tue, 1 Aug 2023 17:16:03 +0900 Subject: [PATCH 05/23] app-serving: check if app name already exists --- internal/delivery/http/app-serve-app.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/internal/delivery/http/app-serve-app.go b/internal/delivery/http/app-serve-app.go index 0f81babc..f46b8c24 100644 --- a/internal/delivery/http/app-serve-app.go +++ b/internal/delivery/http/app-serve-app.go @@ -137,6 +137,16 @@ func (h *AppServeAppHandler) CreateAppServeApp(w http.ResponseWriter, r *http.Re return } + exist, err := h.usecase.IsAppServeAppNameExist(organizationId, app.Name) + if err != nil { + ErrorJSON(w, r, httpErrors.NewInternalServerError(err, "", "")) + return + } + if exist { + ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("error: name '%s' already exists.", app.Name), "", "")) + return + } + // Validate port param for springboot app if app.AppType == "springboot" { if task.Port == "" { From 3345db10b29a9f615dc1d596444af79f752a4983 Mon Sep 17 00:00:00 2001 From: Robert Choi Date: Wed, 2 Aug 2023 11:20:34 +0900 Subject: [PATCH 06/23] bugfix: assign transformed extraEnv to existing var --- internal/usecase/app-serve-app.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/internal/usecase/app-serve-app.go b/internal/usecase/app-serve-app.go index 501b4580..63eaee7b 100644 --- a/internal/usecase/app-serve-app.go +++ b/internal/usecase/app-serve-app.go @@ -110,7 +110,7 @@ func (u *AppServeAppUsecase) CreateAppServeApp(app *domain.AppServeApp) (string, } mJson, _ := json.Marshal(newExtEnv) - extEnv := string(mJson) + extEnv = string(mJson) log.Debug("After transform, extraEnv: ", extEnv) } @@ -401,7 +401,6 @@ func (u *AppServeAppUsecase) UpdateAppServeApp(app *domain.AppServeApp, appTask mJson, _ := json.Marshal(newExtEnv) extEnv = string(mJson) - log.Debug("After transform, extraEnv: ", extEnv) } From 3546f8a41a0b481b9ebaafbfcf07401f970388a9 Mon Sep 17 00:00:00 2001 From: Taekyu Date: Tue, 1 Aug 2023 14:18:58 +0900 Subject: [PATCH 07/23] bugfix. fix filtering logic in users --- internal/delivery/http/user.go | 2 +- internal/pagination/pagination.go | 2 +- internal/repository/user.go | 57 +++++++++++++++++++------------ internal/usecase/auth.go | 8 ++--- internal/usecase/user.go | 26 +++++++++----- 5 files changed, 59 insertions(+), 36 deletions(-) diff --git a/internal/delivery/http/user.go b/internal/delivery/http/user.go index 135393ed..8443cec0 100644 --- a/internal/delivery/http/user.go +++ b/internal/delivery/http/user.go @@ -180,7 +180,7 @@ func (u UserHandler) List(w http.ResponseWriter, r *http.Request) { ErrorJSON(w, r, httpErrors.NewBadRequestError(err, "", "")) return } - users, err := u.usecase.List(r.Context(), organizationId, pg) + users, err := u.usecase.ListWithPagination(r.Context(), organizationId, pg) if err != nil { if _, status := httpErrors.ErrorResponse(err); status == http.StatusNotFound { ResponseJSON(w, r, http.StatusNoContent, domain.ListUserResponse{}) diff --git a/internal/pagination/pagination.go b/internal/pagination/pagination.go index 01f8f513..40ed71ff 100644 --- a/internal/pagination/pagination.go +++ b/internal/pagination/pagination.go @@ -105,7 +105,7 @@ func NewPagination(urlParams *url.Values) (*Pagination, error) { //"combinedFilter=key1,key2:value" filterArray := strings.Split(value[0], ":") if len(filterArray) == 2 { - keys := strings.Split(filterArray[0], ",") + keys := strings.Split(helper.ToSnakeCase(strings.Replace(filterArray[0], "[]", "", -1)), ",") value := filterArray[1] pg.CombinedFilter = CombinedFilter{ diff --git a/internal/repository/user.go b/internal/repository/user.go index 5188c0d7..5403d81f 100644 --- a/internal/repository/user.go +++ b/internal/repository/user.go @@ -18,7 +18,8 @@ type IUserRepository interface { Create(accountId string, organizationId string, password string, name string) (domain.User, error) CreateWithUuid(uuid uuid.UUID, accountId string, name string, password string, email string, department string, description string, organizationId string, roleId uuid.UUID) (domain.User, error) - List(pg *pagination.Pagination, filters ...FilterFunc) (out *[]domain.User, err error) + List(filters ...FilterFunc) (out *[]domain.User, err error) + ListWithPagination(pg *pagination.Pagination, organizationId string) (out *[]domain.User, err error) Get(accountId string, organizationId string) (domain.User, error) GetByUuid(userId uuid.UUID) (domain.User, error) UpdateWithUuid(uuid uuid.UUID, accountId string, name string, password string, roleId uuid.UUID, email string, @@ -143,23 +144,11 @@ func (r *UserRepository) NameFilter(name string) FilterFunc { } } -func (r *UserRepository) List(pg *pagination.Pagination, filters ...FilterFunc) (*[]domain.User, error) { - var res *gorm.DB +func (r *UserRepository) List(filters ...FilterFunc) (*[]domain.User, error) { var users []User - var total int64 - - if pg == nil { - pg = pagination.NewDefaultPagination() - } - + var res *gorm.DB if filters == nil { - r.db.Model(&User{}).Count(&total) - - pg.TotalRows = total - pg.TotalPages = int(math.Ceil(float64(total) / float64(pg.Limit))) - orderQuery := fmt.Sprintf("%s %s", pg.SortColumn, pg.SortOrder) - res = r.db.Model(&User{}).Offset(pg.GetOffset()).Limit(pg.GetLimit()).Order(orderQuery). - Preload("Organization").Preload("Role").Find(&users) + res = r.db.Model(&User{}).Preload("Organization").Preload("Role").Find(&users) } else { combinedFilter := func(filters ...FilterFunc) FilterFunc { return func(user *gorm.DB) *gorm.DB { @@ -170,15 +159,38 @@ func (r *UserRepository) List(pg *pagination.Pagination, filters ...FilterFunc) } } cFunc := combinedFilter(filters...) - cFunc(r.db.Model(&User{})).Count(&total) + res = cFunc(r.db.Model(&User{}).Preload("Organization").Preload("Role")).Find(&users) + } + if res.Error != nil { + log.Errorf("error is :%s(%T)", res.Error.Error(), res.Error) + return nil, res.Error + } + if res.RowsAffected == 0 { + return nil, httpErrors.NewNotFoundError(httpErrors.NotFound, "", "") + } + + var out []domain.User + for _, user := range users { + out = append(out, r.reflect(user)) + } - pg.TotalRows = total - pg.TotalPages = int(math.Ceil(float64(total) / float64(pg.Limit))) - orderQuery := fmt.Sprintf("%s %s", pg.SortColumn, pg.SortOrder) - res = cFunc(r.db.Model(&User{}).Offset(pg.GetOffset()).Limit(pg.GetLimit()).Order(orderQuery). - Preload("Organization").Preload("Role")).Find(&users) + return &out, nil +} +func (r *UserRepository) ListWithPagination(pg *pagination.Pagination, organizationId string) (*[]domain.User, error) { + var users []User + + if pg == nil { + pg = pagination.NewDefaultPagination() } + + filterFunc := CombinedGormFilter("users", pg.GetFilters(), pg.CombinedFilter) + db := filterFunc(r.db.Model(&User{}).Where("organization_id = ?", organizationId)) + db.Count(&pg.TotalRows) + + pg.TotalPages = int(math.Ceil(float64(pg.TotalRows) / float64(pg.Limit))) + orderQuery := fmt.Sprintf("%s %s", pg.SortColumn, pg.SortOrder) + res := db.Preload("Organization").Preload("Role").Offset(pg.GetOffset()).Limit(pg.GetLimit()).Order(orderQuery).Find(&users) if res.Error != nil { log.Errorf("error is :%s(%T)", res.Error.Error(), res.Error) return nil, res.Error @@ -194,6 +206,7 @@ func (r *UserRepository) List(pg *pagination.Pagination, filters ...FilterFunc) return &out, nil } + func (r *UserRepository) Get(accountId string, organizationId string) (domain.User, error) { user, err := r.getUserByAccountId(accountId, organizationId) if err != nil { diff --git a/internal/usecase/auth.go b/internal/usecase/auth.go index 668f665b..02b43103 100644 --- a/internal/usecase/auth.go +++ b/internal/usecase/auth.go @@ -104,7 +104,7 @@ func (u *AuthUsecase) Logout(accessToken string, organizationName string) error return nil } func (u *AuthUsecase) FindId(code string, email string, userName string, organizationId string) (string, error) { - users, err := u.userRepository.List(nil, u.userRepository.OrganizationFilter(organizationId), + users, err := u.userRepository.List(u.userRepository.OrganizationFilter(organizationId), u.userRepository.NameFilter(userName), u.userRepository.EmailFilter(email)) if err != nil && users == nil { return "", httpErrors.NewBadRequestError(err, "A_INVALID_ID", "") @@ -134,7 +134,7 @@ func (u *AuthUsecase) FindId(code string, email string, userName string, organiz } func (u *AuthUsecase) FindPassword(code string, accountId string, email string, userName string, organizationId string) error { - users, err := u.userRepository.List(nil, u.userRepository.OrganizationFilter(organizationId), + users, err := u.userRepository.List(u.userRepository.OrganizationFilter(organizationId), u.userRepository.AccountIdFilter(accountId), u.userRepository.NameFilter(userName), u.userRepository.EmailFilter(email)) if err != nil && users == nil { @@ -198,10 +198,10 @@ func (u *AuthUsecase) VerifyIdentity(accountId string, email string, userName st var err error if accountId == "" { - users, err = u.userRepository.List(nil, u.userRepository.OrganizationFilter(organizationId), + users, err = u.userRepository.List(u.userRepository.OrganizationFilter(organizationId), u.userRepository.NameFilter(userName), u.userRepository.EmailFilter(email)) } else { - users, err = u.userRepository.List(nil, u.userRepository.OrganizationFilter(organizationId), + users, err = u.userRepository.List(u.userRepository.OrganizationFilter(organizationId), u.userRepository.AccountIdFilter(accountId), u.userRepository.NameFilter(userName), u.userRepository.EmailFilter(email)) } diff --git a/internal/usecase/user.go b/internal/usecase/user.go index 41147aa2..a65b6649 100644 --- a/internal/usecase/user.go +++ b/internal/usecase/user.go @@ -24,7 +24,8 @@ type IUserUsecase interface { DeleteAdmin(organizationId string) error DeleteAll(ctx context.Context, organizationId string) error Create(ctx context.Context, user *domain.User) (*domain.User, error) - List(ctx context.Context, organizationId string, pg *pagination.Pagination) (*[]domain.User, error) + List(ctx context.Context, organizationId string) (*[]domain.User, error) + ListWithPagination(ctx context.Context, organizationId string, pg *pagination.Pagination) (*[]domain.User, error) Get(userId uuid.UUID) (*domain.User, error) Update(ctx context.Context, userId uuid.UUID, user *domain.User) (*domain.User, error) ResetPassword(userId uuid.UUID) error @@ -321,13 +322,22 @@ func (u *UserUsecase) UpdatePasswordByAccountId(ctx context.Context, accountId s return nil } -func (u *UserUsecase) List(ctx context.Context, organizationId string, pg *pagination.Pagination) (*[]domain.User, error) { - users, err := u.userRepository.List(pg, u.userRepository.OrganizationFilter(organizationId)) +func (u *UserUsecase) List(ctx context.Context, organizationId string) (users *[]domain.User, err error) { + users, err = u.userRepository.List(u.userRepository.OrganizationFilter(organizationId)) if err != nil { return nil, err } - return users, nil + return +} + +func (u *UserUsecase) ListWithPagination(ctx context.Context, organizationId string, pg *pagination.Pagination) (users *[]domain.User, err error) { + users, err = u.userRepository.ListWithPagination(pg, organizationId) + if err != nil { + return nil, err + } + + return } func (u *UserUsecase) Get(userId uuid.UUID) (*domain.User, error) { @@ -343,7 +353,7 @@ func (u *UserUsecase) Get(userId uuid.UUID) (*domain.User, error) { } func (u *UserUsecase) GetByAccountId(ctx context.Context, accountId string, organizationId string) (*domain.User, error) { - users, err := u.userRepository.List(nil, u.userRepository.OrganizationFilter(organizationId), + users, err := u.userRepository.List(u.userRepository.OrganizationFilter(organizationId), u.userRepository.AccountIdFilter(accountId)) if err != nil { return nil, err @@ -353,7 +363,7 @@ func (u *UserUsecase) GetByAccountId(ctx context.Context, accountId string, orga } func (u *UserUsecase) GetByEmail(ctx context.Context, email string, organizationId string) (*domain.User, error) { - users, err := u.userRepository.List(nil, u.userRepository.OrganizationFilter(organizationId), + users, err := u.userRepository.List(u.userRepository.OrganizationFilter(organizationId), u.userRepository.EmailFilter(email)) if err != nil { return nil, err @@ -395,7 +405,7 @@ func (u *UserUsecase) UpdateByAccountId(ctx context.Context, accountId string, u } } - users, err := u.userRepository.List(nil, u.userRepository.OrganizationFilter(userInfo.GetOrganizationId()), + users, err := u.userRepository.List(u.userRepository.OrganizationFilter(userInfo.GetOrganizationId()), u.userRepository.AccountIdFilter(accountId)) if err != nil { if _, code := httpErrors.ErrorResponse(err); code == http.StatusNotFound { @@ -551,7 +561,7 @@ func (u *UserUsecase) UpdateByAccountIdByAdmin(ctx context.Context, accountId st } } - users, err := u.userRepository.List(nil, u.userRepository.OrganizationFilter(userInfo.GetOrganizationId()), + users, err := u.userRepository.List(u.userRepository.OrganizationFilter(userInfo.GetOrganizationId()), u.userRepository.AccountIdFilter(accountId)) if err != nil { if _, code := httpErrors.ErrorResponse(err); code == http.StatusNotFound { From 8c83023692e987838610a774f803d4c32133ba3a Mon Sep 17 00:00:00 2001 From: Taekyu Date: Wed, 2 Aug 2023 14:45:38 +0900 Subject: [PATCH 08/23] bugfix. remove http status '204 empty' --- internal/delivery/http/user.go | 5 ----- internal/repository/user.go | 3 --- 2 files changed, 8 deletions(-) diff --git a/internal/delivery/http/user.go b/internal/delivery/http/user.go index 8443cec0..53797942 100644 --- a/internal/delivery/http/user.go +++ b/internal/delivery/http/user.go @@ -182,11 +182,6 @@ func (u UserHandler) List(w http.ResponseWriter, r *http.Request) { } users, err := u.usecase.ListWithPagination(r.Context(), organizationId, pg) if err != nil { - if _, status := httpErrors.ErrorResponse(err); status == http.StatusNotFound { - ResponseJSON(w, r, http.StatusNoContent, domain.ListUserResponse{}) - return - } - log.ErrorfWithContext(r.Context(), "error is :%s(%T)", err.Error(), err) ErrorJSON(w, r, err) return diff --git a/internal/repository/user.go b/internal/repository/user.go index 5403d81f..2571b1f6 100644 --- a/internal/repository/user.go +++ b/internal/repository/user.go @@ -195,9 +195,6 @@ func (r *UserRepository) ListWithPagination(pg *pagination.Pagination, organizat log.Errorf("error is :%s(%T)", res.Error.Error(), res.Error) return nil, res.Error } - if res.RowsAffected == 0 { - return nil, httpErrors.NewNotFoundError(httpErrors.NotFound, "", "") - } var out []domain.User for _, user := range users { From 9efd4887c48302d22aed4907695ac2ad548ea5d6 Mon Sep 17 00:00:00 2001 From: Taekyu Date: Wed, 2 Aug 2023 18:01:30 +0900 Subject: [PATCH 09/23] bugfix. change promQL query for "pod restart" in dashboard. --- internal/usecase/dashboard.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/usecase/dashboard.go b/internal/usecase/dashboard.go index a9927cd8..5938f0b5 100644 --- a/internal/usecase/dashboard.go +++ b/internal/usecase/dashboard.go @@ -267,7 +267,7 @@ func (u *DashboardUsecase) getChartFromPrometheus(organizationId string, chartTy query = "avg by (taco_cluster) (sum(node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) by (taco_cluster) / sum(node_memory_MemTotal_bytes) by (taco_cluster))" case domain.ChartType_POD.String(): - query = "avg by (taco_cluster) (increase(kube_pod_container_status_restarts_total{namespace!=\"kube-system\"}[1h]))" + query = "sum by (taco_cluster) (changes(kube_pod_container_status_restarts_total{namespace!=\"kube-system\"}[1h]))" case domain.ChartType_TRAFFIC.String(): query = "avg by (taco_cluster) (rate(container_network_receive_bytes_total[1h]))" @@ -340,7 +340,7 @@ func (u *DashboardUsecase) getChartFromPrometheus(organizationId string, chartTy return domain.DashboardChart{}, fmt.Errorf("No data") } - result, err := thanosClient.FetchRange(query, int(now.Unix())-durationSec, int(now.Unix()), intervalSec) + result, err := thanosClient.FetchRange(query, int(now.Unix())-durationSec, int(now.Unix())+10000, intervalSec) if err != nil { return res, err } From b3241f7873e883d98ed22f90fe4523ba77056269 Mon Sep 17 00:00:00 2001 From: Taekyu Date: Thu, 3 Aug 2023 14:12:05 +0900 Subject: [PATCH 10/23] bugfix. update kubernetes version string v1.25 --- scripts/init_postgres.sql | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/init_postgres.sql b/scripts/init_postgres.sql index 2d1cb14d..6434a1d7 100644 --- a/scripts/init_postgres.sql +++ b/scripts/init_postgres.sql @@ -19,14 +19,14 @@ insert into cloud_accounts ( id, name, description, organization_id, cloud_servi values ( 'ce9e0387-01cb-4f37-a22a-fb91b6338434', 'aws', 'aws_description', 'master', 'AWS', 'result', now(), now() ); insert into stack_templates ( id, organization_id, name, description, version, cloud_service, platform, template, kube_version, kube_type, created_at, updated_at, services ) -values ( '49901092-be76-4d4f-94e9-b84525f560b5', 'master', 'AWS Standard (x86)', 'included LMA', 'v1', 'AWS', 'x86', 'aws-reference', 'v1.24', 'AWS', now(), now(), '[{"name": "Logging,Monitoring,Alerting", "type": "LMA", "applications": [{"name": "prometheus-stack", "version": "v.44.3.1", "description": "통계데이터 제공을 위한 backend 플랫폼"}, {"name": "elastic-system", "version": "v1.8.0", "description": "로그 데이터 적재를 위한 Storage"}, {"name": "alertmanager", "version": "v0.23.0", "description": "Alert 관리를 위한 backend 서비스"}, {"name": "grafana", "version": "v6.50.7", "description": "모니터링 통합 포탈"}]}]' ); +values ( '49901092-be76-4d4f-94e9-b84525f560b5', 'master', 'AWS Standard (x86)', 'included LMA', 'v1', 'AWS', 'x86', 'aws-reference', 'v1.25', 'AWS', now(), now(), '[{"name": "Logging,Monitoring,Alerting", "type": "LMA", "applications": [{"name": "prometheus-stack", "version": "v.44.3.1", "description": "통계데이터 제공을 위한 backend 플랫폼"}, {"name": "elastic-system", "version": "v1.8.0", "description": "로그 데이터 적재를 위한 Storage"}, {"name": "alertmanager", "version": "v0.23.0", "description": "Alert 관리를 위한 backend 서비스"}, {"name": "grafana", "version": "v6.50.7", "description": "모니터링 통합 포탈"}]}]' ); insert into stack_templates ( id, organization_id, name, description, version, cloud_service, platform, template, kube_version, kube_type, created_at, updated_at, services ) -values ( '44d5e76b-63db-4dd0-a16e-11bd3f6054cf', 'master', 'AWS MSA Standard (x86)', 'included LMA, SERVICE MESH', 'v1', 'AWS', 'x86', 'aws-msa-reference', 'v1.24', 'AWS', now(), now(), '[{"name": "Logging,Monitoring,Alerting", "type": "LMA", "applications": [{"name": "prometheus-stack", "version": "v.44.3.1", "description": "통계데이터 제공을 위한 backend 플랫폼"}, {"name": "elastic-system", "version": "v1.8.0", "description": "로그 데이터 적재를 위한 Storage"}, {"name": "alertmanager", "version": "v0.23.0", "description": "Alert 관리를 위한 backend 서비스"}, {"name": "grafana", "version": "v6.50.7", "description": "모니터링 통합 포탈"}]}, {"name": "MSA", "type": "SERVICE_MESH", "applications": [{"name": "istio", "version": "v1.13.1", "description": "MSA 플랫폼"}, {"name": "jagger", "version": "v2.27.1", "description": "분산 서비스간 트랜잭션 추적을 위한 로깅 플랫폼"}, {"name": "kiali", "version": "v1.45.1", "description": "MSA 통합 모니터링포탈"}]}]' ); +values ( '44d5e76b-63db-4dd0-a16e-11bd3f6054cf', 'master', 'AWS MSA Standard (x86)', 'included LMA, SERVICE MESH', 'v1', 'AWS', 'x86', 'aws-msa-reference', 'v1.25', 'AWS', now(), now(), '[{"name": "Logging,Monitoring,Alerting", "type": "LMA", "applications": [{"name": "prometheus-stack", "version": "v.44.3.1", "description": "통계데이터 제공을 위한 backend 플랫폼"}, {"name": "elastic-system", "version": "v1.8.0", "description": "로그 데이터 적재를 위한 Storage"}, {"name": "alertmanager", "version": "v0.23.0", "description": "Alert 관리를 위한 backend 서비스"}, {"name": "grafana", "version": "v6.50.7", "description": "모니터링 통합 포탈"}]}, {"name": "MSA", "type": "SERVICE_MESH", "applications": [{"name": "istio", "version": "v1.13.1", "description": "MSA 플랫폼"}, {"name": "jagger", "version": "v2.27.1", "description": "분산 서비스간 트랜잭션 추적을 위한 로깅 플랫폼"}, {"name": "kiali", "version": "v1.45.1", "description": "MSA 통합 모니터링포탈"}]}]' ); insert into stack_templates ( id, organization_id, name, description, version, cloud_service, platform, template, kube_version, kube_type, created_at, updated_at, services ) -values ( 'fe1d97e0-7428-4be6-9c69-310a88b4ff46', 'master', 'AWS Standard (arm)', 'included LMA', 'v2', 'AWS', 'arm', 'aws-arm-reference', 'v1.24', 'EKS', now(), now(), '[{"name": "Logging,Monitoring,Alerting", "type": "LMA", "applications": [{"name": "prometheus-stack", "version": "v.44.3.1", "description": "통계데이터 제공을 위한 backend 플랫폼"}, {"name": "elastic-system", "version": "v1.8.0", "description": "로그 데이터 적재를 위한 Storage"}, {"name": "alertmanager", "version": "v0.23.0", "description": "Alert 관리를 위한 backend 서비스"}, {"name": "grafana", "version": "v6.50.7", "description": "모니터링 통합 포탈"}]}]' ); +values ( 'fe1d97e0-7428-4be6-9c69-310a88b4ff46', 'master', 'AWS Standard (arm)', 'included LMA', 'v2', 'AWS', 'arm', 'aws-arm-reference', 'v1.25', 'EKS', now(), now(), '[{"name": "Logging,Monitoring,Alerting", "type": "LMA", "applications": [{"name": "prometheus-stack", "version": "v.44.3.1", "description": "통계데이터 제공을 위한 backend 플랫폼"}, {"name": "elastic-system", "version": "v1.8.0", "description": "로그 데이터 적재를 위한 Storage"}, {"name": "alertmanager", "version": "v0.23.0", "description": "Alert 관리를 위한 backend 서비스"}, {"name": "grafana", "version": "v6.50.7", "description": "모니터링 통합 포탈"}]}]' ); insert into stack_templates ( id, organization_id, name, description, version, cloud_service, platform, template, kube_version, kube_type, created_at, updated_at, services ) -values ( '3696cb38-4da0-4235-97eb-b6eb15962bd1', 'master', 'AWS Standard (arm)', 'included LMA, SERVICE_MESH', 'v2', 'AWS', 'arm', 'aws-arm-msa-reference', 'v1.24', 'EKS', now(), now(), '[{"name": "Logging,Monitoring,Alerting", "type": "LMA", "applications": [{"name": "prometheus-stack", "version": "v.44.3.1", "description": "통계데이터 제공을 위한 backend 플랫폼"}, {"name": "elastic-system", "version": "v1.8.0", "description": "로그 데이터 적재를 위한 Storage"}, {"name": "alertmanager", "version": "v0.23.0", "description": "Alert 관리를 위한 backend 서비스"}, {"name": "grafana", "version": "v6.50.7", "description": "모니터링 통합 포탈"}]}, {"name": "MSA", "type": "SERVICE_MESH", "applications": [{"name": "istio", "version": "v1.13.1", "description": "MSA 플랫폼"}, {"name": "jagger", "version": "v2.27.1", "description": "분산 서비스간 트랜잭션 추적을 위한 로깅 플랫폼"}, {"name": "kiali", "version": "v1.45.1", "description": "MSA 통합 모니터링포탈"}]}]' ); +values ( '3696cb38-4da0-4235-97eb-b6eb15962bd1', 'master', 'AWS Standard (arm)', 'included LMA, SERVICE_MESH', 'v2', 'AWS', 'arm', 'aws-arm-msa-reference', 'v1.25', 'EKS', now(), now(), '[{"name": "Logging,Monitoring,Alerting", "type": "LMA", "applications": [{"name": "prometheus-stack", "version": "v.44.3.1", "description": "통계데이터 제공을 위한 backend 플랫폼"}, {"name": "elastic-system", "version": "v1.8.0", "description": "로그 데이터 적재를 위한 Storage"}, {"name": "alertmanager", "version": "v0.23.0", "description": "Alert 관리를 위한 backend 서비스"}, {"name": "grafana", "version": "v6.50.7", "description": "모니터링 통합 포탈"}]}, {"name": "MSA", "type": "SERVICE_MESH", "applications": [{"name": "istio", "version": "v1.13.1", "description": "MSA 플랫폼"}, {"name": "jagger", "version": "v2.27.1", "description": "분산 서비스간 트랜잭션 추적을 위한 로깅 플랫폼"}, {"name": "kiali", "version": "v1.45.1", "description": "MSA 통합 모니터링포탈"}]}]' ); insert into stack_templates ( id, organization_id, name, description, version, cloud_service, platform, template, kube_version, kube_type, created_at, updated_at, services ) -values ( 'c8a4658d-d5a6-4191-8a91-e26f6aee007f', 'master', 'EKS Standard (x86)', 'included LMA', 'v1', 'AWS', 'x86', 'eks-reference', 'v1.24', 'AWS', now(), now(), '[{"name":"Logging,Monitoring,Alerting","type":"LMA","applications":[{"name":"thanos","version":"0.17.2","description":"다중클러스터의 모니터링 데이터 통합 질의처리"},{"name":"prometheus-stack","version":"v0.62.0","description":"모니터링 데이터 수집/저장 및 질의처리"},{"name":"alertmanager","version":"v0.23.0","description":"알람 처리를 위한 노티피케이션 서비스"},{"name":"loki","version":"2.6.1","description":"로그데이터 저장 및 질의처리"},{"name":"grafana","version":"9.3.6","description":"모니터링/로그 통합대시보드"}]}]' ); +values ( 'c8a4658d-d5a6-4191-8a91-e26f6aee007f', 'master', 'EKS Standard (x86)', 'included LMA', 'v1', 'AWS', 'x86', 'eks-reference', 'v1.25', 'AWS', now(), now(), '[{"name":"Logging,Monitoring,Alerting","type":"LMA","applications":[{"name":"thanos","version":"0.17.2","description":"다중클러스터의 모니터링 데이터 통합 질의처리"},{"name":"prometheus-stack","version":"v0.62.0","description":"모니터링 데이터 수집/저장 및 질의처리"},{"name":"alertmanager","version":"v0.23.0","description":"알람 처리를 위한 노티피케이션 서비스"},{"name":"loki","version":"2.6.1","description":"로그데이터 저장 및 질의처리"},{"name":"grafana","version":"9.3.6","description":"모니터링/로그 통합대시보드"}]}]' ); insert into stack_templates ( id, organization_id, name, description, version, cloud_service, platform, template, kube_version, kube_type, created_at, updated_at, services ) -values ( '39f18a09-5b94-4772-bdba-e4c32ee002f7', 'master', 'EKS MSA Standard (x86)', 'included LMA, SERVICE MESH', 'v1', 'AWS', 'x86', 'eks-msa-reference', 'v1.24', 'AWS', now(), now(), '[{"name":"Logging,Monitoring,Alerting","type":"LMA","applications":[{"name":"thanos","version":"0.17.2","description":"다중클러스터의 모니터링 데이터 통합 질의처리"},{"name":"prometheus-stack","version":"v0.62.0","description":"모니터링 데이터 수집/저장 및 질의처리"},{"name":"alertmanager","version":"v0.23.0","description":"알람 처리를 위한 노티피케이션 서비스"},{"name":"loki","version":"2.6.1","description":"로그데이터 저장 및 질의처리"},{"name":"grafana","version":"9.3.6","description":"모니터링/로그 통합대시보드"}]},{"name":"MSA","type":"SERVICE_MESH","applications":[{"name":"istio","version":"v1.17.2","description":"MSA 플랫폼"},{"name":"jagger","version":"1.35.0","description":"분산 서비스간 트랜잭션 추적을 위한 플랫폼"},{"name":"kiali","version":"v1.63.0","description":"MSA 구조 및 성능을 볼 수 있는 Dashboard"},{"name":"k8ssandra","version":"1.6.0","description":"분산 서비스간 호출 로그를 저장하는 스토리지"}]}]' ); +values ( '39f18a09-5b94-4772-bdba-e4c32ee002f7', 'master', 'EKS MSA Standard (x86)', 'included LMA, SERVICE MESH', 'v1', 'AWS', 'x86', 'eks-msa-reference', 'v1.25', 'AWS', now(), now(), '[{"name":"Logging,Monitoring,Alerting","type":"LMA","applications":[{"name":"thanos","version":"0.17.2","description":"다중클러스터의 모니터링 데이터 통합 질의처리"},{"name":"prometheus-stack","version":"v0.62.0","description":"모니터링 데이터 수집/저장 및 질의처리"},{"name":"alertmanager","version":"v0.23.0","description":"알람 처리를 위한 노티피케이션 서비스"},{"name":"loki","version":"2.6.1","description":"로그데이터 저장 및 질의처리"},{"name":"grafana","version":"9.3.6","description":"모니터링/로그 통합대시보드"}]},{"name":"MSA","type":"SERVICE_MESH","applications":[{"name":"istio","version":"v1.17.2","description":"MSA 플랫폼"},{"name":"jagger","version":"1.35.0","description":"분산 서비스간 트랜잭션 추적을 위한 플랫폼"},{"name":"kiali","version":"v1.63.0","description":"MSA 구조 및 성능을 볼 수 있는 Dashboard"},{"name":"k8ssandra","version":"1.6.0","description":"분산 서비스간 호출 로그를 저장하는 스토리지"}]}]' ); From 4b316df2693e7d33b0a2b6a3369f1f5fb196acfd Mon Sep 17 00:00:00 2001 From: Taekyu Date: Tue, 8 Aug 2023 09:57:54 +0900 Subject: [PATCH 11/23] trivial. add github action for prd --- .github/workflows/build-and-push.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build-and-push.yml b/.github/workflows/build-and-push.yml index f943a8d4..84cf0540 100644 --- a/.github/workflows/build-and-push.yml +++ b/.github/workflows/build-and-push.yml @@ -51,6 +51,7 @@ jobs: ( cd cicd-manifests/${SERVICE}/overlay/ft && kustomize edit set image docker.io/sktcloud/${SERVICE}:${TAG} && git add kustomization.yaml ) elif [[ ${{github.ref}} == *"main"* ]]; then ( cd cicd-manifests/${SERVICE}/overlay/cicd && kustomize edit set image docker.io/sktcloud/${SERVICE}:${TAG} && git add kustomization.yaml ) + ( cd cicd-manifests/${SERVICE}/overlay/prd && kustomize edit set image docker.io/sktcloud/${SERVICE}:${TAG} && git add kustomization.yaml ) fi cd cicd-manifests From fdafe0ab0653146063dff0c63776b1b5b3ba6860 Mon Sep 17 00:00:00 2001 From: Taekyu Date: Wed, 9 Aug 2023 23:29:24 +0900 Subject: [PATCH 12/23] feature. check resource quota when creating stack. --- cmd/server/main.go | 1 + go.mod | 36 ++++-- go.sum | 70 +++++++++++ internal/kubernetes/kubernetes.go | 42 +++++++ internal/usecase/dashboard.go | 5 + internal/usecase/stack.go | 192 +++++++++++++++++++++++++++++- pkg/domain/stack.go | 4 +- pkg/httpErrors/errorCode.go | 2 + pkg/httpErrors/httpErrors.go | 5 + scripts/init_postgres.sql | 3 - 10 files changed, 342 insertions(+), 18 deletions(-) diff --git a/cmd/server/main.go b/cmd/server/main.go index c8296977..854f4b34 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -35,6 +35,7 @@ func init() { flag.String("git-base-url", "https://github.com", "git base url") flag.String("git-account", "decapod10", "git account of admin cluster") flag.String("revision", "main", "revision") + flag.String("aws-secret", "awsconfig-secret", "aws secret") flag.Int("migrate-db", 1, "If the values is true, enable db migration. recommend only development") // console diff --git a/go.mod b/go.mod index 50203c37..f09c8032 100644 --- a/go.mod +++ b/go.mod @@ -4,8 +4,8 @@ go 1.18 require ( github.com/Nerzal/gocloak/v13 v13.1.0 - github.com/aws/aws-sdk-go-v2 v1.17.8 - github.com/aws/aws-sdk-go-v2/config v1.18.21 + github.com/aws/aws-sdk-go-v2 v1.20.1 + github.com/aws/aws-sdk-go-v2/config v1.18.32 github.com/aws/aws-sdk-go-v2/service/ses v1.15.7 github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/go-playground/locales v0.14.1 @@ -36,16 +36,28 @@ require ( require ( github.com/KyleBanks/depth v1.2.1 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.13.20 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.2 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.32 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.26 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.3.33 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.26 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.12.8 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.8 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.18.9 // indirect - github.com/aws/smithy-go v1.13.5 // indirect + github.com/aws/aws-sdk-go v1.44.317 // indirect + github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.12 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.13.31 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.7 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.38 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.32 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.3.38 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.1.1 // indirect + github.com/aws/aws-sdk-go-v2/service/ec2 v1.110.1 // indirect + github.com/aws/aws-sdk-go-v2/service/eks v1.29.2 // indirect + github.com/aws/aws-sdk-go-v2/service/elasticloadbalancing v1.16.2 // indirect + github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.20.2 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.13 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.33 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.32 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.15.1 // indirect + github.com/aws/aws-sdk-go-v2/service/s3 v1.38.2 // indirect + github.com/aws/aws-sdk-go-v2/service/servicequotas v1.15.1 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.13.1 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.15.1 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.21.1 // indirect + github.com/aws/smithy-go v1.14.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/emicklei/go-restful v2.9.5+incompatible // indirect github.com/felixge/httpsnoop v1.0.1 // indirect diff --git a/go.sum b/go.sum index 3098d740..316d72c9 100644 --- a/go.sum +++ b/go.sum @@ -59,32 +59,90 @@ github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbt github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= +github.com/aws/aws-sdk-go v1.44.317 h1:+8XWrLmGMwPPXSRSLPzhgcGnzJ2mYkgkrcB9C/GnSOU= +github.com/aws/aws-sdk-go v1.44.317/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/aws/aws-sdk-go-v2 v1.17.8 h1:GMupCNNI7FARX27L7GjCJM8NgivWbRgpjNI/hOQjFS8= github.com/aws/aws-sdk-go-v2 v1.17.8/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw= +github.com/aws/aws-sdk-go-v2 v1.20.0 h1:INUDpYLt4oiPOJl0XwZDK2OVAVf0Rzo+MGVTv9f+gy8= +github.com/aws/aws-sdk-go-v2 v1.20.0/go.mod h1:uWOr0m0jDsiWw8nnXiqZ+YG6LdvAlGYDLLf2NmHZoy4= +github.com/aws/aws-sdk-go-v2 v1.20.1 h1:rZBf5DWr7YGrnlTK4kgDQGn1ltqOg5orCYb/UhOFZkg= +github.com/aws/aws-sdk-go-v2 v1.20.1/go.mod h1:NU06lETsFm8fUC6ZjhgDpVBcGZTFQ6XM+LZWZxMI4ac= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.12 h1:lN6L3LrYHeZ6xCxaIYtoWCx4GMLk4nRknsh29OMSqHY= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.12/go.mod h1:TDCkEAkMTXxTs0oLBGBKpBZbk3NLh8EvAfF0Q3x8/0c= github.com/aws/aws-sdk-go-v2/config v1.18.21 h1:ENTXWKwE8b9YXgQCsruGLhvA9bhg+RqAsL9XEMEsa2c= github.com/aws/aws-sdk-go-v2/config v1.18.21/go.mod h1:+jPQiVPz1diRnjj6VGqWcLK6EzNmQ42l7J3OqGTLsSY= +github.com/aws/aws-sdk-go-v2/config v1.18.32 h1:tqEOvkbTxwEV7hToRcJ1xZRjcATqwDVsWbAscgRKyNI= +github.com/aws/aws-sdk-go-v2/config v1.18.32/go.mod h1:U3ZF0fQRRA4gnbn9GGvOWLoT2EzzZfAWeKwnVrm1rDc= github.com/aws/aws-sdk-go-v2/credentials v1.13.20 h1:oZCEFcrMppP/CNiS8myzv9JgOzq2s0d3v3MXYil/mxQ= github.com/aws/aws-sdk-go-v2/credentials v1.13.20/go.mod h1:xtZnXErtbZ8YGXC3+8WfajpMBn5Ga/3ojZdxHq6iI8o= +github.com/aws/aws-sdk-go-v2/credentials v1.13.31 h1:vJyON3lG7R8VOErpJJBclBADiWTwzcwdkQpTKx8D2sk= +github.com/aws/aws-sdk-go-v2/credentials v1.13.31/go.mod h1:T4sESjBtY2lNxLgkIASmeP57b5j7hTQqCbqG0tWnxC4= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.2 h1:jOzQAesnBFDmz93feqKnsTHsXrlwWORNZMFHMV+WLFU= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.2/go.mod h1:cDh1p6XkSGSwSRIArWRc6+UqAQ7x4alQ0QfpVR6f+co= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.7 h1:X3H6+SU21x+76LRglk21dFRgMTJMa5QcpW+SqUf5BBg= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.7/go.mod h1:3we0V09SwcJBzNlnyovrR2wWJhWmVdqAsmVs4uronv8= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.32 h1:dpbVNUjczQ8Ae3QKHbpHBpfvaVkRdesxpTOe9pTouhU= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.32/go.mod h1:RudqOgadTWdcS3t/erPQo24pcVEoYyqj/kKW5Vya21I= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.37 h1:zr/gxAZkMcvP71ZhQOcvdm8ReLjFgIXnIn0fw5AM7mo= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.37/go.mod h1:Pdn4j43v49Kk6+82spO3Tu5gSeQXRsxo56ePPQAvFiA= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.38 h1:c8ed/T9T2K5I+h/JzmF5tpI46+OODQ74dzmdo+QnaMg= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.38/go.mod h1:qggunOChCMu9ZF/UkAfhTz25+U2rLVb3ya0Ua6TTfCA= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.26 h1:QH2kOS3Ht7x+u0gHCh06CXL/h6G8LQJFpZfFBYBNboo= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.26/go.mod h1:vq86l7956VgFr0/FWQ2BWnK07QC3WYsepKzy33qqY5U= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.31 h1:0HCMIkAkVY9KMgueD8tf4bRTUanzEYvhw7KkPXIMpO0= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.31/go.mod h1:fTJDMe8LOFYtqiFFFeHA+SVMAwqLhoq0kcInYoLa9Js= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.32 h1:hNeAAymUY5gu11WrrmFb3CVIp9Dar9hbo44yzzcQpzA= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.32/go.mod h1:0ZXSqrty4FtQ7p8TEuRde/SZm9X05KT18LAUlR40Ln0= github.com/aws/aws-sdk-go-v2/internal/ini v1.3.33 h1:HbH1VjUgrCdLJ+4lnnuLI4iVNRvBbBELGaJ5f69ClA8= github.com/aws/aws-sdk-go-v2/internal/ini v1.3.33/go.mod h1:zG2FcwjQarWaqXSCGpgcr3RSjZ6dHGguZSppUL0XR7Q= +github.com/aws/aws-sdk-go-v2/internal/ini v1.3.38 h1:+i1DOFrW3YZ3apE45tCal9+aDKK6kNEbW6Ib7e1nFxE= +github.com/aws/aws-sdk-go-v2/internal/ini v1.3.38/go.mod h1:1/jLp0OgOaWIetycOmycW+vYTYgTZFPttJQRgsI1PoU= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.1.1 h1:vUh7dBFNS3oFCtVv6CiYKh5hP9ls8+kIpKLeFruIBLk= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.1.1/go.mod h1:sFMeinkhj/SZKQM8BxtvNtSPjJEo0Xrz+w3g2e4FSKI= +github.com/aws/aws-sdk-go-v2/service/ec2 v1.110.1 h1:OaDeV+sdve2NV+kUheZX5bToHFmfIkflgOlZTKij0Bo= +github.com/aws/aws-sdk-go-v2/service/ec2 v1.110.1/go.mod h1:Ie0Kp61cLk223argiS+t8vO29SpbFIphzlPflIvYcv0= +github.com/aws/aws-sdk-go-v2/service/eks v1.29.2 h1:ZwK94/wSfjVrsp9UucUZOb3QCn6zL9Wru5KauaYQCBg= +github.com/aws/aws-sdk-go-v2/service/eks v1.29.2/go.mod h1:B7NksWEFv8tWu1ob60c1bU1oa1iCIhoQ7AtnT3dE3+8= +github.com/aws/aws-sdk-go-v2/service/elasticloadbalancing v1.16.2 h1:AnXbttLaoY2bgyTotlmKJxozPUQdDQ3WGIQ7MwnznPE= +github.com/aws/aws-sdk-go-v2/service/elasticloadbalancing v1.16.2/go.mod h1:DYqqNwjoFTL0URDn5odwM4Pq455DHNlBmQXSAI2DbWs= +github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.20.2 h1:8TXQKxY0UjNAt/9nkDtfGechuri15a+yw9QtsEuOLtE= +github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.20.2/go.mod h1:AZv/T0/2rhNBLiY2k109TT6HJ7Z0P8Z+SYvs0jqVkXE= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.13 h1:iV/W5OMBys+66OeXJi/7xIRrKZNsu0ylsLGu+6nbmQE= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.13/go.mod h1:ReJb6xYmtGyu9KoFtRreWegbN9dZqvZIIv4vWnhcsyI= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.33 h1:QviNkc+vGSuEHx8P+pVNKOdWLXBPIwMFv7p0fphgE4U= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.33/go.mod h1:fABTUmOrAgAalG2i9WJpjBvlnk7UK8YmnYaxN+Q2CwE= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.26 h1:uUt4XctZLhl9wBE1L8lobU3bVN8SNUP7T+olb0bWBO4= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.26/go.mod h1:Bd4C/4PkVGubtNe5iMXu5BNnaBi/9t/UsFspPt4ram8= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.31 h1:auGDJ0aLZahF5SPvkJ6WcUuX7iQ7kyl2MamV7Tm8QBk= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.31/go.mod h1:3+lloe3sZuBQw1aBc5MyndvodzQlyqCZ7x1QPDHaWP4= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.32 h1:dGAseBFEYxth10V23b5e2mAS+tX7oVbfYHD6dnDdAsg= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.32/go.mod h1:4jwAWKEkCR0anWk5+1RbfSg1R5Gzld7NLiuaq5bTR/Y= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.15.1 h1:PT6PBCycRwhpEW5hJnRiceCeoWJ+r3bdgXtV+VKG7Pk= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.15.1/go.mod h1:TqoxCLwT2nrxrBGA+z7t6OWM7LBkgRckK3gOjYE+7JA= +github.com/aws/aws-sdk-go-v2/service/s3 v1.38.2 h1:v346f1h8sUBKXnEbrv43L37MTBlFHyKXQPIZHNAaghA= +github.com/aws/aws-sdk-go-v2/service/s3 v1.38.2/go.mod h1:cwCATiyNrXK9P2FsWdZ89g9mpsYv2rhk0UA/KByl5fY= +github.com/aws/aws-sdk-go-v2/service/servicequotas v1.15.1 h1:ZL1ul+QW+JGT7my64SG8cPTudyLXRZXifPgJrpIA8qI= +github.com/aws/aws-sdk-go-v2/service/servicequotas v1.15.1/go.mod h1:2rmOo0RfixF8lcXxkquMIb1SY9oPY0iY/Mau8w8nFNs= github.com/aws/aws-sdk-go-v2/service/ses v1.15.7 h1:eS3hpWtxVYnrysF+NEcjZo5zVvmgNTk22zRwJbtmCZY= github.com/aws/aws-sdk-go-v2/service/ses v1.15.7/go.mod h1:sDSPw06IV4uB+RByvHkqDZKfP7SgIataOehYkchSups= github.com/aws/aws-sdk-go-v2/service/sso v1.12.8 h1:5cb3D6xb006bPTqEfCNaEA6PPEfBXxxy4NNeX/44kGk= github.com/aws/aws-sdk-go-v2/service/sso v1.12.8/go.mod h1:GNIveDnP+aE3jujyUSH5aZ/rktsTM5EvtKnCqBZawdw= +github.com/aws/aws-sdk-go-v2/service/sso v1.13.1 h1:DSNpSbfEgFXRV+IfEcKE5kTbqxm+MeF5WgyeRlsLnHY= +github.com/aws/aws-sdk-go-v2/service/sso v1.13.1/go.mod h1:TC9BubuFMVScIU+TLKamO6VZiYTkYoEHqlSQwAe2omw= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.8 h1:NZaj0ngZMzsubWZbrEFSB4rgSQRbFq38Sd6KBxHuOIU= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.8/go.mod h1:44qFP1g7pfd+U+sQHLPalAPKnyfTZjJsYR4xIwsJy5o= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.15.1 h1:hd0SKLMdOL/Sl6Z0np1PX9LeH2gqNtBe0MhTedA8MGI= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.15.1/go.mod h1:XO/VcyoQ8nKyKfFW/3DMsRQXsfh/052tHTWmg3xBXRg= github.com/aws/aws-sdk-go-v2/service/sts v1.18.9 h1:Qf1aWwnsNkyAoqDqmdM3nHwN78XQjec27LjM6b9vyfI= github.com/aws/aws-sdk-go-v2/service/sts v1.18.9/go.mod h1:yyW88BEPXA2fGFyI2KCcZC3dNpiT0CZAHaF+i656/tQ= +github.com/aws/aws-sdk-go-v2/service/sts v1.21.1 h1:pAOJj+80tC8sPVgSDHzMYD6KLWsaLQ1kZw31PTeORbs= +github.com/aws/aws-sdk-go-v2/service/sts v1.21.1/go.mod h1:G8SbvL0rFk4WOJroU8tKBczhsbhj2p/YY7qeJezJ3CI= github.com/aws/smithy-go v1.13.5 h1:hgz0X/DX0dGqTYpGALqXJoRKRj5oQ7150i5FdTePzO8= github.com/aws/smithy-go v1.13.5/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= +github.com/aws/smithy-go v1.14.0 h1:+X90sB94fizKjDmwb4vyl2cTTPXTE5E2G/1mjByb0io= +github.com/aws/smithy-go v1.14.0/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= +github.com/aws/smithy-go v1.14.1 h1:EFKMUmH/iHMqLiwoEDx2rRjRQpI1YCn5jTysoaDujFs= +github.com/aws/smithy-go v1.14.1/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= @@ -461,6 +519,7 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= @@ -492,6 +551,7 @@ golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWP golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= @@ -531,6 +591,7 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -575,6 +636,8 @@ golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -602,6 +665,7 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -658,12 +722,16 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -675,6 +743,7 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -739,6 +808,7 @@ golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/internal/kubernetes/kubernetes.go b/internal/kubernetes/kubernetes.go index ac51c330..d202a55d 100644 --- a/internal/kubernetes/kubernetes.go +++ b/internal/kubernetes/kubernetes.go @@ -2,6 +2,8 @@ package kubernetes import ( "context" + "fmt" + "strings" "github.com/spf13/viper" @@ -50,6 +52,46 @@ func GetClientAdminCluster() (*kubernetes.Clientset, error) { return clientset, nil } +func GetAwsSecret() (awsAccessKeyId string, awsSecretAccessKey string, err error) { + clientset, err := GetClientAdminCluster() + if err != nil { + return "", "", err + } + + secrets, err := clientset.CoreV1().Secrets("argo").Get(context.TODO(), "awsconfig-secret", metav1.GetOptions{}) + if err != nil { + log.Error(err) + return "", "", err + } + + strCredentials := string(secrets.Data["credentials"][:]) + arr := strings.Split(strCredentials, "\n") + if len(arr) < 3 { + return "", "", err + } + + fmt.Sscanf(arr[1], "aws_access_key_id = %s", &awsAccessKeyId) + fmt.Sscanf(arr[2], "aws_secret_access_key = %s", &awsSecretAccessKey) + + return +} + +func GetAwsAccountIdSecret() (awsAccountId string, err error) { + clientset, err := GetClientAdminCluster() + if err != nil { + return "", err + } + + secrets, err := clientset.CoreV1().Secrets("argo").Get(context.TODO(), "tks-aws-user", metav1.GetOptions{}) + if err != nil { + log.Error(err) + return "", err + } + + awsAccountId = string(secrets.Data["account_id"][:]) + return +} + func GetKubeConfig(clusterId string) ([]byte, error) { clientset, err := GetClientAdminCluster() if err != nil { diff --git a/internal/usecase/dashboard.go b/internal/usecase/dashboard.go index 5938f0b5..67a2676a 100644 --- a/internal/usecase/dashboard.go +++ b/internal/usecase/dashboard.go @@ -356,6 +356,11 @@ func (u *DashboardUsecase) getChartFromPrometheus(organizationId string, chartTy } } } + sort.Slice(xAxisData, func(i, j int) bool { + a, _ := strconv.Atoi(xAxisData[i]) + b, _ := strconv.Atoi(xAxisData[j]) + return a < b + }) // cluster 별 y축 계산 for _, val := range result.Data.Result { diff --git a/internal/usecase/stack.go b/internal/usecase/stack.go index f3b69c2b..df4d855c 100644 --- a/internal/usecase/stack.go +++ b/internal/usecase/stack.go @@ -6,6 +6,16 @@ import ( "strings" "time" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go-v2/credentials" + "github.com/aws/aws-sdk-go-v2/credentials/stscreds" + "github.com/aws/aws-sdk-go-v2/service/ec2" + "github.com/aws/aws-sdk-go-v2/service/eks" + "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancing" + "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2" + "github.com/aws/aws-sdk-go-v2/service/servicequotas" + "github.com/aws/aws-sdk-go-v2/service/sts" "github.com/openinfradev/tks-api/internal/helper" "github.com/openinfradev/tks-api/internal/kubernetes" "github.com/openinfradev/tks-api/internal/middleware/auth/request" @@ -69,7 +79,7 @@ func (u *StackUsecase) Create(ctx context.Context, dto domain.Stack) (stackId do return "", httpErrors.NewInternalServerError(errors.Wrap(err, "Invalid stackTemplateId"), "S_INVALID_STACK_TEMPLATE", "") } - _, err = u.cloudAccountRepo.Get(dto.CloudAccountId) + cloudAccount, err := u.cloudAccountRepo.Get(dto.CloudAccountId) if err != nil { return "", httpErrors.NewInternalServerError(errors.Wrap(err, "Invalid cloudAccountId"), "S_INVALID_CLOUD_ACCOUNT", "") } @@ -99,6 +109,11 @@ func (u *StackUsecase) Create(ctx context.Context, dto domain.Stack) (stackId do log.InfoWithContext(ctx, err) } + // Check service quota + if err = u.checkAwsResourceQuota(ctx, cloudAccount); err != nil { + return "", err + } + workflowId, err := u.argo.SumbitWorkflowFromWftpl(workflow, argowf.SubmitOptions{ Parameters: []string{ fmt.Sprintf("tks_api_url=%s", viper.GetString("external-address")), @@ -145,6 +160,168 @@ func (u *StackUsecase) Create(ctx context.Context, dto domain.Stack) (stackId do return dto.ID, nil } +func (u *StackUsecase) checkAwsResourceQuota(ctx context.Context, cloudAccount domain.CloudAccount) (err error) { + awsAccessKeyId, awsSecretAccessKey, _ := kubernetes.GetAwsSecret() + if err != nil || awsAccessKeyId == "" || awsSecretAccessKey == "" { + log.ErrorWithContext(ctx, err) + return httpErrors.NewInternalServerError(fmt.Errorf("Invalid aws secret."), "", "") + } + + cfg, err := config.LoadDefaultConfig(ctx, + config.WithCredentialsProvider(credentials.StaticCredentialsProvider{ + Value: aws.Credentials{ + AccessKeyID: awsAccessKeyId, SecretAccessKey: awsSecretAccessKey, + }, + })) + if err != nil { + log.ErrorWithContext(ctx, err) + } + + stsSvc := sts.NewFromConfig(cfg) + + if !strings.Contains(cloudAccount.Name, domain.CLOUD_ACCOUNT_INCLUSTER) { + log.InfoWithContext(ctx, "Use assume role. awsAccountId : ", cloudAccount.AwsAccountId) + creds := stscreds.NewAssumeRoleProvider(stsSvc, "arn:aws:iam::"+cloudAccount.AwsAccountId+":role/controllers.cluster-api-provider-aws.sigs.k8s.io") + cfg.Credentials = aws.NewCredentialsCache(creds) + } + client := servicequotas.NewFromConfig(cfg) + + quotaMap := map[string]string{ + "L-69A177A2": "elasticloadbalancing", // NLB + "L-E9E9831D": "elasticloadbalancing", // Classic + "L-A4707A72": "vpc", // IGW + "L-1194D53C": "eks", // Cluster + "L-0263D0A3": "ec2", // Elastic IP + } + + // current usage + type CurrentUsage struct { + NLB int + CLB int + IGW int + Cluster int + EIP int + } + + // get current usage + currentUsage := CurrentUsage{} + { + c := elasticloadbalancingv2.NewFromConfig(cfg) + pageSize := int32(100) + res, err := c.DescribeLoadBalancers(ctx, &elasticloadbalancingv2.DescribeLoadBalancersInput{ + PageSize: &pageSize, + }, func(o *elasticloadbalancingv2.Options) { + o.Region = "ap-northeast-2" + }) + if err != nil { + return err + } + + for _, elb := range res.LoadBalancers { + switch elb.Type { + case "network": + currentUsage.NLB += 1 + } + } + } + + { + c := elasticloadbalancing.NewFromConfig(cfg) + pageSize := int32(100) + res, err := c.DescribeLoadBalancers(ctx, &elasticloadbalancing.DescribeLoadBalancersInput{ + PageSize: &pageSize, + }, func(o *elasticloadbalancing.Options) { + o.Region = "ap-northeast-2" + }) + if err != nil { + return err + } + currentUsage.CLB = len(res.LoadBalancerDescriptions) + } + + { + c := ec2.NewFromConfig(cfg) + res, err := c.DescribeInternetGateways(ctx, &ec2.DescribeInternetGatewaysInput{}, func(o *ec2.Options) { + o.Region = "ap-northeast-2" + }) + if err != nil { + return err + } + currentUsage.IGW = len(res.InternetGateways) + } + + { + c := eks.NewFromConfig(cfg) + res, err := c.ListClusters(ctx, &eks.ListClustersInput{}, func(o *eks.Options) { + o.Region = "ap-northeast-2" + }) + if err != nil { + return err + } + currentUsage.Cluster = len(res.Clusters) + } + + { + c := ec2.NewFromConfig(cfg) + res, err := c.DescribeAddresses(ctx, &ec2.DescribeAddressesInput{}, func(o *ec2.Options) { + o.Region = "ap-northeast-2" + }) + if err != nil { + log.ErrorWithContext(ctx, err) + return err + } + currentUsage.EIP = len(res.Addresses) + } + + for key, val := range quotaMap { + res, err := getServiceQuota(client, key, val) + if err != nil { + return err + } + log.DebugfWithContext(ctx, "%s %s %v", *res.Quota.QuotaName, *res.Quota.QuotaCode, *res.Quota.Value) + + quotaValue := int(*res.Quota.Value) + + // stack 1개 생성하는데 필요한 quota + // Classic 1 + // Network 5 + // IGW 1 + // EIP 3 + // Cluster 1 + switch key { + case "L-69A177A2": // NLB + log.InfofWithContext(ctx, "NLB : usage %d, quota %d", currentUsage.NLB, quotaValue) + if quotaValue < currentUsage.NLB+5 { + return httpErrors.NewInternalServerError(fmt.Errorf("Not enough quota (NLB). current[%d], quota[%d]", currentUsage.NLB, quotaValue), "S_NOT_ENOUGH_QUOTA", "") + } + case "L-E9E9831D": // Classic + log.InfofWithContext(ctx, "CLB : usage %d, quota %d", currentUsage.CLB, quotaValue) + if quotaValue < currentUsage.CLB+1 { + return httpErrors.NewInternalServerError(fmt.Errorf("Not enough quota (Classic ELB). current[%d], quota[%d]", currentUsage.CLB, quotaValue), "S_NOT_ENOUGH_QUOTA", "") + } + case "L-A4707A72": // IGW + log.InfofWithContext(ctx, "IGW : usage %d, quota %d", currentUsage.IGW, quotaValue) + if quotaValue < currentUsage.IGW+1 { + return httpErrors.NewInternalServerError(fmt.Errorf("Not enough quota (Internet Gateway). current[%d], quota[%d]", currentUsage.IGW, quotaValue), "S_NOT_ENOUGH_QUOTA", "") + } + case "L-1194D53C": // Cluster + log.InfofWithContext(ctx, "Cluster : usage %d, quota %d", currentUsage.Cluster, quotaValue) + if quotaValue < currentUsage.Cluster+1 { + return httpErrors.NewInternalServerError(fmt.Errorf("Not enough quota (EKS cluster quota). current[%d], quota[%d]", currentUsage.Cluster, quotaValue), "S_NOT_ENOUGH_QUOTA", "") + } + case "L-0263D0A3": // Elastic IP + log.InfofWithContext(ctx, "Elastic IP : usage %d, quota %d", currentUsage.EIP, quotaValue) + if quotaValue < currentUsage.EIP+3 { + return httpErrors.NewInternalServerError(fmt.Errorf("Not enough quota (Elastic IP). current[%d], quota[%d]", currentUsage.EIP, quotaValue), "S_NOT_ENOUGH_QUOTA", "") + } + } + + } + + //return fmt.Errorf("Always return err") + return nil +} + func (u *StackUsecase) Get(ctx context.Context, stackId domain.StackId) (out domain.Stack, err error) { cluster, err := u.clusterRepo.Get(domain.ClusterId(stackId)) if err != nil { @@ -590,3 +767,16 @@ func parseStatusDescription(statusDesc string) (step int) { } return } + +func getServiceQuota(client *servicequotas.Client, quotaCode string, serviceCode string) (res *servicequotas.GetServiceQuotaOutput, err error) { + res, err = client.GetServiceQuota(context.TODO(), &servicequotas.GetServiceQuotaInput{ + QuotaCode: "aCode, + ServiceCode: &serviceCode, + }, func(o *servicequotas.Options) { + o.Region = "ap-northeast-2" + }) + if err != nil { + return nil, err + } + return +} diff --git a/pkg/domain/stack.go b/pkg/domain/stack.go index 8f65f12b..f0400e9d 100644 --- a/pkg/domain/stack.go +++ b/pkg/domain/stack.go @@ -61,9 +61,9 @@ func (m StackStatus) FromString(s string) StackStatus { return StackStatus_PENDING } -const MAX_STEP_CLUSTER_CREATE = 13 +const MAX_STEP_CLUSTER_CREATE = 16 const MAX_STEP_CLUSTER_REMOVE = 11 -const MAX_STEP_LMA_CREATE_PRIMARY = 39 +const MAX_STEP_LMA_CREATE_PRIMARY = 42 const MAX_STEP_LMA_CREATE_MEMBER = 27 const MAX_STEP_LMA_REMOVE = 11 const MAX_STEP_SM_CREATE = 22 diff --git a/pkg/httpErrors/errorCode.go b/pkg/httpErrors/errorCode.go index 61785284..17f62395 100644 --- a/pkg/httpErrors/errorCode.go +++ b/pkg/httpErrors/errorCode.go @@ -4,6 +4,7 @@ type ErrorCode string var errorMap = map[ErrorCode]string{ // Common + "C_INTERNAL_ERROR": "예상하지 못한 오류가 발생했습니다. 문제가 계속되면 관리자에게 문의해주세요.", "C_INVALID_ACCOUNT_ID": "유효하지 않은 어카운트 아이디입니다. 어카운트 아이디를 확인하세요.", "C_INVALID_STACK_ID": "유효하지 않은 스택 아이디입니다. 스택 아이디를 확인하세요.", "C_INVALID_CLUSTER_ID": "유효하지 않은 클러스터 아이디입니다. 클러스터 아이디를 확인하세요.", @@ -53,6 +54,7 @@ var errorMap = map[ErrorCode]string{ "S_REMAIN_CLUSTER_FOR_DELETION": "프라이머리 클러스터를 지우기 위해서는 조직내의 모든 클러스터를 삭제해야 합니다.", "S_FAILED_GET_CLUSTERS": "클러스터를 가져오는데 실패했습니다.", "S_FAILED_DELETE_EXISTED_ASA": "지우고자 하는 스택에 남아 있는 앱서빙앱이 있습니다.", + "S_NOT_ENOUGH_QUOTA": "AWS 의 resource quota 가 부족합니다. 관리자에게 문의하세요.", // Alert "AL_NOT_FOUND_ALERT": "지정한 앨럿이 존재하지 않습니다.", diff --git a/pkg/httpErrors/httpErrors.go b/pkg/httpErrors/httpErrors.go index 60f76dfe..6e5b4464 100644 --- a/pkg/httpErrors/httpErrors.go +++ b/pkg/httpErrors/httpErrors.go @@ -63,11 +63,16 @@ func (e RestError) Text() string { } func NewRestError(status int, err error, code ErrorCode, text string) IRestError { + if code == "" && text == "" { + code = ErrorCode("C_INTERNAL_ERROR") + } + t := code.GetText() if text != "" { t = text } log.Info(t) + return RestError{ ErrStatus: status, ErrCode: string(code), diff --git a/scripts/init_postgres.sql b/scripts/init_postgres.sql index 6434a1d7..ba6c7ce4 100644 --- a/scripts/init_postgres.sql +++ b/scripts/init_postgres.sql @@ -15,9 +15,6 @@ insert into policies ( role_id, name, description, c, create_priviledge, u, upda insert into organizations ( id, name, description, created_at, updated_at ) values ( 'master', 'master', 'tks', now(), now() ); insert into users ( id, account_id, name, password, organization_id, role_id, created_at, updated_at ) values ( 'bf67de40-ce15-4dc0-b6c2-17f053ca504f', 'admin', 'admin', '$2a$10$Akf03nbLHk93sTtozm35XuINXkJeNX7A1T9o/Pxpg9R2B2PToBPOO', 'master', 'b2b689f0-ceeb-46c2-b280-0bc06896acd1', now(), now() ); -insert into cloud_accounts ( id, name, description, organization_id, cloud_service, resource, created_at, updated_at ) -values ( 'ce9e0387-01cb-4f37-a22a-fb91b6338434', 'aws', 'aws_description', 'master', 'AWS', 'result', now(), now() ); - insert into stack_templates ( id, organization_id, name, description, version, cloud_service, platform, template, kube_version, kube_type, created_at, updated_at, services ) values ( '49901092-be76-4d4f-94e9-b84525f560b5', 'master', 'AWS Standard (x86)', 'included LMA', 'v1', 'AWS', 'x86', 'aws-reference', 'v1.25', 'AWS', now(), now(), '[{"name": "Logging,Monitoring,Alerting", "type": "LMA", "applications": [{"name": "prometheus-stack", "version": "v.44.3.1", "description": "통계데이터 제공을 위한 backend 플랫폼"}, {"name": "elastic-system", "version": "v1.8.0", "description": "로그 데이터 적재를 위한 Storage"}, {"name": "alertmanager", "version": "v0.23.0", "description": "Alert 관리를 위한 backend 서비스"}, {"name": "grafana", "version": "v6.50.7", "description": "모니터링 통합 포탈"}]}]' ); insert into stack_templates ( id, organization_id, name, description, version, cloud_service, platform, template, kube_version, kube_type, created_at, updated_at, services ) From 90c3dbeb1ab0487680725abe5d918367ae2d5007 Mon Sep 17 00:00:00 2001 From: Taekyu Date: Thu, 10 Aug 2023 17:17:07 +0900 Subject: [PATCH 13/23] trivial. version up stacktemplates --- scripts/init_postgres.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/init_postgres.sql b/scripts/init_postgres.sql index ba6c7ce4..cf90c12b 100644 --- a/scripts/init_postgres.sql +++ b/scripts/init_postgres.sql @@ -24,6 +24,6 @@ values ( 'fe1d97e0-7428-4be6-9c69-310a88b4ff46', 'master', 'AWS Standard (arm)', insert into stack_templates ( id, organization_id, name, description, version, cloud_service, platform, template, kube_version, kube_type, created_at, updated_at, services ) values ( '3696cb38-4da0-4235-97eb-b6eb15962bd1', 'master', 'AWS Standard (arm)', 'included LMA, SERVICE_MESH', 'v2', 'AWS', 'arm', 'aws-arm-msa-reference', 'v1.25', 'EKS', now(), now(), '[{"name": "Logging,Monitoring,Alerting", "type": "LMA", "applications": [{"name": "prometheus-stack", "version": "v.44.3.1", "description": "통계데이터 제공을 위한 backend 플랫폼"}, {"name": "elastic-system", "version": "v1.8.0", "description": "로그 데이터 적재를 위한 Storage"}, {"name": "alertmanager", "version": "v0.23.0", "description": "Alert 관리를 위한 backend 서비스"}, {"name": "grafana", "version": "v6.50.7", "description": "모니터링 통합 포탈"}]}, {"name": "MSA", "type": "SERVICE_MESH", "applications": [{"name": "istio", "version": "v1.13.1", "description": "MSA 플랫폼"}, {"name": "jagger", "version": "v2.27.1", "description": "분산 서비스간 트랜잭션 추적을 위한 로깅 플랫폼"}, {"name": "kiali", "version": "v1.45.1", "description": "MSA 통합 모니터링포탈"}]}]' ); insert into stack_templates ( id, organization_id, name, description, version, cloud_service, platform, template, kube_version, kube_type, created_at, updated_at, services ) -values ( 'c8a4658d-d5a6-4191-8a91-e26f6aee007f', 'master', 'EKS Standard (x86)', 'included LMA', 'v1', 'AWS', 'x86', 'eks-reference', 'v1.25', 'AWS', now(), now(), '[{"name":"Logging,Monitoring,Alerting","type":"LMA","applications":[{"name":"thanos","version":"0.17.2","description":"다중클러스터의 모니터링 데이터 통합 질의처리"},{"name":"prometheus-stack","version":"v0.62.0","description":"모니터링 데이터 수집/저장 및 질의처리"},{"name":"alertmanager","version":"v0.23.0","description":"알람 처리를 위한 노티피케이션 서비스"},{"name":"loki","version":"2.6.1","description":"로그데이터 저장 및 질의처리"},{"name":"grafana","version":"9.3.6","description":"모니터링/로그 통합대시보드"}]}]' ); +values ( 'c8a4658d-d5a6-4191-8a91-e26f6aee007f', 'master', 'EKS Standard (x86)', 'included LMA', 'v1', 'AWS', 'x86', 'eks-reference', 'v1.25', 'AWS', now(), now(), '[{"name":"Logging,Monitoring,Alerting","type":"LMA","applications":[{"name":"thanos","version":"0.30.2","description":"다중클러스터의 모니터링 데이터 통합 질의처리"},{"name":"prometheus-stack","version":"v0.66.0","description":"모니터링 데이터 수집/저장 및 질의처리"},{"name":"alertmanager","version":"v0.25.0","description":"알람 처리를 위한 노티피케이션 서비스"},{"name":"loki","version":"2.6.1","description":"로그데이터 저장 및 질의처리"},{"name":"grafana","version":"8.3.3","description":"모니터링/로그 통합대시보드"}]}]' ); insert into stack_templates ( id, organization_id, name, description, version, cloud_service, platform, template, kube_version, kube_type, created_at, updated_at, services ) -values ( '39f18a09-5b94-4772-bdba-e4c32ee002f7', 'master', 'EKS MSA Standard (x86)', 'included LMA, SERVICE MESH', 'v1', 'AWS', 'x86', 'eks-msa-reference', 'v1.25', 'AWS', now(), now(), '[{"name":"Logging,Monitoring,Alerting","type":"LMA","applications":[{"name":"thanos","version":"0.17.2","description":"다중클러스터의 모니터링 데이터 통합 질의처리"},{"name":"prometheus-stack","version":"v0.62.0","description":"모니터링 데이터 수집/저장 및 질의처리"},{"name":"alertmanager","version":"v0.23.0","description":"알람 처리를 위한 노티피케이션 서비스"},{"name":"loki","version":"2.6.1","description":"로그데이터 저장 및 질의처리"},{"name":"grafana","version":"9.3.6","description":"모니터링/로그 통합대시보드"}]},{"name":"MSA","type":"SERVICE_MESH","applications":[{"name":"istio","version":"v1.17.2","description":"MSA 플랫폼"},{"name":"jagger","version":"1.35.0","description":"분산 서비스간 트랜잭션 추적을 위한 플랫폼"},{"name":"kiali","version":"v1.63.0","description":"MSA 구조 및 성능을 볼 수 있는 Dashboard"},{"name":"k8ssandra","version":"1.6.0","description":"분산 서비스간 호출 로그를 저장하는 스토리지"}]}]' ); +values ( '39f18a09-5b94-4772-bdba-e4c32ee002f7', 'master', 'EKS MSA Standard (x86)', 'included LMA, SERVICE MESH', 'v1', 'AWS', 'x86', 'eks-msa-reference', 'v1.25', 'AWS', now(), now(), '[{"name":"Logging,Monitoring,Alerting","type":"LMA","applications":[{"name":"thanos","version":"0.30.2","description":"다중클러스터의 모니터링 데이터 통합 질의처리"},{"name":"prometheus-stack","version":"v0.66.0","description":"모니터링 데이터 수집/저장 및 질의처리"},{"name":"alertmanager","version":"v0.25.0","description":"알람 처리를 위한 노티피케이션 서비스"},{"name":"loki","version":"2.6.1","description":"로그데이터 저장 및 질의처리"},{"name":"grafana","version":"8.3.3","description":"모니터링/로그 통합대시보드"}]},{"name":"MSA","type":"SERVICE_MESH","applications":[{"name":"istio","version":"v1.17.2","description":"MSA 플랫폼"},{"name":"jagger","version":"1.35.0","description":"분산 서비스간 트랜잭션 추적을 위한 플랫폼"},{"name":"kiali","version":"v1.63.0","description":"MSA 구조 및 성능을 볼 수 있는 Dashboard"},{"name":"k8ssandra","version":"1.6.0","description":"분산 서비스간 호출 로그를 저장하는 스토리지"}]}]' ); From 2ba8e0b13685f998a14ff0d28af67eee95e374a7 Mon Sep 17 00:00:00 2001 From: Taekyu Date: Fri, 11 Aug 2023 14:45:02 +0900 Subject: [PATCH 14/23] bugfix. change ' to $$ ( postgres syntax ). --- internal/repository/repository.go | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/internal/repository/repository.go b/internal/repository/repository.go index 33142cd3..0503a53d 100644 --- a/internal/repository/repository.go +++ b/internal/repository/repository.go @@ -2,6 +2,8 @@ package repository import ( "fmt" + "strings" + "gorm.io/gorm" "github.com/openinfradev/tks-api/internal/pagination" @@ -28,13 +30,18 @@ func CombinedGormFilter(table string, filters []pagination.Filter, combinedFilte if len(filter.Values) > 1 { inQuery := fmt.Sprintf("LOWER(%s.%s::text) in (", table, filter.Column) for _, val := range filter.Values { - inQuery = inQuery + fmt.Sprintf("LOWER('%s'),", val) + inQuery = inQuery + fmt.Sprintf("LOWER($$%s$$),", val) } inQuery = inQuery[:len(inQuery)-1] + ")" db = db.Where(inQuery) } else { if len(filter.Values[0]) > 0 { - db = db.Where(fmt.Sprintf("LOWER(%s.%s::text) like LOWER('%%%s%%')", table, filter.Column, filter.Values[0])) + if strings.Contains(filter.Values[0], "%") { + filterVal := strings.Replace(filter.Values[0], "%", "`%", -1) + db = db.Where(fmt.Sprintf("LOWER(%s.%s::text) like LOWER($$%%%s%%$$) escape '`'", table, filter.Column, filterVal)) + } else { + db = db.Where(fmt.Sprintf("LOWER(%s.%s::text) like LOWER($$%%%s%%$$)", table, filter.Column, filter.Values[0])) + } } } } @@ -44,7 +51,12 @@ func CombinedGormFilter(table string, filters []pagination.Filter, combinedFilte if len(combinedFilter.Columns) > 0 { orQuery := "" for _, column := range combinedFilter.Columns { - orQuery = orQuery + fmt.Sprintf("LOWER(%s.%s::text) like LOWER('%%%s%%') OR ", table, column, combinedFilter.Value) + if strings.Contains(combinedFilter.Value, "%") { + filterVal := strings.Replace(combinedFilter.Value, "%", "`%", -1) + orQuery = orQuery + fmt.Sprintf("LOWER(%s.%s::text) like LOWER($$%%%s%%$$) escape '`' OR ", table, column, filterVal) + } else { + orQuery = orQuery + fmt.Sprintf("LOWER(%s.%s::text) like LOWER($$%%%s%%$$) OR ", table, column, combinedFilter.Value) + } } orQuery = orQuery[:len(orQuery)-3] db = db.Where(orQuery) From b324aeeb364a6067bccfb1ed1532a90227fd9d2b Mon Sep 17 00:00:00 2001 From: Robert Choi Date: Fri, 11 Aug 2023 16:26:47 +0900 Subject: [PATCH 15/23] app-serving: use unique namespace --- internal/delivery/http/app-serve-app.go | 24 +++++++++++++++++++++++- internal/usecase/app-serve-app.go | 22 ++++++++++++++++++++++ pkg/domain/app-serve-app.go | 3 --- 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/internal/delivery/http/app-serve-app.go b/internal/delivery/http/app-serve-app.go index f46b8c24..0d391ca3 100644 --- a/internal/delivery/http/app-serve-app.go +++ b/internal/delivery/http/app-serve-app.go @@ -2,6 +2,7 @@ package http import ( "fmt" + "math/rand" "net/http" "regexp" "strconv" @@ -89,7 +90,7 @@ func NewAppServeAppHandler(h usecase.IAppServeAppUsecase) *AppServeAppHandler { func (h *AppServeAppHandler) CreateAppServeApp(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) organizationId, ok := vars["organizationId"] - fmt.Printf("organizationId = [%v]\n", organizationId) + log.Debugf("organizationId = [%v]\n", organizationId) if !ok { ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("invalid organizationId"), "C_INVALID_ORGANIZATION_ID", "")) return @@ -110,6 +111,8 @@ func (h *AppServeAppHandler) CreateAppServeApp(w http.ResponseWriter, r *http.Re return } + log.Infof("Processing CREATE request for app '%s'...", app.Name) + now := time.Now() app.OrganizationId = organizationId app.EndpointUrl = "N/A" @@ -147,6 +150,25 @@ func (h *AppServeAppHandler) CreateAppServeApp(w http.ResponseWriter, r *http.Re return } + // Check if the namespace is already used in the target cluster + ns := "" + nsExist := true + for nsExist { + // Generate unique namespace based on name and random number + src := rand.NewSource(time.Now().UnixNano()) + r1 := rand.New(src) + ns = fmt.Sprintf("%s-%s", app.Name, strconv.Itoa(r1.Intn(10000))) + + nsExist, err = h.usecase.IsAppServeAppNamespaceExist(app.TargetClusterId, ns) + if err != nil { + ErrorJSON(w, r, httpErrors.NewInternalServerError(err, "", "")) + return + } + } + + log.Infof("Using namespace: %s", ns) + app.Namespace = ns + // Validate port param for springboot app if app.AppType == "springboot" { if task.Port == "" { diff --git a/internal/usecase/app-serve-app.go b/internal/usecase/app-serve-app.go index 63eaee7b..24a4f407 100644 --- a/internal/usecase/app-serve-app.go +++ b/internal/usecase/app-serve-app.go @@ -1,6 +1,7 @@ package usecase import ( + "context" "encoding/json" "fmt" @@ -10,7 +11,9 @@ import ( "github.com/pkg/errors" "github.com/spf13/viper" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "github.com/openinfradev/tks-api/internal/kubernetes" "github.com/openinfradev/tks-api/internal/pagination" "github.com/openinfradev/tks-api/internal/repository" argowf "github.com/openinfradev/tks-api/pkg/argo-client" @@ -27,6 +30,7 @@ type IAppServeAppUsecase interface { GetNumOfAppsOnStack(organizationId string, clusterId string) (int64, error) IsAppServeAppExist(appId string) (bool, error) IsAppServeAppNameExist(orgId string, appName string) (bool, error) + IsAppServeAppNamespaceExist(clusterId string, namespace string) (bool, error) UpdateAppServeAppStatus(appId string, taskId string, status string, output string) (ret string, err error) DeleteAppServeApp(appId string) (res string, err error) UpdateAppServeApp(app *domain.AppServeApp, appTask *domain.AppServeAppTask) (ret string, err error) @@ -231,6 +235,24 @@ func (u *AppServeAppUsecase) IsAppServeAppNameExist(orgId string, appName string return false, nil } +func (u *AppServeAppUsecase) IsAppServeAppNamespaceExist(clusterId string, new_ns string) (bool, error) { + clientset, err := kubernetes.GetClientFromClusterId(clusterId) + if err != nil { + log.Error(err) + return false, err + } + + namespaces, err := clientset.CoreV1().Namespaces().List(context.TODO(), metav1.ListOptions{}) + for _, ns := range namespaces.Items { + if new_ns == ns.ObjectMeta.Name { + log.Debugf("Namespace %s already exists.", new_ns) + return true, nil + } + } + log.Debugf("Namespace %s is available", new_ns) + return false, nil +} + func (u *AppServeAppUsecase) UpdateAppServeAppStatus( appId string, taskId string, diff --git a/pkg/domain/app-serve-app.go b/pkg/domain/app-serve-app.go index 4edcc92d..1624f90d 100644 --- a/pkg/domain/app-serve-app.go +++ b/pkg/domain/app-serve-app.go @@ -92,9 +92,6 @@ type CreateAppServeAppRequest struct { } func (c *CreateAppServeAppRequest) SetDefaultValue() { - if c.Namespace == "" { - c.Namespace = c.Name - } if c.Type == "" { c.Type = "all" } From a7b897c9e15f54a106833242c37203d914ca3348 Mon Sep 17 00:00:00 2001 From: Robert Choi Date: Fri, 11 Aug 2023 17:00:30 +0900 Subject: [PATCH 16/23] fix lint error --- internal/usecase/app-serve-app.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/internal/usecase/app-serve-app.go b/internal/usecase/app-serve-app.go index 24a4f407..53e38005 100644 --- a/internal/usecase/app-serve-app.go +++ b/internal/usecase/app-serve-app.go @@ -243,6 +243,10 @@ func (u *AppServeAppUsecase) IsAppServeAppNamespaceExist(clusterId string, new_n } namespaces, err := clientset.CoreV1().Namespaces().List(context.TODO(), metav1.ListOptions{}) + if err != nil { + log.Error(err) + return false, err + } for _, ns := range namespaces.Items { if new_ns == ns.ObjectMeta.Name { log.Debugf("Namespace %s already exists.", new_ns) From 66b90968c01da26dd8007d7883cd2dc724086dba Mon Sep 17 00:00:00 2001 From: Robert Choi Date: Mon, 14 Aug 2023 11:05:55 +0900 Subject: [PATCH 17/23] app-serving: remove redundant connect button --- internal/delivery/http/app-serve-app.go | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/internal/delivery/http/app-serve-app.go b/internal/delivery/http/app-serve-app.go index 0d391ca3..fc1601b0 100644 --- a/internal/delivery/http/app-serve-app.go +++ b/internal/delivery/http/app-serve-app.go @@ -450,22 +450,8 @@ func makeStage(app *domain.AppServeApp, pl string) domain.StageResponse { var actions []domain.ActionResponse if stage.Status == "DEPLOY_SUCCESS" { - if strategy == "rolling-update" { - action := domain.ActionResponse{ - Name: "ENDPOINT", - Uri: app.EndpointUrl, - Type: "LINK", - } - actions = append(actions, action) - } else if strategy == "blue-green" { - if taskStatus == "PROMOTE_SUCCESS" || taskStatus == "ABORT_SUCCESS" { - action := domain.ActionResponse{ - Name: "ENDPOINT", - Uri: app.EndpointUrl, - Type: "LINK", - } - actions = append(actions, action) - } else if taskStatus == "PROMOTE_WAIT" { + if strategy == "blue-green" { + if taskStatus == "PROMOTE_WAIT" { action := domain.ActionResponse{ Name: "OLD_EP", Uri: app.EndpointUrl, From 12da24d74887a3116398dd06108996277f374233 Mon Sep 17 00:00:00 2001 From: Taekyu Date: Mon, 14 Aug 2023 13:48:29 +0900 Subject: [PATCH 18/23] bugfix. decrease maxstep 15 when creating user cluster --- pkg/domain/stack.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/domain/stack.go b/pkg/domain/stack.go index f0400e9d..16a235bb 100644 --- a/pkg/domain/stack.go +++ b/pkg/domain/stack.go @@ -61,7 +61,7 @@ func (m StackStatus) FromString(s string) StackStatus { return StackStatus_PENDING } -const MAX_STEP_CLUSTER_CREATE = 16 +const MAX_STEP_CLUSTER_CREATE = 15 const MAX_STEP_CLUSTER_REMOVE = 11 const MAX_STEP_LMA_CREATE_PRIMARY = 42 const MAX_STEP_LMA_CREATE_MEMBER = 27 From f316b64e642ec86550e7d004365dba9b815159de Mon Sep 17 00:00:00 2001 From: Taekyu Date: Mon, 14 Aug 2023 13:58:30 +0900 Subject: [PATCH 19/23] bugfix. change default sort order. (created_at DESC) --- internal/pagination/pagination.go | 4 ++-- internal/repository/cluster.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/pagination/pagination.go b/internal/pagination/pagination.go index 40ed71ff..287da518 100644 --- a/internal/pagination/pagination.go +++ b/internal/pagination/pagination.go @@ -82,7 +82,7 @@ func NewPagination(urlParams *url.Values) (*Pagination, error) { } case SORT_ORDER: if value[0] == "" { - pg.SortOrder = "ASC" + pg.SortOrder = "DESC" } else { pg.SortOrder = value[0] } @@ -130,7 +130,7 @@ func NewPagination(urlParams *url.Values) (*Pagination, error) { func NewDefaultPagination() *Pagination { return &Pagination{ SortColumn: "created_at", - SortOrder: "ASC", + SortOrder: "DESC", Page: 1, Limit: MAX_LIMIT, } diff --git a/internal/repository/cluster.go b/internal/repository/cluster.go index 80ee8898..153b2c4a 100644 --- a/internal/repository/cluster.go +++ b/internal/repository/cluster.go @@ -112,7 +112,7 @@ func (r *ClusterRepository) FetchByOrganizationId(organizationId string, pg *pag if pg == nil { pg = pagination.NewDefaultPagination() } - pg.SortColumn = "updated_at" + pg.SortColumn = "created_at" pg.SortOrder = "DESC" filterFunc := CombinedGormFilter("clusters", pg.GetFilters(), pg.CombinedFilter) db := filterFunc(r.db.Model(&Cluster{}).Preload(clause.Associations). @@ -138,7 +138,7 @@ func (r *ClusterRepository) FetchByCloudAccountId(cloudAccountId uuid.UUID, pg * if pg == nil { pg = pagination.NewDefaultPagination() } - pg.SortColumn = "updated_at" + pg.SortColumn = "created_at" pg.SortOrder = "DESC" filterFunc := CombinedGormFilter("clusters", pg.GetFilters(), pg.CombinedFilter) db := filterFunc(r.db.Model(&Cluster{}).Preload("CloudAccount"). From 476f1eaded55be7f4b9cc8763e744085829b434e Mon Sep 17 00:00:00 2001 From: donggyu Date: Thu, 17 Aug 2023 11:18:05 +0900 Subject: [PATCH 20/23] minor fix: change sso_session_idle_timeout time 8hours -> 1day --- internal/keycloak/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/keycloak/config.go b/internal/keycloak/config.go index cb87c975..212748c1 100644 --- a/internal/keycloak/config.go +++ b/internal/keycloak/config.go @@ -13,6 +13,6 @@ const ( DefaultClientSecret = "secret" AdminCliClientID = "admin-cli" accessTokenLifespan = 60 * 60 * 24 // 1 day - ssoSessionIdleTimeout = 60 * 60 * 8 // 8 hours + ssoSessionIdleTimeout = 60 * 60 * 24 // 1 day ssoSessionMaxLifespan = 60 * 60 * 24 // 1 day ) From 674efdb9ada871e0d28eb9b22d3085cc611bfbf8 Mon Sep 17 00:00:00 2001 From: Taekyu Date: Fri, 18 Aug 2023 14:34:44 +0900 Subject: [PATCH 21/23] bugfix. change promsql function rate() to irate() on dashboard' --- internal/usecase/dashboard.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/usecase/dashboard.go b/internal/usecase/dashboard.go index 67a2676a..663bd7b7 100644 --- a/internal/usecase/dashboard.go +++ b/internal/usecase/dashboard.go @@ -261,7 +261,7 @@ func (u *DashboardUsecase) getChartFromPrometheus(organizationId string, chartTy switch chartType { case domain.ChartType_CPU.String(): //query := "sum (avg(1-rate(node_cpu_seconds_total{mode=\"idle\"}[1h])) by (taco_cluster))" - query = "avg by (taco_cluster) (1-rate(node_cpu_seconds_total{mode=\"idle\"}[1h]))" + query = "avg by (taco_cluster) (1-irate(node_cpu_seconds_total{mode=\"idle\"}[1h]))" case domain.ChartType_MEMORY.String(): query = "avg by (taco_cluster) (sum(node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) by (taco_cluster) / sum(node_memory_MemTotal_bytes) by (taco_cluster))" @@ -270,7 +270,7 @@ func (u *DashboardUsecase) getChartFromPrometheus(organizationId string, chartTy query = "sum by (taco_cluster) (changes(kube_pod_container_status_restarts_total{namespace!=\"kube-system\"}[1h]))" case domain.ChartType_TRAFFIC.String(): - query = "avg by (taco_cluster) (rate(container_network_receive_bytes_total[1h]))" + query = "avg by (taco_cluster) (irate(container_network_receive_bytes_total[1h]))" case domain.ChartType_POD_CALENDAR.String(): // 입력받은 년,월 을 date 형식으로 From 7ae930b4841c528d4a4eda23df5e150ce7535935 Mon Sep 17 00:00:00 2001 From: Taekyu Date: Mon, 21 Aug 2023 14:36:36 +0900 Subject: [PATCH 22/23] bugfix. fix thanos query for dashboard --- api/swagger/docs.go | 3 --- api/swagger/swagger.json | 3 --- api/swagger/swagger.yaml | 2 -- internal/usecase/dashboard.go | 10 ++++------ pkg/domain/stack.go | 2 +- 5 files changed, 5 insertions(+), 15 deletions(-) diff --git a/api/swagger/docs.go b/api/swagger/docs.go index 77172154..fbfc0d1a 100644 --- a/api/swagger/docs.go +++ b/api/swagger/docs.go @@ -5962,9 +5962,6 @@ const docTemplate = `{ }, "domain.UpdateStackRequest": { "type": "object", - "required": [ - "description" - ], "properties": { "description": { "type": "string" diff --git a/api/swagger/swagger.json b/api/swagger/swagger.json index cd91d143..7682a695 100644 --- a/api/swagger/swagger.json +++ b/api/swagger/swagger.json @@ -5955,9 +5955,6 @@ }, "domain.UpdateStackRequest": { "type": "object", - "required": [ - "description" - ], "properties": { "description": { "type": "string" diff --git a/api/swagger/swagger.yaml b/api/swagger/swagger.yaml index 4227bbed..5f015d41 100644 --- a/api/swagger/swagger.yaml +++ b/api/swagger/swagger.yaml @@ -1618,8 +1618,6 @@ definitions: properties: description: type: string - required: - - description type: object domain.UpdateStackTemplateRequest: properties: diff --git a/internal/usecase/dashboard.go b/internal/usecase/dashboard.go index 663bd7b7..aa25da53 100644 --- a/internal/usecase/dashboard.go +++ b/internal/usecase/dashboard.go @@ -252,8 +252,6 @@ func (u *DashboardUsecase) getChartFromPrometheus(organizationId string, chartTy intervalSec = 60 * 60 case "1d": intervalSec = 60 * 60 * 24 - case "7h": - intervalSec = 60 * 60 * 24 * 7 } query := "" @@ -261,16 +259,16 @@ func (u *DashboardUsecase) getChartFromPrometheus(organizationId string, chartTy switch chartType { case domain.ChartType_CPU.String(): //query := "sum (avg(1-rate(node_cpu_seconds_total{mode=\"idle\"}[1h])) by (taco_cluster))" - query = "avg by (taco_cluster) (1-irate(node_cpu_seconds_total{mode=\"idle\"}[1h]))" + query = "avg by (taco_cluster) (1-irate(node_cpu_seconds_total{mode=\"idle\"}[" + interval + "]))" case domain.ChartType_MEMORY.String(): query = "avg by (taco_cluster) (sum(node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) by (taco_cluster) / sum(node_memory_MemTotal_bytes) by (taco_cluster))" case domain.ChartType_POD.String(): - query = "sum by (taco_cluster) (changes(kube_pod_container_status_restarts_total{namespace!=\"kube-system\"}[1h]))" + query = "sum by (taco_cluster) (changes(kube_pod_container_status_restarts_total{namespace!=\"kube-system\"}[" + interval + "]))" case domain.ChartType_TRAFFIC.String(): - query = "avg by (taco_cluster) (irate(container_network_receive_bytes_total[1h]))" + query = "avg by (taco_cluster) (irate(container_network_receive_bytes_total[" + interval + "]))" case domain.ChartType_POD_CALENDAR.String(): // 입력받은 년,월 을 date 형식으로 @@ -340,7 +338,7 @@ func (u *DashboardUsecase) getChartFromPrometheus(organizationId string, chartTy return domain.DashboardChart{}, fmt.Errorf("No data") } - result, err := thanosClient.FetchRange(query, int(now.Unix())-durationSec, int(now.Unix())+10000, intervalSec) + result, err := thanosClient.FetchRange(query, int(now.Unix())-durationSec, int(now.Unix()), intervalSec) if err != nil { return res, err } diff --git a/pkg/domain/stack.go b/pkg/domain/stack.go index 16a235bb..f405ad99 100644 --- a/pkg/domain/stack.go +++ b/pkg/domain/stack.go @@ -162,7 +162,7 @@ type GetStackResponse struct { } type UpdateStackRequest struct { - Description string `json:"description" validate:"required"` + Description string `json:"description"` } type CheckStackNameResponse struct { From afef5d2e82e9aca30db504b040bc7ee1b64a3a01 Mon Sep 17 00:00:00 2001 From: Taekyu Date: Mon, 21 Aug 2023 15:04:55 +0900 Subject: [PATCH 23/23] bugfix. fix stack status logic. --- internal/usecase/stack.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/usecase/stack.go b/internal/usecase/stack.go index df4d855c..2182a658 100644 --- a/internal/usecase/stack.go +++ b/internal/usecase/stack.go @@ -691,6 +691,9 @@ func reflectClusterToStack(cluster domain.Cluster, appGroups []domain.AppGroup) // [TODO] more pretty func getStackStatus(cluster domain.Cluster, appGroups []domain.AppGroup) (domain.StackStatus, string) { for _, appGroup := range appGroups { + if appGroup.Status == domain.AppGroupStatus_PENDING && cluster.Status == domain.ClusterStatus_RUNNING { + return domain.StackStatus_APPGROUP_INSTALLING, appGroup.StatusDesc + } if appGroup.Status == domain.AppGroupStatus_INSTALLING { return domain.StackStatus_APPGROUP_INSTALLING, appGroup.StatusDesc }