diff --git a/cmd/server/cluster_byoh.go b/cmd/server/cluster_byoh.go new file mode 100644 index 0000000..76e06fc --- /dev/null +++ b/cmd/server/cluster_byoh.go @@ -0,0 +1,113 @@ +package main + +import ( + "bytes" + "encoding/json" + "fmt" + + "github.com/openinfradev/tks-api/pkg/domain" + "github.com/openinfradev/tks-api/pkg/log" + "github.com/spf13/viper" +) + +var token string + +func processClusterByoh() error { + // get clusters + clusters, err := clusterAccessor.GetBootstrappedByohClusters() + if err != nil { + return err + } + if len(clusters) == 0 { + return nil + } + log.Info("byoh clusters : ", clusters) + + token = getTksApiToken() + if token != "" { + apiClient.SetToken(token) + } + for _, cluster := range clusters { + clusterId := cluster.ID + + // check agent node + url := fmt.Sprintf("clusters/%s/nodes", clusterId) + body, err := apiClient.Get(url) + if err != nil { + log.Error(err) + continue + } + + var out domain.GetClusterNodesResponse + transcode(body, &out) + + completed := true + for _, node := range out.Nodes { + if node.Status != "COMPLETED" { + completed = false + } + } + log.Info(out.Nodes) + + //completed = true // FOR TEST + if completed { + log.Info(fmt.Sprintf("all agents registered! starting stack creation. clusterId %s", clusterId)) + // clusterId, newStatus, newMessage, workflowId + if err = clusterAccessor.UpdateClusterStatus(clusterId, domain.ClusterStatus_INSTALLING, "", ""); err != nil { + log.Error("Failed to update cluster status err : ", err) + continue + } + + if cluster.IsStack { + if _, err = apiClient.Post(fmt.Sprintf("organizations/%s/stacks/%s/install", cluster.OrganizationId, clusterId), nil); err != nil { + log.Error(err) + continue + } + } else { + if _, err = apiClient.Post("clusters/"+clusterId+"/install", nil); err != nil { + log.Error(err) + continue + } + } + + } + } + return nil +} + +func transcode(in, out interface{}) { + buf := new(bytes.Buffer) + err := json.NewEncoder(buf).Encode(in) + if err != nil { + fmt.Println(err) + } + err = json.NewDecoder(buf).Decode(out) + if err != nil { + fmt.Println(err) + } +} + +func getTksApiToken() string { + _, err := apiClient.Post("auth/ping", domain.PingTokenRequest{ + Token: token, + OrganizationId: "master", + }) + if err != nil { + body, err := apiClient.Post("auth/login", domain.LoginRequest{ + AccountId: viper.GetString("tks-api-account"), + Password: viper.GetString("tks-api-password"), + OrganizationId: "master", + }) + if err != nil { + return "" + } + + var out domain.LoginResponse + transcode(body, &out) + + log.Info(out.User.Token) + token = out.User.Token + } + + return token +} diff --git a/cmd/server/cluster_status.go b/cmd/server/cluster_status.go index d96e3e2..4f93e52 100644 --- a/cmd/server/cluster_status.go +++ b/cmd/server/cluster_status.go @@ -62,6 +62,17 @@ func processClusterStatus() error { case "Error": newStatus = domain.ClusterStatus_DELETE_ERROR } + } else if status == domain.ClusterStatus_BOOTSTRAPPING { + switch workflow.Status.Phase { + case "Running": + newStatus = domain.ClusterStatus_BOOTSTRAPPING + case "Succeeded": + newStatus = domain.ClusterStatus_BOOTSTRAPPED + case "Failed": + newStatus = domain.ClusterStatus_BOOTSTRAP_ERROR + case "Error": + newStatus = domain.ClusterStatus_BOOTSTRAP_ERROR + } } if newStatus == domain.ClusterStatus_PENDING { continue diff --git a/cmd/server/main.go b/cmd/server/main.go index e6fafc5..ea1a858 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -5,6 +5,7 @@ import ( "fmt" "time" + _apiClient "github.com/openinfradev/tks-api/pkg/api-client" argo "github.com/openinfradev/tks-api/pkg/argo-client" "github.com/openinfradev/tks-api/pkg/log" "github.com/spf13/pflag" @@ -17,7 +18,7 @@ import ( "github.com/openinfradev/tks-batch/internal/organization" ) -const INTERVAL_SEC = 1 +const INTERVAL_SEC = 5 var ( argowfClient argo.ArgoClient @@ -25,12 +26,17 @@ var ( applicationAccessor *application.ApplicationAccessor cloudAccountAccessor *cloudAccount.CloudAccountAccessor organizationAccessor *organization.OrganizationAccessor + apiClient _apiClient.ApiClient ) func init() { flag.Int("port", 9112, "service port") flag.String("argo-address", "localhost", "server address for argo-workflow-server") flag.Int("argo-port", 2746, "server port for argo-workflow-server") + flag.String("tks-api-address", "http://tks-api.tks.svc", "server address for tks-api") + flag.Int("tks-api-port", 9110, "server port number for tks-api") + flag.String("tks-api-account", "admin", "account name for tks-api") + flag.String("tks-api-password", "admin", "the password for tks-api account") flag.String("dbhost", "localhost", "host of postgreSQL") flag.String("dbport", "5432", "port of postgreSQL") @@ -68,6 +74,10 @@ func main() { if err != nil { log.Fatal("failed to create argowf client : ", err) } + apiClient, err = _apiClient.New(fmt.Sprintf("%s:%d", viper.GetString("tks-api-address"), viper.GetInt("tks-api-port"))) + if err != nil { + log.Fatal("failed to create tks-api client : ", err) + } for { err = processClusterStatus() @@ -86,6 +96,10 @@ func main() { if err != nil { log.Error(err) } + err = processClusterByoh() + if err != nil { + log.Error(err) + } time.Sleep(time.Second * INTERVAL_SEC) } diff --git a/cmd/server/server b/cmd/server/server new file mode 100755 index 0000000..cea31af Binary files /dev/null and b/cmd/server/server differ diff --git a/go.mod b/go.mod index 0a31f4f..02ba31d 100644 --- a/go.mod +++ b/go.mod @@ -28,8 +28,9 @@ require ( github.com/magiconair/properties v1.8.7 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect - github.com/openinfradev/tks-api v0.0.0-20230621070855-6fc105a25e72 // indirect + github.com/openinfradev/tks-api v0.0.0-20231023034343-1580951459e9 // indirect github.com/pelletier/go-toml/v2 v2.0.6 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/sirupsen/logrus v1.9.0 // indirect github.com/spf13/afero v1.9.3 // indirect github.com/spf13/cast v1.5.0 // indirect @@ -46,4 +47,3 @@ require ( replace github.com/openinfradev/tks-batch => ./ //replace github.com/openinfradev/tks-api => ../tks-api -//replace github.com/openinfradev/tks-proto => ./tks-proto diff --git a/go.sum b/go.sum index 14a895a..98e8662 100644 --- a/go.sum +++ b/go.sum @@ -220,10 +220,8 @@ github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyua github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/openinfradev/tks-api v0.0.0-20230524092045-07d78d318640 h1:g+vESHF0vnB5ObeTbnb/U3Dwx7kDpAuRc2ftxu/o3x4= -github.com/openinfradev/tks-api v0.0.0-20230524092045-07d78d318640/go.mod h1:FfhP5GE5TpRaHGUgTlMyxSjRsr6szNy+KhzXWBkMQ4g= -github.com/openinfradev/tks-api v0.0.0-20230621070855-6fc105a25e72 h1:07S05WaRiIXS+i4Avbavr/vAr+97IKC62/J5YcXDH+c= -github.com/openinfradev/tks-api v0.0.0-20230621070855-6fc105a25e72/go.mod h1:FfhP5GE5TpRaHGUgTlMyxSjRsr6szNy+KhzXWBkMQ4g= +github.com/openinfradev/tks-api v0.0.0-20231023034343-1580951459e9 h1:Qhly947YqvzbproX+sIAT8C4beZiJuGgFx78i0PLp2U= +github.com/openinfradev/tks-api v0.0.0-20231023034343-1580951459e9/go.mod h1:91WDknrRu9zZZ1rI1OGhj7dqqc4DQJb830y7EU5t85I= github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU= github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= diff --git a/internal/cluster/cluster.go b/internal/cluster/cluster.go index 70c06cd..6bbefec 100644 --- a/internal/cluster/cluster.go +++ b/internal/cluster/cluster.go @@ -11,10 +11,12 @@ import ( // Cluster represents a kubernetes cluster information. type Cluster struct { - ID string `gorm:"primarykey"` - WorkflowId string - Status domain.ClusterStatus - StatusDesc string + ID string `gorm:"primarykey"` + OrganizationId string + WorkflowId string + Status domain.ClusterStatus + StatusDesc string + IsStack bool } // Accessor accesses cluster info in DB. @@ -38,7 +40,21 @@ func (x *ClusterAccessor) GetIncompleteClusters() ([]Cluster, error) { var clusters []Cluster res := x.db. - Where("status IN ?", []domain.ClusterStatus{domain.ClusterStatus_INSTALLING, domain.ClusterStatus_DELETING}). + Where("status IN ?", []domain.ClusterStatus{domain.ClusterStatus_BOOTSTRAPPING, domain.ClusterStatus_INSTALLING, domain.ClusterStatus_DELETING}). + Find(&clusters) + + if res.Error != nil { + return nil, res.Error + } + + return clusters, nil +} + +func (x *ClusterAccessor) GetBootstrappedByohClusters() ([]Cluster, error) { + var clusters []Cluster + + res := x.db. + Where("cloud_service = 'BYOH' AND status IN ?", []domain.ClusterStatus{domain.ClusterStatus_BOOTSTRAPPED}). Find(&clusters) if res.Error != nil {