Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ jobs:
with:
fetch-depth: 0
- name: build
env:
GITHUB_TOKEN: ${{ secrets.WGE_NPM_GITHUB_TOKEN }}
run: |
make GITHUB_BUILD_TOKEN=${GITHUB_BUILD_TOKEN} cmd/clusters-service/.uptodate
- name: Login to Docker Hub
Expand Down
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ cmd/event-writer/$(UPTODATE): cmd/event-writer/Dockerfile cmd/event-writer/*

# Takes precedence over the more general rule above
# The only difference is the build context
cmd/clusters-service/$(UPTODATE): cmd/clusters-service/Dockerfile cmd/clusters-service/*
cmd/clusters-service/$(UPTODATE): cmd/clusters-service/Dockerfile cmd/clusters-service/* ui-cra/build
$(SUDO) docker build \
--build-arg=version=$(WEAVE_GITOPS_VERSION) \
--build-arg=image_tag=$(IMAGE_TAG) \
Expand Down Expand Up @@ -169,6 +169,10 @@ ui-audit:
lint:
bin/go-lint

cmd/clusters-service/clusters-service: ui-cra/build
CGO_ENABLED=1 GOARCH=amd64 go build -ldflags "$(cgo_ldflags)" -o $@ ./cmd/gitops-repo-broker
cp -r ui-cra/build/* cmd/clusters-service/app/dist/

# We select which directory we want to descend into to not execute integration
# tests here.
unit-tests-with-coverage: $(GENERATED)
Expand Down
1 change: 1 addition & 0 deletions cmd/clusters-service/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ COPY cmd/clusters-service/main.go main.go
COPY cmd/clusters-service/api/ api/
COPY cmd/clusters-service/app/ app/
COPY cmd/clusters-service/pkg/ pkg/
COPY ui-cra/build app/dist

ARG version
# build
Expand Down
Empty file.
91 changes: 83 additions & 8 deletions cmd/clusters-service/app/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ package app

import (
"context"
"embed"
"encoding/json"
"errors"
"fmt"
"io/fs"
"net/http"
"os"
"os/signal"
"path/filepath"
"strings"
"syscall"

Expand All @@ -16,6 +19,7 @@ import (
"github.com/go-playground/validator/v10"
"github.com/gorilla/mux"
grpc_runtime "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/spf13/viper"
Expand Down Expand Up @@ -323,7 +327,23 @@ func RunInProcessGateway(ctx context.Context, addr string, setters ...Option) er
httpHandler = entitlement.EntitlementHandler(ctx, args.Log, args.KubernetesClient, args.EntitlementSecretKey, entitlement.CheckEntitlementHandler(args.Log, httpHandler))

gitopsBrokerHandler := getGitopsBrokerMux(args.AgentTemplateNatsURL, args.AgentTemplateAlertmanagerURL, args.Database)
mux.Handle("/gitops/", gitopsBrokerHandler)
mux.Handle("/gitops/api/", gitopsBrokerHandler)

// UI
var log = logrus.New()
assetFS := getAssets()
assetHandler := http.FileServer(http.FS(assetFS))
redirector := createRedirector(assetFS, log)

mux.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
extension := filepath.Ext(req.URL.Path)

if extension == "" {
redirector(w, req)
return
}
assetHandler.ServeHTTP(w, req)
}))

s := &http.Server{
Addr: addr,
Expand Down Expand Up @@ -428,13 +448,68 @@ func checkVersionWithFlags(log logr.Logger, flags map[string]string) {
func getGitopsBrokerMux(agentTemplateNatsURL, agentTemplateAlertmanagerURL string, db *gorm.DB) *mux.Router {
r := mux.NewRouter()

r.HandleFunc("/agent.yaml", agent.NewGetHandler(db, agentTemplateNatsURL, agentTemplateAlertmanagerURL)).Methods("GET")
r.HandleFunc("/clusters", api.ListClusters(db, json.MarshalIndent)).Methods("GET")
r.HandleFunc("/clusters/{id:[0-9]+}", api.FindCluster(db, json.MarshalIndent)).Methods("GET")
r.HandleFunc("/clusters", api.RegisterCluster(db, validator.New(), json.Unmarshal, json.MarshalIndent, utils.Generate)).Methods("POST")
r.HandleFunc("/clusters/{id:[0-9]+}", api.UpdateCluster(db, validator.New(), json.Unmarshal, json.MarshalIndent)).Methods("PUT")
r.HandleFunc("/clusters/{id:[0-9]+}", api.UnregisterCluster(db)).Methods("DELETE")
r.HandleFunc("/alerts", api.ListAlerts(db, json.MarshalIndent)).Methods("GET")
r.HandleFunc("/gitops/api/agent.yaml", agent.NewGetHandler(db, agentTemplateNatsURL, agentTemplateAlertmanagerURL)).Methods("GET")
r.HandleFunc("/gitops/api/clusters", api.ListClusters(db, json.MarshalIndent)).Methods("GET")
r.HandleFunc("/gitops/api/clusters/{id:[0-9]+}", api.FindCluster(db, json.MarshalIndent)).Methods("GET")
r.HandleFunc("/gitops/api/clusters", api.RegisterCluster(db, validator.New(), json.Unmarshal, json.MarshalIndent, utils.Generate)).Methods("POST")
r.HandleFunc("/gitops/api/clusters/{id:[0-9]+}", api.UpdateCluster(db, validator.New(), json.Unmarshal, json.MarshalIndent)).Methods("PUT")
r.HandleFunc("/gitops/api/clusters/{id:[0-9]+}", api.UnregisterCluster(db)).Methods("DELETE")
r.HandleFunc("/gitops/api/alerts", api.ListAlerts(db, json.MarshalIndent)).Methods("GET")

return r
}

//go:embed dist/*
var static embed.FS

func getAssets() fs.FS {
f, err := fs.Sub(static, "dist")

if err != nil {
panic(err)
}

return f
}

// A redirector ensures that index.html always gets served.
// The JS router will take care of actual navigation once the index.html page lands.
func createRedirector(fsys fs.FS, log logrus.FieldLogger) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
indexPage, err := fsys.Open("index.html")

if err != nil {
log.Error(err, "could not open index.html page")
w.WriteHeader(http.StatusInternalServerError)

return
}

stat, err := indexPage.Stat()
if err != nil {
log.Error(err, "could not get index.html stat")
w.WriteHeader(http.StatusInternalServerError)

return
}

bt := make([]byte, stat.Size())
_, err = indexPage.Read(bt)

if err != nil {
log.Error(err, "could not read index.html")
w.WriteHeader(http.StatusInternalServerError)

return
}

_, err = w.Write(bt)

if err != nil {
log.Error(err, "error writing index.html")
w.WriteHeader(http.StatusInternalServerError)

return
}
}
}