Skip to content

Commit

Permalink
Support running Go with certs
Browse files Browse the repository at this point in the history
  • Loading branch information
bergundy committed Sep 7, 2022
1 parent b27ddab commit 0eacecc
Show file tree
Hide file tree
Showing 8 changed files with 110 additions and 16 deletions.
41 changes: 36 additions & 5 deletions .github/workflows/docker-images.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ on: # rebuild any PRs and main branch changes
jobs:
build-images:
runs-on: ubuntu-latest
env:
# TODO(bergundy): get a permanent cloud namespace
TEMPORAL_CLOUD_ADDRESS: roey.temporal-dev.tmprl.cloud:7233
TEMPORAL_CLOUD_NAMESPACE: roey.temporal-dev
# For some reason this needs to be set globally ¯\_(ツ)_/¯
TEMPORAL_CLIENT_CERT: ${{ secrets.TEMPORAL_CLIENT_CERT }}
TEMPORAL_CLIENT_KEY: ${{ secrets.TEMPORAL_CLIENT_KEY }}
steps:
- name: Print build information
run: 'echo head_ref: ${{ github.head_ref }}, ref: ${{ github.ref }}, os: ${{ matrix.os }}'
Expand All @@ -18,15 +25,39 @@ jobs:
go-version: '^1.17'
- name: Lint go docker image
run: docker run --rm -i hadolint/hadolint < dockerfiles/go.Dockerfile

# Downlad the certs to be mounted as a volume in the running container
- run: mkdir /tmp/temporal-certs
- run: echo "$TEMPORAL_CLIENT_CERT" > /tmp/temporal-certs/client.pem
- run: echo "$TEMPORAL_CLIENT_KEY" > /tmp/temporal-certs/client.key

# Just see if it runs for now, not publishing yet
# TODO(bergundy): run these in parallel
# TODO(bergundy): run against a cloud namespace

- name: Build go master image
run: go run . build-image --lang go --repo-ref master
- name: Run go master image
run: docker run --rm -i sdk-features:go-master
- name: Run go master image against Temporalite
run: docker run --rm -i -v /tmp/temporal-certs:/certs sdk-features:go-master
- name: Run go master image against Cloud
run: |
docker run --rm -i -v /tmp/temporal-certs:/certs sdk-features:go-master \
--server $TEMPORAL_CLOUD_ADDRESS \
--namespace $TEMPORAL_CLOUD_NAMESPACE \
--client-cert-path /certs/client.pem \
--client-key-path /certs/client.key
# Latest release at the time this was written
# TODO(bergundy): Find some way to automatically upgrade to "latest"
- name: Build go 1.16 image
run: go run . build-image --lang go --version v1.16
- name: Run go 1.16 image
run: docker run --rm -i sdk-features:go-1.16.0
- name: Run go 1.16 image against Temporalite
run: docker run --rm -i -v /tmp/temporal-certs:/certs sdk-features:go-1.16.0
- name: Run go 1.16 image against Cloud
run: |
docker run --rm -i -v /tmp/temporal-certs:/certs sdk-features:go-1.16.0 \
--server $TEMPORAL_CLOUD_ADDRESS \
--namespace $TEMPORAL_CLOUD_NAMESPACE \
--client-cert-path /certs/client.pem \
--client-key-path /certs/client.key
# TODO(bergundy): create a docker push step
7 changes: 5 additions & 2 deletions cmd/build_image.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,11 @@ func (i *ImageBuilder) buildFromRepo(ctx context.Context) error {
tags := []string{fmt.Sprintf("%s-%s", i.config.Lang, i.config.RepoRef)}

return i.dockerBuild(ctx, buildConfig{
tags: tags,
labels: map[string]string{"SDK_REPO_URL": i.config.RepoURL, "SDK_REPO_REF": repoRef},
tags: tags,
labels: map[string]string{
"SDK_REPO_URL": i.config.RepoURL,
"SDK_REPO_REF": repoRef,
},
buildArgs: map[string]string{"SDK_VERSION": repoDir, "REPO_DIR_OR_PLACEHOLDER": repoDir},
})
}
Expand Down
37 changes: 32 additions & 5 deletions cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cmd

import (
"context"
"crypto/tls"
"encoding/json"
"fmt"
"os"
Expand Down Expand Up @@ -40,6 +41,8 @@ type RunConfig struct {
PrepareConfig
Server string
Namespace string
ClientCertPath string
ClientKeyPath string
GenerateHistory bool
DisableHistoryCheck bool
RetainTempDir bool
Expand Down Expand Up @@ -74,6 +77,16 @@ func (r *RunConfig) flags() []cli.Flag {
Usage: "The namespace to use (default is random)",
Destination: &r.Namespace,
},
&cli.StringFlag{
Name: "client-cert-path",
Usage: "Path of TLS client cert to use (optional)",
Destination: &r.ClientCertPath,
},
&cli.StringFlag{
Name: "client-key-path",
Usage: "Path of TLS client key to use (optional)",
Destination: &r.ClientKeyPath,
},
&cli.BoolFlag{
Name: "retain-temp-dir",
Usage: "Do not delete the temp directory after the run",
Expand Down Expand Up @@ -195,11 +208,16 @@ func (r *Runner) Run(ctx context.Context, patterns []string) error {
err = nil
switch r.config.Lang {
case "go":
// If there's a version we run external, otherwise we run local
if r.config.Version != "" {
// If there's a version or prepared dir we run external, otherwise we run local
if r.config.Version != "" || r.config.Dir != "" {
err = r.RunGoExternal(ctx, run)
} else {
err = cmd.NewRunner(cmd.RunConfig{Server: r.config.Server, Namespace: r.config.Namespace}).Run(ctx, run)
err = cmd.NewRunner(cmd.RunConfig{
Server: r.config.Server,
Namespace: r.config.Namespace,
ClientCertPath: r.config.ClientCertPath,
ClientKeyPath: r.config.ClientKeyPath,
}).Run(ctx, run)
}
case "java":
err = r.RunJavaExternal(ctx, run)
Expand All @@ -219,11 +237,20 @@ func (r *Runner) Run(ctx context.Context, patterns []string) error {
}

func (r *Runner) handleHistory(ctx context.Context, run *cmd.Run) error {
cl, err := client.NewClient(client.Options{
opts := client.Options{
HostPort: r.config.Server,
Namespace: r.config.Namespace,
Logger: log.NewSdkLogger(r.log),
})
}
if r.config.ClientCertPath != "" {
cert, err := tls.LoadX509KeyPair(r.config.ClientCertPath, r.config.ClientKeyPath)
if err != nil {
return fmt.Errorf("failed to load certs: %s", err)
}
opts.ConnectionOptions.TLS = &tls.Config{Certificates: []tls.Certificate{cert}}
}

cl, err := client.NewClient(opts)
if err != nil {
return fmt.Errorf("failed creating client: %w", err)
}
Expand Down
2 changes: 2 additions & 0 deletions cmd/run_go.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ func (r *Runner) RunGoExternal(ctx context.Context, run *cmd.Run) error {
"run",
"--server", r.config.Server,
"--namespace", r.config.Namespace,
"--client-cert-path", r.config.ClientCertPath,
"--client-key-path", r.config.ClientKeyPath,
}, run.ToArgs()...)
r.log.Debug("Running Go separately", tag.NewStringsTag("Args", runArgs))
goCmd := exec.CommandContext(ctx, filepath.Join(r.config.Dir, exe), runArgs...)
Expand Down
5 changes: 3 additions & 2 deletions dockerfiles/go.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@ ARG REPO_DIR_OR_PLACEHOLDER
COPY ./${REPO_DIR_OR_PLACEHOLDER} ./${REPO_DIR_OR_PLACEHOLDER}

# Prepare the feature for running
RUN ./sdk-features prepare --lang go --dir prepared --version "$SDK_VERSION"
RUN CGO_ENABLED=0 ./sdk-features prepare --lang go --dir prepared --version "$SDK_VERSION"

# Copy the CLI and prepared feature to a distroless "run" container
FROM gcr.io/distroless/static-debian11:nonroot

COPY --from=build /app/sdk-features /app/sdk-features
COPY --from=build /app/features /app/features
COPY --from=build /app/prepared /app/prepared
CMD ["/app/sdk-features", "run", "--lang", "go", "--prepared-dir", "prepared"]
# # Use entrypoint instead of command to "bake" the default command options
ENTRYPOINT ["/app/sdk-features", "run", "--lang", "go", "--prepared-dir", "prepared"]
18 changes: 16 additions & 2 deletions harness/go/cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,10 @@ type RunFeature struct {

// RunConfig is configuration for NewRunner.
type RunConfig struct {
Server string
Namespace string
Server string
Namespace string
ClientCertPath string
ClientKeyPath string
}

func (r *RunConfig) flags() []cli.Flag {
Expand All @@ -77,6 +79,16 @@ func (r *RunConfig) flags() []cli.Flag {
Usage: "The namespace to use (default is random)",
Destination: &r.Namespace,
},
&cli.StringFlag{
Name: "client-cert-path",
Usage: "Path of TLS client cert to use (optional)",
Destination: &r.ClientCertPath,
},
&cli.StringFlag{
Name: "client-key-path",
Usage: "Path of TLS client key to use (optional)",
Destination: &r.ClientKeyPath,
},
}
}

Expand Down Expand Up @@ -127,6 +139,8 @@ func (r *Runner) Run(ctx context.Context, run *Run) error {
runnerConfig := harness.RunnerConfig{
ServerHostPort: r.config.Server,
Namespace: r.config.Namespace,
ClientCertPath: r.config.ClientCertPath,
ClientKeyPath: r.config.ClientKeyPath,
TaskQueue: runFeature.TaskQueue,
Log: r.log,
}
Expand Down
15 changes: 15 additions & 0 deletions harness/go/harness/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package harness

import (
"context"
"crypto/tls"
"errors"
"fmt"
"path/filepath"
Expand Down Expand Up @@ -38,6 +39,8 @@ type RunnerConfig struct {
ServerHostPort string
Namespace string
TaskQueue string
ClientCertPath string
ClientKeyPath string
Log log.Logger
}

Expand Down Expand Up @@ -72,6 +75,18 @@ func NewRunner(config RunnerConfig, feature *PreparedFeature) (*Runner, error) {
if r.Feature.ClientOptions.Logger == nil {
r.Feature.ClientOptions.Logger = r.Log
}
if config.ClientCertPath != "" {
if config.ClientKeyPath == "" {
return nil, errors.New("got TLS cert with no key")
}
cert, err := tls.LoadX509KeyPair(config.ClientCertPath, config.ClientKeyPath)
if err != nil {
return nil, fmt.Errorf("failed to load certs: %s", err)
}
r.Feature.ClientOptions.ConnectionOptions.TLS = &tls.Config{Certificates: []tls.Certificate{cert}}
} else if config.ClientKeyPath != "" {
return nil, errors.New("got TLS key with no cert")
}

var err error
if r.Client, err = client.NewClient(r.Feature.ClientOptions); err != nil {
Expand Down
1 change: 1 addition & 0 deletions harness/go/history/history.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ func scrubRunSpecificScalars(v interface{}) {
// keeping same namespaces the same fixed value?
v.Namespace = ""
case *history.HistoryEvent:
v.Version = 0 // This field is undocumented but seems to depend on server version, ignore it
v.EventTime = nil
v.TaskId = 0
case *history.WorkflowExecutionStartedEventAttributes:
Expand Down

0 comments on commit 0eacecc

Please sign in to comment.