Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feature. add cloudSetting to cluster #7

Merged
merged 1 commit into from
Mar 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions api/swagger/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -1145,6 +1145,9 @@ const docTemplate = `{
"domain.Cluster": {
"type": "object",
"properties": {
"cloudSetting": {
"$ref": "#/definitions/domain.CloudSetting"
},
"conf": {
"$ref": "#/definitions/domain.ClusterConf"
},
Expand Down Expand Up @@ -1256,6 +1259,9 @@ const docTemplate = `{
"domain.CreateClusterRequest": {
"type": "object",
"properties": {
"cloudSettingId": {
"type": "string"
},
"creator": {
"type": "string"
},
Expand Down
6 changes: 6 additions & 0 deletions api/swagger/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -1138,6 +1138,9 @@
"domain.Cluster": {
"type": "object",
"properties": {
"cloudSetting": {
"$ref": "#/definitions/domain.CloudSetting"
},
"conf": {
"$ref": "#/definitions/domain.ClusterConf"
},
Expand Down Expand Up @@ -1249,6 +1252,9 @@
"domain.CreateClusterRequest": {
"type": "object",
"properties": {
"cloudSettingId": {
"type": "string"
},
"creator": {
"type": "string"
},
Expand Down
4 changes: 4 additions & 0 deletions api/swagger/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ definitions:
type: object
domain.Cluster:
properties:
cloudSetting:
$ref: '#/definitions/domain.CloudSetting'
conf:
$ref: '#/definitions/domain.ClusterConf'
createdAt:
Expand Down Expand Up @@ -160,6 +162,8 @@ definitions:
type: object
domain.CreateClusterRequest:
properties:
cloudSettingId:
type: string
creator:
type: string
description:
Expand Down
32 changes: 8 additions & 24 deletions internal/delivery/http/cluster.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
package http

import (
"encoding/json"
"fmt"
"io"
"net/http"

"github.com/gorilla/mux"
"github.com/openinfradev/tks-api/internal/auth/request"
"github.com/openinfradev/tks-api/internal/usecase"
"github.com/openinfradev/tks-api/pkg/domain"
"github.com/openinfradev/tks-api/pkg/httpErrors"
Expand Down Expand Up @@ -94,36 +93,21 @@ func (h *ClusterHandler) GetCluster(w http.ResponseWriter, r *http.Request) {
// @Router /clusters [post]
// @Security JWT
func (h *ClusterHandler) CreateCluster(w http.ResponseWriter, r *http.Request) {
input := domain.CreateClusterRequest{}
body, err := io.ReadAll(r.Body)
if err != nil {
log.Error(err)
user, ok := request.UserFrom(r.Context())
if !ok {
ErrorJSON(w, httpErrors.NewBadRequestError(fmt.Errorf("Invalid token")))
return
}
err = json.Unmarshal(body, &input)

input := domain.CreateClusterRequest{}
err := UnmarshalRequestInput(r, &input)
if err != nil {
ErrorJSON(w, httpErrors.NewBadRequestError(err))
return
}

creator := ""

//txHandle := r.Context().Value("txHandle").(*gorm.DB)
clusterId, err := h.usecase.Create(
input.OrganizationId,
input.TemplateId,
input.Name,
domain.ClusterConf{
Region: input.Region,
NumOfAz: input.NumberOfAz,
SshKeyName: "",
MachineType: input.MachineType,
MachineReplicas: input.MachineReplicas,
},
creator,
input.Description,
)

clusterId, err := h.usecase.Create(user, input)
if err != nil {
ErrorJSON(w, err)
return
Expand Down
32 changes: 23 additions & 9 deletions internal/repository/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ type IClusterRepository interface {
FetchByOrganizationId(organizationId string) (res []domain.Cluster, err error)
FetchByCloudSettingId(cloudSettingId uuid.UUID) (res []domain.Cluster, err error)
Get(id string) (domain.Cluster, error)
Create(organizationId string, templateId string, name string, conf *domain.ClusterConf, creator uuid.UUID, description string) (clusterId string, err error)
Create(organizationId string, templateId string, name string, cloudSettingId uuid.UUID, conf *domain.ClusterConf, creator uuid.UUID, description string) (clusterId string, err error)
Delete(id string) error
InitWorkflow(clusterId string, workflowId string) error
}
Expand Down Expand Up @@ -78,7 +78,7 @@ func (r *ClusterRepository) Fetch() (out []domain.Cluster, err error) {
var clusters []Cluster
out = []domain.Cluster{}

res := r.db.Find(&clusters)
res := r.db.Preload("CloudSetting").Find(&clusters)
if res.Error != nil {
return nil, res.Error
}
Expand All @@ -93,7 +93,7 @@ func (r *ClusterRepository) Fetch() (out []domain.Cluster, err error) {
func (r *ClusterRepository) FetchByOrganizationId(organizationId string) (out []domain.Cluster, err error) {
var clusters []Cluster

res := r.db.Find(&clusters, "organization_id = ?", organizationId)
res := r.db.Preload("CloudSetting").Find(&clusters, "organization_id = ?", organizationId)

if res.Error != nil {
return nil, res.Error
Expand All @@ -114,7 +114,7 @@ func (r *ClusterRepository) FetchByOrganizationId(organizationId string) (out []
func (r *ClusterRepository) FetchByCloudSettingId(cloudSettingId uuid.UUID) (out []domain.Cluster, err error) {
var clusters []Cluster

res := r.db.Find(&clusters, "cloud_setting_id = ?", cloudSettingId)
res := r.db.Preload("CloudSetting").Find(&clusters, "cloud_setting_id = ?", cloudSettingId)

if res.Error != nil {
return nil, res.Error
Expand Down Expand Up @@ -143,13 +143,14 @@ func (r *ClusterRepository) Get(id string) (domain.Cluster, error) {
return resCluster, nil
}

func (r *ClusterRepository) Create(organizationId string, templateId string, name string, conf *domain.ClusterConf, creator uuid.UUID, description string) (string, error) {
func (r *ClusterRepository) Create(organizationId string, templateId string, name string, cloudSettingId uuid.UUID, conf *domain.ClusterConf, creator uuid.UUID, description string) (string, error) {
cluster := Cluster{
OrganizationId: organizationId,
TemplateId: templateId,
Name: name,
Creator: creator,
Description: description,
CloudSettingId: cloudSettingId,
Creator: creator,
SshKeyName: conf.SshKeyName,
Region: conf.Region,
NumOfAz: conf.NumOfAz,
Expand Down Expand Up @@ -188,14 +189,12 @@ func (r *ClusterRepository) InitWorkflow(clusterId string, workflowId string) er
}

func (r *ClusterRepository) reflect(cluster Cluster) domain.Cluster {

log.Info(helper.ModelToJson(cluster))

return domain.Cluster{
ID: cluster.ID,
OrganizationId: cluster.OrganizationId,
Name: cluster.Name,
Description: cluster.Description,
CloudSetting: r.reflectCloudSetting(cluster.CloudSetting),
Status: cluster.Status.String(),
StatusDesc: cluster.StatusDesc,
Creator: cluster.Creator.String(),
Expand All @@ -211,3 +210,18 @@ func (r *ClusterRepository) reflect(cluster Cluster) domain.Cluster {
},
}
}

func (r *ClusterRepository) reflectCloudSetting(cloudSetting CloudSetting) domain.CloudSetting {
return domain.CloudSetting{
ID: cloudSetting.ID.String(),
OrganizationId: cloudSetting.OrganizationId,
Name: cloudSetting.Name,
Description: cloudSetting.Description,
Resource: cloudSetting.Resource,
Type: cloudSetting.Type,
Creator: cloudSetting.Creator.String(),
Updator: cloudSetting.Updator.String(),
CreatedAt: cloudSetting.CreatedAt,
UpdatedAt: cloudSetting.UpdatedAt,
}
}
51 changes: 30 additions & 21 deletions internal/usecase/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@ import (
"strings"

"github.com/google/uuid"
"github.com/openinfradev/tks-api/internal/auth/user"
"github.com/openinfradev/tks-api/internal/repository"
argowf "github.com/openinfradev/tks-api/pkg/argo-client"
"github.com/openinfradev/tks-api/pkg/domain"
"github.com/openinfradev/tks-api/pkg/httpErrors"
"github.com/openinfradev/tks-api/pkg/log"
"github.com/pkg/errors"
"github.com/spf13/viper"
"gorm.io/gorm"
)
Expand All @@ -17,7 +20,7 @@ type IClusterUsecase interface {
WithTrx(*gorm.DB) IClusterUsecase
Fetch(organizationId string) ([]domain.Cluster, error)
FetchByCloudSettingId(cloudSettingId uuid.UUID) (out []domain.Cluster, err error)
Create(organizationId string, templateId string, name string, conf domain.ClusterConf, creatorId string, description string) (clusterId string, err error)
Create(user user.Info, in domain.CreateClusterRequest) (clusterId string, err error)
Get(clusterId string) (out domain.Cluster, err error)
Delete(clusterId string) (err error)
}
Expand Down Expand Up @@ -87,55 +90,61 @@ func (u *ClusterUsecase) FetchByCloudSettingId(cloudSettingId uuid.UUID) (out []
return nil, fmt.Errorf("Invalid cloudSettingId")
}

out, err = u.repo.Fetch()

if err != nil {
return nil, err
}
return out, nil
}

func (u *ClusterUsecase) Create(organizationId string, templateId string, name string, conf domain.ClusterConf, creatorId string, description string) (clusterId string, err error) {
creator := uuid.Nil
if creatorId != "" {
creator, err = uuid.Parse(creatorId)
if err != nil {
return "", fmt.Errorf("Invalid Creator ID %s", creatorId)
}
}

func (u *ClusterUsecase) Create(session user.Info, in domain.CreateClusterRequest) (clusterId string, err error) {
/***************************
* Pre-process cluster conf *
***************************/
clConf, err := u.constructClusterConf(&conf)
clConf, err := u.constructClusterConf(&domain.ClusterConf{
Region: in.Region,
NumOfAz: in.NumberOfAz,
SshKeyName: "",
MachineType: in.MachineType,
MachineReplicas: in.MachineReplicas,
},
)
if err != nil {
return "", err
}

clusterId, err = u.repo.Create(organizationId, templateId, name, clConf, creator, description)
parsedCloudSettingId, err := uuid.Parse(in.CloudSettingId)
if err != nil {
return "", fmt.Errorf("Failed to create cluster")
return "", errors.Wrap(err, "Invalid UUID cloudSettingId")
}

clusterId, err = u.repo.Create(in.OrganizationId, in.TemplateId, in.Name, parsedCloudSettingId, clConf, session.GetUserId(), in.Description)
if err != nil {
return "", errors.Wrap(err, "Failed to create cluster")
}

// Call argo workflow
workflowId, err := u.argo.SumbitWorkflowFromWftpl(
"create-tks-usercluster",
argowf.SubmitOptions{
Parameters: []string{
"contract_id=" + organizationId,
"contract_id=" + in.OrganizationId,
"cluster_id=" + clusterId,
"site_name=" + clusterId,
"template_name=" + templateId,
"template_name=" + in.TemplateId,
"git_account=" + viper.GetString("git-account"),
//"manifest_repo_url=" + viper.GetString("git-base-url") + "/" + viper.GetString("git-account") + "/" + clusterId + "-manifests",
},
})
if err != nil {
log.Error("failed to submit argo workflow template. err : ", err)
return "", fmt.Errorf("Failed to call argo workflow : %s", err)
return "", err
}
log.Info("Successfully submited workflow: ", workflowId)

if err := u.repo.InitWorkflow(clusterId, workflowId); err != nil {
return "", fmt.Errorf("Failed to initialize status . err : %s", err)
return "", errors.Wrap(err, "Failed to initialize status")
}

return clusterId, nil
Expand All @@ -152,7 +161,7 @@ func (u *ClusterUsecase) Get(clusterId string) (out domain.Cluster, err error) {
func (u *ClusterUsecase) Delete(clusterId string) (err error) {
cluster, err := u.repo.Get(clusterId)
if err != nil {
return fmt.Errorf("No cluster for deletiing : %s", clusterId)
return httpErrors.NewNotFoundError(err)
}

if cluster.Status != "RUNNING" {
Expand All @@ -161,7 +170,7 @@ func (u *ClusterUsecase) Delete(clusterId string) (err error) {

resAppGroups, err := u.appGroupRepo.Fetch(clusterId)
if err != nil {
return fmt.Errorf("Failed to get appgroup : %s", err)
return errors.Wrap(err, "Failed to get appgroup")
}

for _, resAppGroup := range resAppGroups {
Expand All @@ -181,13 +190,13 @@ func (u *ClusterUsecase) Delete(clusterId string) (err error) {
})
if err != nil {
log.Error("failed to submit argo workflow template. err : ", err)
return fmt.Errorf("Failed to call argo workflow : %s", err)
return errors.Wrap(err, "Failed to call argo workflow")
}

log.Debug("submited workflow name : ", workflowId)

if err := u.repo.InitWorkflow(clusterId, workflowId); err != nil {
return fmt.Errorf("Failed to initialize cluster status. err : %s", err)
return errors.Wrap(err, "Failed to initialize status")
}

return nil
Expand Down
22 changes: 12 additions & 10 deletions pkg/domain/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,17 @@ func (m ClusterStatus) FromString(s string) ClusterStatus {

// model
type Cluster = struct {
ID string `json:"id"`
OrganizationId string `json:"organizationId"`
Name string `json:"name"`
Description string `json:"description"`
Status string `json:"status"`
StatusDesc string `json:"statusDesc"`
Conf ClusterConf `json:"conf"`
Creator string `json:"creator"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
ID string `json:"id"`
OrganizationId string `json:"organizationId"`
Name string `json:"name"`
Description string `json:"description"`
CloudSetting CloudSetting `json:"cloudSetting"`
Status string `json:"status"`
StatusDesc string `json:"statusDesc"`
Conf ClusterConf `json:"conf"`
Creator string `json:"creator"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}

type ClusterConf = struct {
Expand Down Expand Up @@ -99,6 +100,7 @@ type CreateClusterRequest struct {
TemplateId string `json:"templateId"`
Name string `json:"name"`
Description string `json:"description"`
CloudSettingId string `json:"cloudSettingId"`
NumberOfAz int `json:"numberOfAz"`
MachineType string `json:"machineType"`
Region string `json:"region"`
Expand Down