1
0
mirror of https://github.com/raseels-repos/golang-saas-starter-kit.git synced 2025-06-17 00:17:59 +02:00
Files

105 lines
2.9 KiB
Go
Raw Permalink Normal View History

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)
}