diff --git a/api/swagger/docs.go b/api/swagger/docs.go index b35f65c1..6d5d58d3 100644 --- a/api/swagger/docs.go +++ b/api/swagger/docs.go @@ -4219,6 +4219,9 @@ const docTemplate = `{ "description": { "type": "string" }, + "favorited": { + "type": "boolean" + }, "id": { "type": "string" }, @@ -4684,6 +4687,9 @@ const docTemplate = `{ "stackTemplateId" ], "properties": { + "adminClusterUrl": { + "type": "string" + }, "cloudAccountId": { "type": "string" }, @@ -5772,6 +5778,9 @@ const docTemplate = `{ "domain.StackResponse": { "type": "object", "properties": { + "adminClusterUrl": { + "type": "string" + }, "cloudAccount": { "$ref": "#/definitions/domain.SimpleCloudAccountResponse" }, @@ -5787,6 +5796,9 @@ const docTemplate = `{ "description": { "type": "string" }, + "favorited": { + "type": "boolean" + }, "grafanaUrl": { "type": "string" }, diff --git a/api/swagger/swagger.json b/api/swagger/swagger.json index ef7eb582..5b065ef1 100644 --- a/api/swagger/swagger.json +++ b/api/swagger/swagger.json @@ -4212,6 +4212,9 @@ "description": { "type": "string" }, + "favorited": { + "type": "boolean" + }, "id": { "type": "string" }, @@ -4677,6 +4680,9 @@ "stackTemplateId" ], "properties": { + "adminClusterUrl": { + "type": "string" + }, "cloudAccountId": { "type": "string" }, @@ -5765,6 +5771,9 @@ "domain.StackResponse": { "type": "object", "properties": { + "adminClusterUrl": { + "type": "string" + }, "cloudAccount": { "$ref": "#/definitions/domain.SimpleCloudAccountResponse" }, @@ -5780,6 +5789,9 @@ "description": { "type": "string" }, + "favorited": { + "type": "boolean" + }, "grafanaUrl": { "type": "string" }, diff --git a/api/swagger/swagger.yaml b/api/swagger/swagger.yaml index 4f484a0a..564ae5bb 100644 --- a/api/swagger/swagger.yaml +++ b/api/swagger/swagger.yaml @@ -376,6 +376,8 @@ definitions: type: string description: type: string + favorited: + type: boolean id: type: string name: @@ -687,6 +689,8 @@ definitions: type: object domain.CreateStackRequest: properties: + adminClusterUrl: + type: string cloudAccountId: type: string cloudService: @@ -1409,6 +1413,8 @@ definitions: type: object domain.StackResponse: properties: + adminClusterUrl: + type: string cloudAccount: $ref: '#/definitions/domain.SimpleCloudAccountResponse' conf: @@ -1419,6 +1425,8 @@ definitions: $ref: '#/definitions/domain.SimpleUserResponse' description: type: string + favorited: + type: boolean grafanaUrl: type: string id: diff --git a/internal/delivery/http/stack.go b/internal/delivery/http/stack.go index d9ba89d7..9d219f6b 100644 --- a/internal/delivery/http/stack.go +++ b/internal/delivery/http/stack.go @@ -49,10 +49,20 @@ func (h *StackHandler) CreateStack(w http.ResponseWriter, r *http.Request) { return } + if input.CloudService == domain.CloudService_BYOH { + if input.AdminClusterUrl == "" { + ErrorJSON(w, r, httpErrors.NewBadRequestError(fmt.Errorf("Invalid adminClusterUrl"), "C_INVALID_ADMINCLUSTER_URL", "")) + return + } + } + var dto domain.Stack if err = serializer.Map(input, &dto); err != nil { log.InfoWithContext(r.Context(), err) } + if err = serializer.Map(input, &dto.Conf); err != nil { + log.InfoWithContext(r.Context(), err) + } dto.OrganizationId = organizationId stackId, err := h.usecase.Create(r.Context(), dto) diff --git a/internal/repository/cluster.go b/internal/repository/cluster.go index 649c18ce..725bc416 100644 --- a/internal/repository/cluster.go +++ b/internal/repository/cluster.go @@ -61,7 +61,8 @@ type Cluster struct { CloudAccount CloudAccount `gorm:"foreignKey:CloudAccountId"` StackTemplateId uuid.UUID StackTemplate StackTemplate `gorm:"foreignKey:StackTemplateId"` - Favorite *[]ClusterFavorite + Favorites *[]ClusterFavorite + ByohHosts *[]ClusterByohHost ClusterType domain.ClusterType `gorm:"default:0"` TksCpNode int TksCpNodeMax int @@ -93,6 +94,14 @@ type ClusterFavorite struct { User User `gorm:"foreignKey:UserId"` } +type ClusterByohHost struct { + ID uuid.UUID `gorm:"primarykey"` + ClusterId domain.ClusterId + Cluster Cluster `gorm:"foreignKey:ClusterId"` + Type string + HostName string +} + func (c *ClusterFavorite) BeforeCreate(tx *gorm.DB) (err error) { c.ID = uuid.New() return nil @@ -315,6 +324,10 @@ func (r *ClusterRepository) DeleteFavorite(clusterId domain.ClusterId, userId uu } func reflectCluster(cluster Cluster) (out domain.Cluster) { + if err := serializer.Map(cluster.Model, &out); err != nil { + log.Error(err) + } + if err := serializer.Map(cluster, &out); err != nil { log.Error(err) } @@ -322,5 +335,13 @@ func reflectCluster(cluster Cluster) (out domain.Cluster) { if err := serializer.Map(cluster, &out.Conf); err != nil { log.Error(err) } + + if cluster.Favorites != nil && len(*cluster.Favorites) > 0 { + out.Favorited = true + + } else { + out.Favorited = false + } + return } diff --git a/internal/usecase/cluster.go b/internal/usecase/cluster.go index 417c6375..63fba610 100644 --- a/internal/usecase/cluster.go +++ b/internal/usecase/cluster.go @@ -159,23 +159,42 @@ func (u *ClusterUsecase) Create(ctx context.Context, dto domain.Cluster) (cluste return "", errors.Wrap(err, "Failed to create cluster") } - // Call argo workflow - workflowId, err := u.argo.SumbitWorkflowFromWftpl( - "create-tks-usercluster", - argowf.SubmitOptions{ - Parameters: []string{ - fmt.Sprintf("tks_api_url=%s", viper.GetString("external-address")), - "contract_id=" + dto.OrganizationId, - "cluster_id=" + clusterId.String(), - "site_name=" + clusterId.String(), - "template_name=" + stackTemplate.Template, - "git_account=" + viper.GetString("git-account"), - "creator=" + user.GetUserId().String(), - "cloud_account_id=" + tksCloudAccountId, - "base_repo_branch=" + viper.GetString("revision"), - //"manifest_repo_url=" + viper.GetString("git-base-url") + "/" + viper.GetString("git-account") + "/" + clusterId + "-manifests", - }, - }) + workflowId := "" + if dto.CloudService == domain.CloudService_BYOH { + workflowId, err = u.argo.SumbitWorkflowFromWftpl( + "bootstrap-tks-usercluster", + argowf.SubmitOptions{ + Parameters: []string{ + fmt.Sprintf("tks_api_url=%s", viper.GetString("external-address")), + "contract_id=" + dto.OrganizationId, + "cluster_id=" + clusterId.String(), + "site_name=" + clusterId.String(), + "template_name=" + stackTemplate.Template, + "git_account=" + viper.GetString("git-account"), + "creator=" + user.GetUserId().String(), + "cloud_account_id=" + tksCloudAccountId, + "base_repo_branch=" + viper.GetString("revision"), + //"manifest_repo_url=" + viper.GetString("git-base-url") + "/" + viper.GetString("git-account") + "/" + clusterId + "-manifests", + }, + }) + } else { + workflowId, err = u.argo.SumbitWorkflowFromWftpl( + "create-tks-usercluster", + argowf.SubmitOptions{ + Parameters: []string{ + fmt.Sprintf("tks_api_url=%s", viper.GetString("external-address")), + "contract_id=" + dto.OrganizationId, + "cluster_id=" + clusterId.String(), + "site_name=" + clusterId.String(), + "template_name=" + stackTemplate.Template, + "git_account=" + viper.GetString("git-account"), + "creator=" + user.GetUserId().String(), + "cloud_account_id=" + tksCloudAccountId, + "base_repo_branch=" + viper.GetString("revision"), + //"manifest_repo_url=" + viper.GetString("git-base-url") + "/" + viper.GetString("git-account") + "/" + clusterId + "-manifests", + }, + }) + } if err != nil { log.ErrorWithContext(ctx, "failed to submit argo workflow template. err : ", err) return "", err diff --git a/internal/usecase/stack.go b/internal/usecase/stack.go index bcb314b9..b5bf8a8d 100644 --- a/internal/usecase/stack.go +++ b/internal/usecase/stack.go @@ -115,6 +115,7 @@ func (u *StackUsecase) Create(ctx context.Context, dto domain.Stack) (stackId do "creator=" + user.GetUserId().String(), "base_repo_branch=" + viper.GetString("revision"), "infra_conf=" + strings.Replace(helper.ModelToJson(stackConf), "\"", "\\\"", -1), + "cloud_service=" + dto.CloudService, }, }) if err != nil { diff --git a/pkg/domain/cluster.go b/pkg/domain/cluster.go index 98ff1514..7558d0d5 100644 --- a/pkg/domain/cluster.go +++ b/pkg/domain/cluster.go @@ -86,6 +86,7 @@ type Cluster struct { Status ClusterStatus StatusDesc string Conf ClusterConf + Favorited bool CreatorId *uuid.UUID Creator User ClusterType ClusterType diff --git a/pkg/domain/stack.go b/pkg/domain/stack.go index b8800f8d..efd6ced8 100644 --- a/pkg/domain/stack.go +++ b/pkg/domain/stack.go @@ -91,6 +91,8 @@ type Stack = struct { Updator User CreatedAt time.Time UpdatedAt time.Time + Favorited bool + AdminClusterUrl string } type StackConf struct { @@ -126,6 +128,7 @@ type CreateStackRequest struct { TksUserNode int `json:"tksUserNode"` TksUserNodeMax int `json:"tksUserNodeMax,omitempty"` TksUserNodeType string `json:"tksUserNodeType,omitempty"` + AdminClusterUrl string `json:"adminClusterUrl,omitempty"` } type CreateStackResponse struct { @@ -145,21 +148,23 @@ type StackConfResponse struct { } type StackResponse struct { - ID StackId `json:"id"` - Name string `json:"name"` - Description string `json:"description"` - OrganizationId string `json:"organizationId"` - StackTemplate SimpleStackTemplateResponse `json:"stackTemplate,omitempty"` - CloudAccount SimpleCloudAccountResponse `json:"cloudAccount,omitempty"` - Status string `json:"status"` - StatusDesc string `json:"statusDesc"` - PrimaryCluster bool `json:"primaryCluster"` - Conf StackConfResponse `json:"conf"` - GrafanaUrl string `json:"grafanaUrl"` - Creator SimpleUserResponse `json:"creator,omitempty"` - Updator SimpleUserResponse `json:"updator,omitempty"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` + ID StackId `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + OrganizationId string `json:"organizationId"` + StackTemplate SimpleStackTemplateResponse `json:"stackTemplate,omitempty"` + CloudAccount SimpleCloudAccountResponse `json:"cloudAccount,omitempty"` + Status string `json:"status"` + StatusDesc string `json:"statusDesc"` + PrimaryCluster bool `json:"primaryCluster"` + Conf StackConfResponse `json:"conf"` + GrafanaUrl string `json:"grafanaUrl"` + Creator SimpleUserResponse `json:"creator,omitempty"` + Updator SimpleUserResponse `json:"updator,omitempty"` + Favorited bool `json:"favorited"` + AdminClusterUrl string `json:"adminClusterUrl,omitempty"` + CreatedAt time.Time `json:"createdAt"` + UpdatedAt time.Time `json:"updatedAt"` } type GetStacksResponse struct { diff --git a/pkg/httpErrors/errorCode.go b/pkg/httpErrors/errorCode.go index 17f62395..6a4a9dcb 100644 --- a/pkg/httpErrors/errorCode.go +++ b/pkg/httpErrors/errorCode.go @@ -55,6 +55,7 @@ var errorMap = map[ErrorCode]string{ "S_FAILED_GET_CLUSTERS": "클러스터를 가져오는데 실패했습니다.", "S_FAILED_DELETE_EXISTED_ASA": "지우고자 하는 스택에 남아 있는 앱서빙앱이 있습니다.", "S_NOT_ENOUGH_QUOTA": "AWS 의 resource quota 가 부족합니다. 관리자에게 문의하세요.", + "C_INVALID_ADMINCLUSTER_URL": "BYOH 타입의 클러스터 생성은 반드시 adminClusterUrl 값이 필요합니다.", // Alert "AL_NOT_FOUND_ALERT": "지정한 앨럿이 존재하지 않습니다.",