Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: dummy sync server #53

Merged
merged 12 commits into from
Sep 1, 2023
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
14 changes: 13 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ on:
permissions:
contents: read

env:
GO_VERSION: 1.19.3

jobs:
build:
runs-on: ubuntu-latest
Expand All @@ -27,7 +30,16 @@ jobs:
- name: Lint Gherkin
run: npm run gherkin-lint

- name: Build Docker image
- name: Build flagd-testbed Docker image
uses: docker/build-push-action@v4
with:
context: .
file: flagd/Dockerfile
push: false

- name: Build sync-testbed Docker image
uses: docker/build-push-action@v4
with:
context: .
file: sync/Dockerfile
push: false
22 changes: 18 additions & 4 deletions .github/workflows/release-please.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ permissions:

env:
REGISTRY: ghcr.io
IMAGE_NAME: flagd-testbed
FLAGD_IMAGE_NAME: flagd-testbed
SYNC_IMAGE_NAME: sync-testbed
GO_VERSION: 1.19.3

jobs:
release-please:
Expand Down Expand Up @@ -50,10 +52,22 @@ jobs:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push Docker image
- name: Build and push flagd-testbed Docker image
uses: docker/build-push-action@v4
with:
context: .
file: flagd/Dockerfile
push: true
tags: |
${{ env.REGISTRY }}/open-feature/${{ env.IMAGE_NAME }}:${{ needs.release-please.outputs.release_tag_name }}
${{ env.REGISTRY }}/open-feature/${{ env.IMAGE_NAME }}:latest
${{ env.REGISTRY }}/open-feature/${{ env.FLAGD_IMAGE_NAME }}:${{ needs.release-please.outputs.release_tag_name }}
${{ env.REGISTRY }}/open-feature/${{ env.FLAGD_IMAGE_NAME }}:latest

- name: Build and push sync-testbed Docker image
uses: docker/build-push-action@v4
with:
context: .
file: sync/Dockerfile
push: true
tags: |
${{ env.REGISTRY }}/open-feature/${{ env.SYNC_IMAGE_NAME }}:${{ needs.release-please.outputs.release_tag_name }}
${{ env.REGISTRY }}/open-feature/${{ env.SYNC_IMAGE_NAME }}:latest
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.idea
node_modules
flags/changing-flag.json
flags/changing-flag.json
bin/
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.PHONY: clean
clean:
rm -R bin/
.PHONY: build-sync
build-sync:
cd sync && go build -o ./bin/sync
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,13 @@ This repository contains a docker image to support the [gherkin suites](https://

The _flagd-testbed_ container is a docker image built on flagd, which essentially just adds a simple set of flags for the purposes of testing OpenFeature SDKs.
`testing-flags.json` contains a set of flags consistent with the [evaluation feature](https://github.com/open-feature/spec/blob/main/specification/assets/gherkin/evaluation.feature).
`change-flag.sh` runs in the test container generates a file `changing-flag.json`, which contains a flag that changes once every seconds, allowing to easily test change events.
`change-flag.sh` runs in the test container generates a file `changing-flag.json`, which contains a flag that changes once every seconds, allowing to easily test change events.

See the [flagd docs](https://flagd.dev/) for more information on flagd.

## sync-testbed container

The _sync_-testbed_ container is a docker image built on conforming to the sync.proto - a grpc which flagd or flagd in-process providers can use as a sync-source.
It features an identical set of flags to the [flagd-testbed container](#flagd-testbed-container)

For details on the sync-testbed, see [sync/README.me](sync/README.md)
4 changes: 2 additions & 2 deletions Dockerfile → flagd/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ FROM busybox:1.36

COPY --from=flagd /flagd-build /flagd
COPY flags/* .
COPY wrapper.sh .
COPY scripts/* .
LABEL org.opencontainers.image.source = "https://github.com/open-feature/test-harness"

ENTRYPOINT ["sh", "wrapper.sh"]
ENTRYPOINT ["sh", "wrapper.sh", "./flagd", "start", "-f", "file:testing-flags.json", "-f", "file:changing-flag.json"]
File renamed without changes.
8 changes: 4 additions & 4 deletions wrapper.sh → scripts/wrapper.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/bin/sh
# wrapper script to start change-flag.sh and flagd, and forward signals to the child process
# wrapper script to start change-flag.sh and flagd/sync, and forward signals to the child process

# handle SIGINTs and SIGTERMs so we can kill the container
handle_term() {
Expand All @@ -13,10 +13,10 @@ handle_int() {
trap handle_term SIGTERM
trap handle_int SIGINT

# start change script and flagd
# start change script and our server
sh ./change-flag.sh &
./flagd start -f 'file:testing-flags.json' -f 'file:changing-flag.json' &
"$@" &

# wait on flagd
# wait on server
child=$!
wait "$child"
16 changes: 16 additions & 0 deletions sync/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
FROM golang:1.21-alpine AS builder

WORKDIR /src

COPY sync .
RUN go mod download
RUN go build -o sync

FROM busybox:1.36

COPY --from=builder /src/sync .
COPY flags/* .
COPY scripts/* .
LABEL org.opencontainers.image.source = "https://github.com/open-feature/test-harness"

ENTRYPOINT ["sh", "wrapper.sh", "./sync", "start", "-f", "testing-flags.json", "-f", "changing-flag.json"]
86 changes: 86 additions & 0 deletions sync/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
## Flagd GRPC sync provider

A simple [flagd](https://github.com/open-feature/flagd) gRPC flag configuration sync source.

This implementation confirms to gPRC sync definition of flagd - https://buf.build/open-feature/flagd/docs/main:sync.v1

### How to run ?

#### go run / binary

```shell
go run main.go start -f your-flags.json
```

and then, start flagd in local mode (for example with source):

```shell
go run main.go start -f your-flags.json --uri grpc://127.0.0.1:8080 --debug
```

#### Options

Following options are available to the start command,

```text
-f string
file to watch (can be specified more than once)
-certPath string
certificate path for tls connection
-h string
hostDefault of the server (default "0.0.0.0")
-keyPath string
certificate key for tls connection
-p string
portDefault of the server (default "9090")
-s enable tls
```

For example, to start with TLS certs,

```shell
go run main.go -s=true -certPath=server.crt -keyPath=server.key
```

Then start your flagd with gRPC TLS sync.

### Running RPCs from the command line

Test the sync from the command line with [grpcurl](https://github.com/fullstorydev/grpcurl) (requires you have a copy of [sync.proto](https://raw.githubusercontent.com/open-feature/schemas/main/protobuf/sync/v1/sync_service.proto) at `/path/to/proto/dir/`):

```shell
# request all flags
grpcurl -import-path '/path/to/proto/dir' -proto sync.proto -plaintext localhost:9090 sync.v1.FlagSyncService/FetchAllFlags
```

```shell
# open a stream for getting flag changes
grpcurl -import-path '/path/to/proto/dir' -proto sync.proto -plaintext localhost:9090 sync.v1.FlagSyncService/SyncFlags
```

### Generate certificates ?

Given below are some commands you can use to generate CA cert and Server cert to used with `localhost`

#### Generate CA cert

- CA Private Key: `openssl ecparam -name prime256v1 -genkey -noout -out ca.key`
- CA Certificate: `openssl req -new -x509 -sha256 -key ca.key -out ca.cert`

#### Generate Server certificate

- Server private key: `openssl ecparam -name prime256v1 -genkey -noout -out server.key`
- Server signing request: `openssl req -new -sha256 -addext "subjectAltName=DNS:localhost" -key server.key -out server.csr`
- Server cert: `openssl x509 -req -in server.csr -CA ca.cert -CAkey ca.key -out server.crt -days 1000 -sha256 -extfile opnessl.conf`

Where the file `opnessl.conf` contains following,

`subjectAltName = DNS:localhost`

#### Running grpc server with certificates

`go run main.go -s=true -certPath=server.crt -keyPath=server.key`

#### Running flagd with certificates

`go run main.go start --sources='[{"uri":"grpcs://localhost:9090","provider":"grpc", "certPath":"ca.cert"}]'`
35 changes: 35 additions & 0 deletions sync/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
module github.com/open-feature/test-harness/sync

go 1.19

require (
buf.build/gen/go/open-feature/flagd/grpc/go v1.3.0-20230822184021-85780df4e019.1
buf.build/gen/go/open-feature/flagd/protocolbuffers/go v1.31.0-20230822184021-85780df4e019.1
github.com/fsnotify/fsnotify v1.6.0
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.43.0
go.opentelemetry.io/otel v1.17.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.17.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.17.0
go.opentelemetry.io/otel/sdk v1.17.0
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63
google.golang.org/grpc v1.57.0
)

require (
cloud.google.com/go/compute v1.23.0 // indirect
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
github.com/go-logr/logr v1.2.4 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.17.1 // indirect
go.opentelemetry.io/otel/metric v1.17.0 // indirect
go.opentelemetry.io/otel/trace v1.17.0 // indirect
go.opentelemetry.io/proto/otlp v1.0.0 // indirect
golang.org/x/net v0.14.0 // indirect
golang.org/x/sys v0.11.0 // indirect
golang.org/x/text v0.12.0 // indirect
google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect
google.golang.org/protobuf v1.31.0 // indirect
)
Loading