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
102 changes: 88 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,18 @@ been modified considerably to showcase Signadot & Sandboxes.

![image](/docs/graph.png)


## Running

First, [install Signadot Operator](https://www.signadot.com/docs/installation/signadot-operator)
if you haven't already.
Next, install and configure the [Signadot CLI](https://www.signadot.com/docs/getting-started/installation/signadot-cli).

### Run everything in Kubernetes
### Install the HotROD Application

Decide on a namespace in which to install HotROD and then run:

```sh
```bash
kubectl create ns "${NAMESPACE}"
kubectl -n "${NAMESPACE}" apply -k k8s/overlays/prod/<devmesh | istio>
```
Expand All @@ -28,28 +30,100 @@ kubectl delete ns "${NAMESPACE}"

## Development

You can easily run any of the HotROD services on your workstation by leveraging
Signadot sandboxes. Let’s walk through an example of how to do this for the
frontend application.

### Frontend

To run frontend you could easily run with `air` that helps with hot-reload.
Let's start by connecting the cluster and creating a sandbox with a local
workload. Be sure to replace `<cluster-name>` and `<namespace>` with the
appropriate values for your setup:

```bash
# Connect to the cluster
#
signadot local connect


# Create a local sandbox for the frontend app
#
signadot sandbox apply -f - <<EOF
name: local-hotrod-frontend
spec:
cluster: <cluster-name>
local:
- name: local-frontend
from:
kind: Deployment
namespace: <namespace>
name: frontend
mappings:
- port: 8080
toLocal: localhost:8080
EOF
```

Before running `air` or manual steps you have to set up the following env
```shell
export KAFKA_BROKER=kafka-headless.${NAMESPACE}.svc:9092
export REDIS_ADDR=redis.${NAMESPACE}.svc:6379
export FRONTEND_LOCATION_ADDR=location.${NAMESPACE}.svc:8081
The above sandbox ensures that any traffic within the cluster directed to
`http://frontend.<namespace>:8080` is routed to your local machine at
`localhost:8080`.

Now it's time to run the local version of the frontend application, which will
bind to `localhost:8080`.

Since the frontend depends on several other services, such as the location
service, Redis, Kafka, and others, we'll continue using the existing in-cluster
instances of these dependencies. To ensure the local frontend can seamlessly
communicate with them, we'll reuse the environment configuration from the
in-cluster baseline workload.

To load these environment variables into your local shell, run:

```bash
eval "$(signadot sandbox get-env local-hotrod-frontend)"
```

Now let's run the frontend
```shell
This command fetches and sets the necessary environment variables so your local
frontend can interact with the in-cluster services just as it would within the
cluster.

To run the frontend application locally, you have a couple of options.

If you prefer automatic hot-reloading during development, you can use `air`:

```bash
air
```

That will listen for the changes and restart the server every change.
Alternatively, you can manually build and run the frontend using the `make` and
`go run` commands:

If no want to use this approach, you could
```shell
```bash
make build-frontend-app
go run ./cmd/hotrod/main.go frontend
go run ./cmd/hotrod frontend
```

Both approaches will launch the frontend bound to `localhost:8080`, ready to
receive traffic from the Signadot sandbox.

Now you can even run Signadot Smart Tests against your local frontend to
validate its behavior in a realistic environment. For example:

```bash
signadot st run --sandbox=local-hotrod-frontend --publish
Created test run with ID "eu3o6mpz6mtc" in cluster "xrc-test".

Test run status:
✅ ...rt-tests/frontend/post-frontend-dispatch.star [ID: eu3o6mpz6mtc-1, STATUS: completed]
✅ ...hotrod/smart-tests/location/get-location.star [ID: eu3o6mpz6mtc-2, STATUS: completed]

Test run summary:
* Executions
✅ 2/2 tests completed
* Diffs
✅ No high/medium relevance differences found
* Checks
✅ 2 checks passed
```


Expand Down
17 changes: 0 additions & 17 deletions cmd/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,29 +21,12 @@ import (
var (
metricsBackend string
verbose bool

locationPort int
frontendPort int
routePort int

basePath string
baseDomain string
)

const expvarDepr = "(deprecated, will be removed after 2024-01-01 or in release v1.53.0, whichever is later) "

// used by root command
func addFlags(cmd *cobra.Command) {
cmd.PersistentFlags().StringVarP(&metricsBackend, "metrics", "m", "prometheus", expvarDepr+"Metrics backend (expvar|prometheus). ")

// Add flags to choose ports for services
cmd.PersistentFlags().IntVarP(&locationPort, "location-service-port", "c", 8081, "Port for location service")
cmd.PersistentFlags().IntVarP(&frontendPort, "frontend-service-port", "f", 8080, "Port for frontend service")
cmd.PersistentFlags().IntVarP(&routePort, "route-service-port", "r", 8083, "Port for routing service")

// Flag for serving frontend at custom basepath url
cmd.PersistentFlags().StringVarP(&basePath, "basepath", "b", "", `Basepath for frontend service(default "/")`)
cmd.PersistentFlags().StringVarP(&baseDomain, "basedomain", "B", "", `Base domain for accessing hotrod services`)

cmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "Enables debug logging")
}
37 changes: 1 addition & 36 deletions cmd/frontend.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@
package cmd

import (
"net"
"os"
"strconv"

"github.com/spf13/cobra"
"go.uber.org/zap"

Expand All @@ -33,44 +29,13 @@ var frontendCmd = &cobra.Command{
Short: "Starts Frontend service",
Long: `Starts Frontend service.`,
RunE: func(cmd *cobra.Command, args []string) error {
options.FrontendHostPort = net.JoinHostPort("0.0.0.0", strconv.Itoa(frontendPort))

options.Basepath = basePath

// Resolve services addresses
var locationHost, routeHost string
if baseDomain == "" {
locationHost = "location"
routeHost = "route"
} else {
if baseDomain == "localhost" || net.ParseIP(baseDomain) != nil {
locationHost = baseDomain
routeHost = baseDomain
} else {
locationHost = "location." + baseDomain
routeHost = "route." + baseDomain
}
}
if val := os.Getenv("FRONTEND_LOCATION_ADDR"); val != "" {
options.LocationHostPort = val
} else {
options.LocationHostPort = net.JoinHostPort(locationHost, strconv.Itoa(locationPort))
}
if val := os.Getenv("FRONTEND_ROUTE_ADDR"); val != "" {
options.RouteHostPort = val
} else {
options.RouteHostPort = net.JoinHostPort(routeHost, strconv.Itoa(routePort))
}

zapLogger := logger.With(zap.String("service", "frontend"))
logger := log.NewFactory(zapLogger)
server := frontend.NewServer(options, logger)
server := frontend.NewServer(logger)
return logError(zapLogger, server.Run())
},
}

var options frontend.ConfigOptions

func init() {
RootCmd.AddCommand(frontendCmd)
}
8 changes: 1 addition & 7 deletions cmd/location.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@
package cmd

import (
"net"
"strconv"

"github.com/spf13/cobra"
"go.uber.org/zap"

Expand All @@ -34,10 +31,7 @@ var locationCmd = &cobra.Command{
RunE: func(cmd *cobra.Command, args []string) error {
zapLogger := logger.With(zap.String("service", "location"))
logger := log.NewFactory(zapLogger)
server := location.NewServer(
net.JoinHostPort("0.0.0.0", strconv.Itoa(locationPort)),
logger,
)
server := location.NewServer(logger)
return logError(zapLogger, server.Run())
},
}
Expand Down
16 changes: 0 additions & 16 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,22 +78,6 @@ func onInitialize() {
default:
logger.Fatal("unsupported metrics backend " + metricsBackend)
}

if locationPort != 8081 {
logger.Info("changing location service port", zap.Int("old", 8081), zap.Int("new", locationPort))
}

if frontendPort != 8080 {
logger.Info("changing frontend service port", zap.Int("old", 8080), zap.Int("new", frontendPort))
}

if routePort != 8083 {
logger.Info("changing route service port", zap.Int("old", 8083), zap.Int("new", routePort))
}

if basePath != "" {
logger.Info("changing basepath for frontend", zap.String("old", "/"), zap.String("new", basePath))
}
}

func logError(logger *zap.Logger, err error) error {
Expand Down
8 changes: 1 addition & 7 deletions cmd/route.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@
package cmd

import (
"net"
"strconv"

"github.com/spf13/cobra"
"go.uber.org/zap"

Expand All @@ -34,10 +31,7 @@ var routeCmd = &cobra.Command{
RunE: func(cmd *cobra.Command, args []string) error {
zapLogger := logger.With(zap.String("service", "route"))
logger := log.NewFactory(zapLogger)
server := route.NewServer(
net.JoinHostPort("0.0.0.0", strconv.Itoa(routePort)),
logger,
)
server := route.NewServer(logger)
return logError(zapLogger, server.Run())
},
}
Expand Down
11 changes: 9 additions & 2 deletions k8s/base/driver.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ spec:
- driver
- --verbose
env:
# baseline reference
- name: SIGNADOT_BASELINE_KIND
value: Deployment
- name: SIGNADOT_BASELINE_NAMESPACE
Expand All @@ -31,15 +32,21 @@ spec:
fieldPath: metadata.namespace
- name: SIGNADOT_BASELINE_NAME
value: "driver"
# service dependencies (<NAMESPACE> get replaced at runtime by the app)
- name: SIGNADOT_ROUTESERVER
value: routeserver.signadot.svc:7777
- name: ROUTE_ADDR
value: route.<NAMESPACE>:8083
- name: REDIS_ADDR
value: redis.<NAMESPACE>:6379
- name: KAFKA_BROKER_ADDR
value: kafka-headless.<NAMESPACE>:9092
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: "http://jaeger:4318"
value: http://jaeger.<NAMESPACE>:4318
image: signadot/hotrod:latest
imagePullPolicy: Always
readinessProbe:
httpGet:
path: /healthz
port: 8082

restartPolicy: Always
10 changes: 9 additions & 1 deletion k8s/base/frontend.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ spec:
- frontend
- --verbose
env:
# baseline reference
- name: SIGNADOT_BASELINE_KIND
value: Deployment
- name: SIGNADOT_BASELINE_NAMESPACE
Expand All @@ -31,8 +32,15 @@ spec:
fieldPath: metadata.namespace
- name: SIGNADOT_BASELINE_NAME
value: "frontend"
# service dependencies (<NAMESPACE> get replaced at runtime by the app)
- name: LOCATION_ADDR
value: location.<NAMESPACE>:8081
- name: REDIS_ADDR
value: redis.<NAMESPACE>:6379
- name: KAFKA_BROKER_ADDR
value: kafka-headless.<NAMESPACE>:9092
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: "http://jaeger:4318"
value: http://jaeger.<NAMESPACE>:4318
image: signadot/hotrod:latest
imagePullPolicy: Always
ports:
Expand Down
20 changes: 11 additions & 9 deletions k8s/base/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
- mysql
- redis
- kafka
- frontend.yaml
- location.yaml
- driver.yaml
- route.yaml
- mysql
- redis
- kafka
- frontend.yaml
- location.yaml
- driver.yaml
- route.yaml

images:
- name: signadot/hotrod
newTag: latest
- name: signadot/hotrod
newTag: latest
Loading
Loading