You've already forked golang-saas-starter-kit
mirror of
https://github.com/raseels-repos/golang-saas-starter-kit.git
synced 2025-06-17 00:17:59 +02:00
105 lines
2.9 KiB
Go
105 lines
2.9 KiB
Go
![]() |
package handlers
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"net/http"
|
||
|
"net/url"
|
||
|
|
||
|
"geeks-accelerator/oss/saas-starter-kit/internal/mid"
|
||
|
"geeks-accelerator/oss/saas-starter-kit/internal/platform/web"
|
||
|
"github.com/aws/aws-sdk-go/aws"
|
||
|
"github.com/aws/aws-sdk-go/aws/session"
|
||
|
"github.com/aws/aws-sdk-go/service/rds"
|
||
|
"github.com/jmoiron/sqlx"
|
||
|
"github.com/pkg/errors"
|
||
|
)
|
||
|
|
||
|
// Serverless provides support for ensuring serverless resources are available for the user. .
|
||
|
type Serverless struct {
|
||
|
Renderer web.Renderer
|
||
|
MasterDB *sqlx.DB
|
||
|
MasterDbHost string
|
||
|
AwsSession *session.Session
|
||
|
}
|
||
|
|
||
|
// WaitDb validates the the database is resumed and ready to accept requests.
|
||
|
func (h *Serverless) Pending(ctx context.Context, w http.ResponseWriter, r *http.Request, params map[string]string) error {
|
||
|
|
||
|
var redirectUri string
|
||
|
if v, ok := ctx.Value(mid.ServerlessKey).(error); ok && v != nil {
|
||
|
redirectUri = r.RequestURI
|
||
|
} else {
|
||
|
redirectUri = r.URL.Query().Get("redirect")
|
||
|
}
|
||
|
|
||
|
if redirectUri == "" {
|
||
|
redirectUri = "/"
|
||
|
}
|
||
|
|
||
|
f := func() (bool, error) {
|
||
|
svc := rds.New(h.AwsSession)
|
||
|
|
||
|
res, err := svc.DescribeDBClusters(&rds.DescribeDBClustersInput{})
|
||
|
if err != nil {
|
||
|
return false, errors.WithMessage(err, "Failed to list AWS db clusters.")
|
||
|
}
|
||
|
|
||
|
var targetCluster *rds.DBCluster
|
||
|
for _, c := range res.DBClusters {
|
||
|
if c.Endpoint == nil || *c.Endpoint != h.MasterDbHost {
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
targetCluster = c
|
||
|
}
|
||
|
|
||
|
if targetCluster == nil {
|
||
|
return false, errors.New("Failed to find database cluster.")
|
||
|
} else if targetCluster.ScalingConfigurationInfo == nil || targetCluster.ScalingConfigurationInfo.MinCapacity == nil {
|
||
|
return false, errors.New("Database cluster has now scaling configuration.")
|
||
|
}
|
||
|
|
||
|
if targetCluster.Capacity != nil && *targetCluster.Capacity > 0 {
|
||
|
return true, nil
|
||
|
}
|
||
|
|
||
|
_, err = svc.ModifyCurrentDBClusterCapacity(&rds.ModifyCurrentDBClusterCapacityInput{
|
||
|
DBClusterIdentifier: targetCluster.DBClusterIdentifier,
|
||
|
Capacity: targetCluster.ScalingConfigurationInfo.MinCapacity,
|
||
|
SecondsBeforeTimeout: aws.Int64(10),
|
||
|
TimeoutAction: aws.String("ForceApplyCapacityChange"),
|
||
|
})
|
||
|
if err != nil {
|
||
|
return false, err
|
||
|
}
|
||
|
|
||
|
return false, nil
|
||
|
}
|
||
|
|
||
|
end, err := f()
|
||
|
if err != nil {
|
||
|
return web.RenderError(ctx, w, r, err, h.Renderer, TmplLayoutBase, TmplContentErrorGeneric, web.MIMETextHTMLCharsetUTF8)
|
||
|
}
|
||
|
|
||
|
if web.RequestIsJson(r) {
|
||
|
data := map[string]interface{}{
|
||
|
"redirectUri": redirectUri,
|
||
|
"statusCode": http.StatusServiceUnavailable,
|
||
|
}
|
||
|
if end {
|
||
|
data["statusCode"] = http.StatusOK
|
||
|
}
|
||
|
return web.RespondJson(ctx, w, data, http.StatusOK)
|
||
|
}
|
||
|
|
||
|
if end {
|
||
|
// Redirect the user to their requested page.
|
||
|
return web.Redirect(ctx, w, r, redirectUri, http.StatusFound)
|
||
|
}
|
||
|
|
||
|
data := map[string]interface{}{
|
||
|
"statusUrl": "/serverless/pending?redirect=" + url.QueryEscape(redirectUri),
|
||
|
}
|
||
|
return h.Renderer.Render(ctx, w, r, TmplLayoutBase, "serverless-db.gohtml", web.MIMETextHTMLCharsetUTF8, http.StatusOK, data)
|
||
|
}
|