From 7342d08fd0c4c36134fe0c1bbbf2de4fa6781fc6 Mon Sep 17 00:00:00 2001 From: Pierre Le Fevre Date: Thu, 10 Aug 2023 16:48:06 +0200 Subject: [PATCH 1/2] ping deployments --- main.go | 6 +- models/dto/body/deployment.go | 1 + models/sys/deployment/converters.go | 6 ++ models/sys/deployment/deployment.go | 4 +- models/sys/deployment/helpers.go | 21 ++++++ pkg/app/server.go | 6 ++ pkg/workers/ping/ping.go | 11 ++++ pkg/workers/ping/workers.go | 64 +++++++++++++++++++ .../deployment_service/deployment_service.go | 23 +++++++ 9 files changed, 140 insertions(+), 2 deletions(-) create mode 100644 pkg/workers/ping/ping.go create mode 100644 pkg/workers/ping/workers.go diff --git a/main.go b/main.go index c0b32842..b9c389c9 100644 --- a/main.go +++ b/main.go @@ -23,6 +23,7 @@ func main() { _ = flag.Bool("status-updater", false, "start status updater") _ = flag.Bool("job-executor", false, "start job executor") _ = flag.Bool("repairer", false, "start repairer") + _ = flag.Bool("pinger", false, "start pinger") flag.Parse() @@ -31,15 +32,17 @@ func main() { statusUpdater := isFlagPassed("status-updater") jobExecutor := isFlagPassed("job-executor") repairer := isFlagPassed("repairer") + pinger := isFlagPassed("pinger") var options *app.StartOptions - if confirmer || statusUpdater || jobExecutor || repairer || api { + if confirmer || statusUpdater || jobExecutor || repairer || api || pinger { options = &app.StartOptions{ API: api, Confirmer: confirmer, StatusUpdater: statusUpdater, JobExecutor: jobExecutor, Repairer: repairer, + Pinger: pinger, } log.Println("api: ", options.API) @@ -47,6 +50,7 @@ func main() { log.Println("status-updater: ", options.StatusUpdater) log.Println("job-executor: ", options.JobExecutor) log.Println("repairer: ", options.Repairer) + log.Println("pinger: ", options.Pinger) } else { log.Println("no workers specified, starting all") } diff --git a/models/dto/body/deployment.go b/models/dto/body/deployment.go index 2641642c..6b5c09c2 100644 --- a/models/dto/body/deployment.go +++ b/models/dto/body/deployment.go @@ -51,6 +51,7 @@ type DeploymentRead struct { Envs []Env `json:"envs"` Private bool `json:"private"` Integrations []string `json:"integrations"` + PingResult *int `json:"pingResult,omitempty"` } type CiConfig struct { diff --git a/models/sys/deployment/converters.go b/models/sys/deployment/converters.go index 2d9d4d06..5d00e41b 100644 --- a/models/sys/deployment/converters.go +++ b/models/sys/deployment/converters.go @@ -29,6 +29,11 @@ func (deployment *Deployment) ToDTO(url *string) body.DeploymentRead { integrations = append(integrations, "github") } + var pingResult *int + if deployment.PingResult != 0 { + pingResult = &deployment.PingResult + } + return body.DeploymentRead{ ID: deployment.ID, Name: deployment.Name, @@ -38,6 +43,7 @@ func (deployment *Deployment) ToDTO(url *string) body.DeploymentRead { Envs: envs, Private: deployment.Private, Integrations: integrations, + PingResult: pingResult, } } diff --git a/models/sys/deployment/deployment.go b/models/sys/deployment/deployment.go index f52951ec..7f632095 100644 --- a/models/sys/deployment/deployment.go +++ b/models/sys/deployment/deployment.go @@ -6,7 +6,7 @@ type Deployment struct { ID string `bson:"id"` Name string `bson:"name"` OwnerID string `bson:"ownerId"` - + CreatedAt time.Time `bson:"createdAt"` UpdatedAt time.Time `bson:"updatedAt"` RepairedAt time.Time `bson:"repairedAt"` @@ -20,6 +20,8 @@ type Deployment struct { Subsystems Subsystems `bson:"subsystems"` StatusCode int `bson:"statusCode"` StatusMessage string `bson:"statusMessage"` + + PingResult int `bson:"pingResult"` } func (deployment *Deployment) Ready() bool { diff --git a/models/sys/deployment/helpers.go b/models/sys/deployment/helpers.go index 49d1c09a..5408c48d 100644 --- a/models/sys/deployment/helpers.go +++ b/models/sys/deployment/helpers.go @@ -363,3 +363,24 @@ func GetLastGitLabBuild(deploymentID string) (*GitLabBuild, error) { return &deployment.Subsystems.GitLab.LastBuild, nil } + +func SavePing(id string, pingResult int) error { + updateData := bson.M{} + + models.AddIfNotNil(updateData, "pingResult", pingResult) + + if len(updateData) == 0 { + return nil + } + + _, err := models.DeploymentCollection.UpdateOne(context.TODO(), + bson.D{{"id", id}}, + bson.D{{"$set", updateData}}, + ) + if err != nil { + return fmt.Errorf("failed to update deployment ping result %s. details: %s", id, err) + } + + return nil + +} diff --git a/pkg/app/server.go b/pkg/app/server.go index 274a5ae3..c0b22ea9 100644 --- a/pkg/app/server.go +++ b/pkg/app/server.go @@ -11,6 +11,7 @@ import ( "go-deploy/pkg/sys" "go-deploy/pkg/workers/confirm" "go-deploy/pkg/workers/job_execute" + "go-deploy/pkg/workers/ping" "go-deploy/pkg/workers/repair" "go-deploy/pkg/workers/status_update" "go-deploy/routers" @@ -26,6 +27,7 @@ type StartOptions struct { StatusUpdater bool JobExecutor bool Repairer bool + Pinger bool } func shutdown() { @@ -52,6 +54,7 @@ func Start(options *StartOptions) *http.Server { StatusUpdater: true, JobExecutor: true, Repairer: true, + Pinger: true, } } @@ -67,6 +70,9 @@ func Start(options *StartOptions) *http.Server { if options.Repairer { repair.Setup(c) } + if options.Pinger { + ping.Setup(c) + } if options.API { ginMode, exists := os.LookupEnv("GIN_MODE") if exists { diff --git a/pkg/workers/ping/ping.go b/pkg/workers/ping/ping.go new file mode 100644 index 00000000..f7ea18c8 --- /dev/null +++ b/pkg/workers/ping/ping.go @@ -0,0 +1,11 @@ +package ping + +import ( + "go-deploy/pkg/sys" + "log" +) + +func Setup(ctx *sys.Context) { + log.Println("starting status updaters") + go deploymentPingUpdater(ctx) +} diff --git a/pkg/workers/ping/workers.go b/pkg/workers/ping/workers.go new file mode 100644 index 00000000..bc6084b8 --- /dev/null +++ b/pkg/workers/ping/workers.go @@ -0,0 +1,64 @@ +package ping + +import ( + deploymentModels "go-deploy/models/sys/deployment" + "go-deploy/pkg/sys" + "go-deploy/service/deployment_service" + "log" + "net/http" + "time" +) + +func deploymentPingUpdater(ctx *sys.Context) { + log.Println("starting deployment ping updater") + for { + if ctx.Stop { + break + } + + updateAllDeploymentPings() + time.Sleep(30 * time.Second) + } +} + +func updateAllDeploymentPings() { + deployments, _ := deployment_service.GetAll() + + for _, deployment := range deployments { + + url := getURL(&deployment) + + if url == nil { + log.Println("deployment has no url") + continue + } + + go updateOneDeploymentPing(&deployment, *url) + } +} + +func updateOneDeploymentPing(deployment *deploymentModels.Deployment, url string) { + code, err := ping(url) + + if err != nil { + log.Println("error fetching deployment status ping. details:", err) + } + + _ = deployment_service.SavePing(deployment.ID, code) +} + +func ping(url string) (int, error) { + resp, err := http.Get("https://" + url) + if err != nil { + return 0, err + } + + return resp.StatusCode, nil +} + +func getURL(deployment *deploymentModels.Deployment) *string { + if len(deployment.Subsystems.K8s.Ingress.Hosts) > 0 && len(deployment.Subsystems.K8s.Ingress.Hosts[0]) > 0 { + return &deployment.Subsystems.K8s.Ingress.Hosts[0] + } + return nil +} diff --git a/service/deployment_service/deployment_service.go b/service/deployment_service/deployment_service.go index 50a97d40..05052343 100644 --- a/service/deployment_service/deployment_service.go +++ b/service/deployment_service/deployment_service.go @@ -455,3 +455,26 @@ func build(deployment *deploymentModel.Deployment, params *deploymentModel.Build return nil } + +func SavePing(id string, pingResult int) error { + makeError := func(err error) error { + return fmt.Errorf("failed to update deployment with ping result. details: %s", err) + } + + deployment, err := deploymentModel.GetByID(id) + if err != nil { + return makeError(err) + } + + if deployment == nil { + log.Println("deployment", id, "not found when updating ping result. assuming it was deleted") + return nil + } + + err = deploymentModel.SavePing(id, pingResult) + if err != nil { + return makeError(err) + } + + return nil +} From 074a870d3b95980fe96110231aff320ffbff6155 Mon Sep 17 00:00:00 2001 From: saffronjam Date: Mon, 14 Aug 2023 14:48:22 +0200 Subject: [PATCH 2/2] add ping interval to config --- pkg/conf/environment.go | 1 + pkg/workers/ping/workers.go | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/pkg/conf/environment.go b/pkg/conf/environment.go index 7bec259a..0b1f03ca 100644 --- a/pkg/conf/environment.go +++ b/pkg/conf/environment.go @@ -41,6 +41,7 @@ type Environment struct { ExtraDomainIP string `yaml:"extraDomainIp"` IngressClass string `yaml:"ingressClass"` RepairInterval int `yaml:"repairInterval"` + PingInterval int `yaml:"pingInterval"` Resources struct { Limits struct { CPU string `yaml:"cpu"` diff --git a/pkg/workers/ping/workers.go b/pkg/workers/ping/workers.go index bc6084b8..02a8b9c1 100644 --- a/pkg/workers/ping/workers.go +++ b/pkg/workers/ping/workers.go @@ -2,6 +2,7 @@ package ping import ( deploymentModels "go-deploy/models/sys/deployment" + "go-deploy/pkg/conf" "go-deploy/pkg/sys" "go-deploy/service/deployment_service" "log" @@ -17,13 +18,15 @@ func deploymentPingUpdater(ctx *sys.Context) { } updateAllDeploymentPings() - time.Sleep(30 * time.Second) + time.Sleep(time.Duration(conf.Env.Deployment.PingInterval) * time.Second) } } func updateAllDeploymentPings() { deployments, _ := deployment_service.GetAll() + log.Println("pinging", len(deployments), "deployments") + for _, deployment := range deployments { url := getURL(&deployment)