diff --git a/cmd/web-api/handlers/check.go b/cmd/web-api/handlers/check.go index 35083a7..3af68ad 100644 --- a/cmd/web-api/handlers/check.go +++ b/cmd/web-api/handlers/check.go @@ -35,23 +35,23 @@ func (c *Check) Health(ctx context.Context, w http.ResponseWriter, r *http.Reque } data := struct { - Status string `json:"status"` - CiCommitRefName string `json:"ci-commit-ref-name,omitempty"` - CiCommitRefSlug string `json:"ci-commit-ref-slug,omitempty"` - CiCommitSha string `json:"ci-commit-sha,omitempty"` - CiCommitTag string `json:"ci-commit-tag,omitempty"` - CiCommitTitle string `json:"ci-commit-title,omitempty"` - CiJobId string `json:"ci-commit-job-id,omitempty"` - CiPipelineId string `json:"ci-commit-pipeline-id,omitempty"` + Status string `json:"status"` + CiCommitRefName string `json:"ci-commit-ref-name,omitempty"` + CiCommitRefSlug string `json:"ci-commit-ref-slug,omitempty"` + CiCommitSha string `json:"ci-commit-sha,omitempty"` + CiCommitTag string `json:"ci-commit-tag,omitempty"` + CiCommitTitle string `json:"ci-commit-title,omitempty"` + CiJobId string `json:"ci-commit-job-id,omitempty"` + CiPipelineId string `json:"ci-commit-pipeline-id,omitempty"` }{ - Status: "ok", + Status: "ok", CiCommitRefName: os.Getenv("CI_COMMIT_REF_NAME"), CiCommitRefSlug: os.Getenv("CI_COMMIT_REF_SLUG"), - CiCommitSha: os.Getenv("CI_COMMIT_SHA"), - CiCommitTag: os.Getenv("CI_COMMIT_TAG"), - CiCommitTitle: os.Getenv("CI_COMMIT_TITLE"), - CiJobId : os.Getenv("CI_COMMIT_JOB_ID"), - CiPipelineId: os.Getenv("CI_COMMIT_PIPELINE_ID"), + CiCommitSha: os.Getenv("CI_COMMIT_SHA"), + CiCommitTag: os.Getenv("CI_COMMIT_TAG"), + CiCommitTitle: os.Getenv("CI_COMMIT_TITLE"), + CiJobId: os.Getenv("CI_COMMIT_JOB_ID"), + CiPipelineId: os.Getenv("CI_COMMIT_PIPELINE_ID"), } return web.RespondJson(ctx, w, data, http.StatusOK) diff --git a/cmd/web-app/handlers/check.go b/cmd/web-app/handlers/check.go index f7b3c0a..879f036 100644 --- a/cmd/web-app/handlers/check.go +++ b/cmd/web-app/handlers/check.go @@ -35,23 +35,23 @@ func (c *Check) Health(ctx context.Context, w http.ResponseWriter, r *http.Reque } data := struct { - Status string `json:"status"` - CiCommitRefName string `json:"ci-commit-ref-name,omitempty"` - CiCommitRefSlug string `json:"ci-commit-ref-slug,omitempty"` - CiCommitSha string `json:"ci-commit-sha,omitempty"` - CiCommitTag string `json:"ci-commit-tag,omitempty"` - CiCommitTitle string `json:"ci-commit-title,omitempty"` - CiJobId string `json:"ci-commit-job-id,omitempty"` - CiPipelineId string `json:"ci-commit-pipeline-id,omitempty"` + Status string `json:"status"` + CiCommitRefName string `json:"ci-commit-ref-name,omitempty"` + CiCommitRefSlug string `json:"ci-commit-ref-slug,omitempty"` + CiCommitSha string `json:"ci-commit-sha,omitempty"` + CiCommitTag string `json:"ci-commit-tag,omitempty"` + CiCommitTitle string `json:"ci-commit-title,omitempty"` + CiJobId string `json:"ci-commit-job-id,omitempty"` + CiPipelineId string `json:"ci-commit-pipeline-id,omitempty"` }{ - Status: "ok", + Status: "ok", CiCommitRefName: os.Getenv("CI_COMMIT_REF_NAME"), CiCommitRefSlug: os.Getenv("CI_COMMIT_REF_SLUG"), - CiCommitSha: os.Getenv("CI_COMMIT_SHA"), - CiCommitTag: os.Getenv("CI_COMMIT_TAG"), - CiCommitTitle: os.Getenv("CI_COMMIT_TITLE"), - CiJobId : os.Getenv("CI_COMMIT_JOB_ID"), - CiPipelineId: os.Getenv("CI_COMMIT_PIPELINE_ID"), + CiCommitSha: os.Getenv("CI_COMMIT_SHA"), + CiCommitTag: os.Getenv("CI_COMMIT_TAG"), + CiCommitTitle: os.Getenv("CI_COMMIT_TITLE"), + CiJobId: os.Getenv("CI_COMMIT_JOB_ID"), + CiPipelineId: os.Getenv("CI_COMMIT_PIPELINE_ID"), } return web.RespondJson(ctx, w, data, http.StatusOK) diff --git a/cmd/web-app/handlers/root.go b/cmd/web-app/handlers/root.go index 13c0667..99d3d64 100644 --- a/cmd/web-app/handlers/root.go +++ b/cmd/web-app/handlers/root.go @@ -4,28 +4,29 @@ import ( "context" "encoding/json" "fmt" - "github.com/pkg/errors" - "github.com/sethgrid/pester" - "io/ioutil" - "net/http" "geeks-accelerator/oss/saas-starter-kit/internal/platform/auth" "geeks-accelerator/oss/saas-starter-kit/internal/platform/web" "geeks-accelerator/oss/saas-starter-kit/internal/platform/web/webcontext" project_routes "geeks-accelerator/oss/saas-starter-kit/internal/project-routes" + "github.com/ikeikeikeike/go-sitemap-generator/v2/stm" "github.com/jmoiron/sqlx" + "github.com/pkg/errors" + "github.com/sethgrid/pester" + "io/ioutil" + "net/http" ) // Root represents the Root API method handler set. type Root struct { MasterDB *sqlx.DB Renderer web.Renderer + Sitemap *stm.Sitemap ProjectRoutes project_routes.ProjectRoutes } // Index determines if the user has authentication and loads the associated page. func (h *Root) Index(ctx context.Context, w http.ResponseWriter, r *http.Request, params map[string]string) error { - if claims, err := auth.ClaimsFromContext(ctx); err == nil && claims.HasAuth() { return h.indexDashboard(ctx, w, r, params) } @@ -131,3 +132,22 @@ func (h *Root) RobotTxt(ctx context.Context, w http.ResponseWriter, r *http.Requ txt := fmt.Sprintf("User-agent: *\nDisallow: /ping\nDisallow: /status\nDisallow: /debug/\nSitemap: %s", sitemapUrl) return web.RespondText(ctx, w, txt, http.StatusOK) } + +type SiteMap struct { + Pages []SiteMapPage `json:"pages"` +} + +type SiteMapPage struct { + Loc string `json:"loc" xml:"loc"` + File string `json:"file" xml:"file"` + Changefreq string `json:"changefreq" xml:"changefreq"` + Mobile bool `json:"mobile" xml:"mobile"` + Priority float64 `json:"priority" xml:"priority"` + Lastmod string `json:"lastmod" xml:"lastmod"` +} + +// SitemapXml returns a robots.txt response. +func (h *Root) SitemapXml(ctx context.Context, w http.ResponseWriter, r *http.Request, params map[string]string) error { + w.Write(h.Sitemap.XMLContent()) + return nil +} diff --git a/cmd/web-app/handlers/routes.go b/cmd/web-app/handlers/routes.go index 79a51fb..e8e1373 100644 --- a/cmd/web-app/handlers/routes.go +++ b/cmd/web-app/handlers/routes.go @@ -6,6 +6,8 @@ import ( "log" "net/http" "os" + "path/filepath" + "time" "geeks-accelerator/oss/saas-starter-kit/internal/mid" "geeks-accelerator/oss/saas-starter-kit/internal/platform/auth" @@ -14,6 +16,7 @@ import ( "geeks-accelerator/oss/saas-starter-kit/internal/platform/web/webcontext" "geeks-accelerator/oss/saas-starter-kit/internal/platform/web/weberror" project_routes "geeks-accelerator/oss/saas-starter-kit/internal/project-routes" + "github.com/ikeikeikeike/go-sitemap-generator/v2/stm" "github.com/jmoiron/sqlx" "gopkg.in/DataDog/dd-trace-go.v1/contrib/go-redis/redis" ) @@ -40,6 +43,24 @@ func APP(shutdown chan os.Signal, log *log.Logger, env webcontext.Env, staticDir // Construct the web.App which holds all routes as well as common Middleware. app := web.NewApp(shutdown, log, env, middlewares...) + // Build a sitemap. + sm := stm.NewSitemap(1) + sm.SetDefaultHost(projectRoutes.WebAppUrl("")) + sm.Create() + + smLocAddModified := func(loc stm.URL, filename string) { + contentPath := filepath.Join(templateDir, "content", filename) + + file, err := os.Stat(contentPath) + if err != nil { + log.Fatalf("main : Add sitemap file modified for %s: %+v", filename, err) + } + + lm := []interface{}{"lastmod", file.ModTime().Format(time.RFC3339)} + loc = append(loc, lm) + sm.Add(loc) + } + // Register project management pages. p := Projects{ MasterDB: masterDB, @@ -149,6 +170,7 @@ func APP(shutdown chan os.Signal, log *log.Logger, env webcontext.Env, staticDir MasterDB: masterDB, Renderer: renderer, ProjectRoutes: projectRoutes, + Sitemap: sm, } app.Handle("GET", "/api", r.SitePage) app.Handle("GET", "/pricing", r.SitePage) @@ -158,6 +180,15 @@ func APP(shutdown chan os.Signal, log *log.Logger, env webcontext.Env, staticDir app.Handle("GET", "/", r.Index, mid.AuthenticateSessionOptional(authenticator)) app.Handle("GET", "/index.html", r.IndexHtml) app.Handle("GET", "/robots.txt", r.RobotTxt) + app.Handle("GET", "/sitemap.xml", r.SitemapXml) + + // Add sitemap entries for Root. + smLocAddModified(stm.URL{{"loc", "/"}, {"changefreq", "weekly"}, {"mobile", true}, {"priority", 0.9}}, "site-index.gohtml") + smLocAddModified(stm.URL{{"loc", "/pricing"}, {"changefreq", "monthly"}, {"mobile", true}, {"priority", 0.8}}, "site-pricing.gohtml") + smLocAddModified(stm.URL{{"loc", "/support"}, {"changefreq", "monthly"}, {"mobile", true}, {"priority", 0.8}}, "site-support.gohtml") + smLocAddModified(stm.URL{{"loc", "/api"}, {"changefreq", "monthly"}, {"mobile", true}, {"priority", 0.7}}, "site-api.gohtml") + smLocAddModified(stm.URL{{"loc", "/legal/privacy"}, {"changefreq", "monthly"}, {"mobile", true}, {"priority", 0.5}}, "legal-privacy.gohtml") + smLocAddModified(stm.URL{{"loc", "/legal/terms"}, {"changefreq", "monthly"}, {"mobile", true}, {"priority", 0.5}}, "legal-terms.gohtml") // Register health check endpoint. This route is not authenticated. check := Check{ diff --git a/cmd/web-app/main.go b/cmd/web-app/main.go index 4832787..0b1a648 100644 --- a/cmd/web-app/main.go +++ b/cmd/web-app/main.go @@ -542,7 +542,7 @@ func main() { return f.String() }, "SiteBaseUrl": func(p string) string { - u, err := url.Parse(cfg.HTTP.Host) + u, err := url.Parse(cfg.Service.BaseUrl) if err != nil { return "?" } diff --git a/cmd/web-app/templates/content/sitemap.xml b/cmd/web-app/templates/content/sitemap.xml deleted file mode 100644 index cc8b8ce..0000000 --- a/cmd/web-app/templates/content/sitemap.xml +++ /dev/null @@ -1,44 +0,0 @@ - - - - weekly - site-index.gohtml - 0.9 - - - - /pricing - monthly - site-pricing.gohtml - 0.8 - - - - /support - monthly - site-support.gohtml - 0.8 - - - - /api - monthly - site-api.gohtml - 0.7 - - - - /legal/privacy - monthly - legal-privacy.gohtml - 0.6 - - - - /legal/terms - monthly - legal-privacy.gohtml - 0.6 - - - \ No newline at end of file diff --git a/go.mod b/go.mod index eb93b75..91f58a2 100644 --- a/go.mod +++ b/go.mod @@ -24,6 +24,7 @@ require ( github.com/gorilla/sessions v1.2.0 github.com/huandu/go-sqlbuilder v1.4.1 github.com/iancoleman/strcase v0.0.0-20190422225806-e506e3ef7365 + github.com/ikeikeikeike/go-sitemap-generator/v2 v2.0.2 github.com/jmoiron/sqlx v1.2.0 github.com/kelseyhightower/envconfig v1.4.0 github.com/kr/pty v1.1.8 // indirect diff --git a/go.sum b/go.sum index 97c49a3..d297042 100644 --- a/go.sum +++ b/go.sum @@ -10,7 +10,10 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafo github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/aws/aws-sdk-go v1.21.8 h1:Lv6hW2twBhC6mGZAuWtqplEpIIqtVctJg02sE7Qn0Zw= github.com/aws/aws-sdk-go v1.21.8/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/beevik/etree v1.1.0 h1:T0xke/WvNtMoCqgzPhkX2r4rjY3GDZFi+FjpRZY2Jbs= +github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A= github.com/bobesa/go-domain-util v0.0.0-20180815122459-1d708c097a6a/go.mod h1:/mf0HzRK9xVv+1puqGSMzCo7bhEcQhiisuUXlMkq2p4= +github.com/clbanning/mxj v1.8.3/go.mod h1:BVjHeAH+rl9rs6f+QIpeRl0tfu10SXn1pUSa5PVGJng= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -24,6 +27,7 @@ github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4 github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8= github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/fatih/structtag v1.0.0 h1:pTHj65+u3RKWYPSGaU290FpI/dXxTaHdVwVwbcPKmEc= github.com/fatih/structtag v1.0.0/go.mod h1:IKitwq45uXL/yqi5mYghiD3w9H6eTOvI9vnk8tXMphA= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= @@ -83,6 +87,8 @@ github.com/huandu/go-sqlbuilder v1.4.1 h1:DYGFGLbOUXhtQ2kwO1uyDIPJbsztmVWdPPDyxi github.com/huandu/go-sqlbuilder v1.4.1/go.mod h1:mYfGcZTUS6yJsahUQ3imkYSkGGT3A+owd54+79kkW+U= github.com/iancoleman/strcase v0.0.0-20190422225806-e506e3ef7365 h1:ECW73yc9MY7935nNYXUkK7Dz17YuSUI9yqRqYS8aBww= github.com/iancoleman/strcase v0.0.0-20190422225806-e506e3ef7365/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE= +github.com/ikeikeikeike/go-sitemap-generator/v2 v2.0.2 h1:wIdDEle9HEy7vBPjC6oKz6ejs3Ut+jmsYvuOoAW2pSM= +github.com/ikeikeikeike/go-sitemap-generator/v2 v2.0.2/go.mod h1:WtaVKD9TeruTED9ydiaOJU08qGoEPP/LyzTKiD3jEsw= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmoiron/sqlx v1.2.0 h1:41Ip0zITnmWNR/vHV+S4m+VoUivnWY5E4OJfLZjCJMA= diff --git a/tools/devops/cmd/cicd/service_build.go b/tools/devops/cmd/cicd/service_build.go index 63c7625..8834e0c 100644 --- a/tools/devops/cmd/cicd/service_build.go +++ b/tools/devops/cmd/cicd/service_build.go @@ -234,9 +234,9 @@ func ServiceBuild(log *log.Logger, req *serviceBuildRequest) error { } buildStageName = strings.TrimSpace(strings.Split(lineLower, " as ")[1]) - stageLines = append(stageLines, line ) + stageLines = append(stageLines, line) } else if buildStageName != "" { - stageLines = append(stageLines, line ) + stageLines = append(stageLines, line) } } @@ -288,7 +288,7 @@ func ServiceBuild(log *log.Logger, req *serviceBuildRequest) error { buildBaseImage = os.Getenv("CI_REGISTRY_IMAGE") + ":" + buildBaseImageTag pushTargetImg = true } else { - buildBaseImage = req.ProjectName + ":" + req.Env + "-" +req.ServiceName + "-" + buildBaseImageTag + buildBaseImage = req.ProjectName + ":" + req.Env + "-" + req.ServiceName + "-" + buildBaseImageTag } cmds = append(cmds, []string{"docker", "pull", buildBaseImageTag}) @@ -341,7 +341,7 @@ func ServiceBuild(log *log.Logger, req *serviceBuildRequest) error { err = execCmds(log, req.ProjectRoot, cmd) if err != nil { if len(cmd) > 2 && cmd[1] == "pull" { - log.Printf("\t\t\tSkipping pull - %s\n", err.Error()) + log.Printf("\t\t\tSkipping pull - %s\n", err.Error()) } else { return errors.Wrapf(err, "Failed to exec %s", strings.Join(cmd, " ")) } diff --git a/tools/devops/cmd/cicd/service_deploy.go b/tools/devops/cmd/cicd/service_deploy.go index bcde41a..c67238c 100644 --- a/tools/devops/cmd/cicd/service_deploy.go +++ b/tools/devops/cmd/cicd/service_deploy.go @@ -2552,8 +2552,6 @@ func ServiceDeploy(log *log.Logger, req *serviceDeployRequest) error { pks = append(pks, k) } - - // Read the defined json task definition. dat, err := EcsReadTaskDefinition(req.ServiceDir, req.Env) if err != nil { @@ -2602,13 +2600,13 @@ func ServiceDeploy(log *log.Logger, req *serviceDeployRequest) error { replaced := make(map[string]bool) for _, m := range matches { - m = strings.Trim(m, "{}") if replaced[m] { continue } replaced[m] = true - newVal := os.Getenv(m) + envKey := strings.Trim(m, "{}") + newVal := os.Getenv(envKey) log.Printf("\t\t\t%s -> %s", m, newVal) jsonStr = strings.Replace(jsonStr, m, newVal, -1) }