Skip to content

Commit

Permalink
Cloud Run
Browse files Browse the repository at this point in the history
  • Loading branch information
timburks committed Mar 10, 2020
1 parent fbe181b commit 1b41dec
Show file tree
Hide file tree
Showing 7 changed files with 147 additions and 17 deletions.
25 changes: 25 additions & 0 deletions .gcloudignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# This file specifies files that are *not* uploaded to Google Cloud Platform
# using gcloud. It follows the same syntax as .gitignore, with the addition of
# "#!include" directives (which insert the entries of the given .gitignore-style
# file at that point).
#
# For more information, run:
# $ gcloud topic gcloudignore
#
.gcloudignore
# If you would like to upload your .git directory, .gitignore file or files
# from your .gitignore file, remove the corresponding line
# below:
.git
.gitignore

# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
# Test binary, build with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
30 changes: 30 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Use the official Golang image to create a build artifact.
# This is based on Debian and sets the GOPATH to /go.
# https://hub.docker.com/_/golang
FROM golang:1.13 as builder

# Create and change to the app directory.
WORKDIR /app

# Retrieve application dependencies.
# This allows the container build to reuse cached dependencies.
COPY go.* ./
RUN go mod download

# Copy local code to the container image.
COPY . ./

# Build the binary.
RUN CGO_ENABLED=0 GOOS=linux go build -mod=readonly -v -o flamed ./cmd/flamed

# Use the official Alpine image for a lean production container.
# https://hub.docker.com/_/alpine
# https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds
FROM alpine:3
RUN apk add --no-cache ca-certificates

# Copy the binary to the production image from the builder stage.
COPY --from=builder /app/flamed /flamed

# Run the web service on container startup.
CMD ["/flamed"]
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,9 @@ test:

clean:
rm -rf cmd/cli gapic rpc third_party/api-common-protos envoy/proto.pb

build:
gcloud builds submit --tag gcr.io/${FLAME_PROJECT_IDENTIFIER}/flame

run:
gcloud run deploy --image gcr.io/${FLAME_PROJECT_IDENTIFIER}/flame --platform managed
33 changes: 33 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,35 @@
# FLAME Reference Implementation

This directory contains a reference implementation of the FLAME
(Full Lifecycle API Management) API.

The reference implementation is written in Go.
It stores data using the [Google Cloud Datastore API]()
and can be deployed in a container using [Google Cloud Run]().

It is implemented as a [gRPC]() service and follows the
Google API Design Guidelines that are published at [aip.dev](https://aip.dev).

The gRPC service supports gRPC JSON transcoding, which allows a JSON REST API
to be automatically published using a proxy. Configuration files for Envoy are
included.

The gRPC service is configured to support GAPIC generated API clients
and a Go GAPIC library is generated as part of the build process.

The build process also creates a command-line interface that is
automatically generated from the API description.

## Cloud Run

make build

make run

export AUDIENCES=`gcloud beta run services describe flame --platform managed --format="value(status.address.url)"`

`gcloud auth activate-service-account [email protected] --key-file ~/Downloads/your-project-identifier-e48bd9f1c60a.json`

export CLI_FLAME_TOKEN=`gcloud auth print-identity-token [email protected] --audiences="$AUDIENCES"`

export CLI_FLAME_ADDRESS=flame-ozfrf5bp4a-uw.a.run.app:443
29 changes: 24 additions & 5 deletions apps/disco-flame/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"github.com/golang/protobuf/proto"
"github.com/googleapis/gnostic/conversions"
discovery "github.com/googleapis/gnostic/discovery"
"golang.org/x/oauth2"
"google.golang.org/api/option"
"google.golang.org/grpc"
)
Expand Down Expand Up @@ -201,6 +202,7 @@ func handleExportArgumentsForBytes(arguments map[string]interface{}, bytes []byt
initFlame()
api := document
ctx := context.TODO()

// does the API exist? if not, create it
{
request := &rpcpb.GetProductRequest{}
Expand Down Expand Up @@ -371,19 +373,36 @@ func checkSchema(schemaName string, schema *discovery.Schema, depth int) {
var FlameClient *gapic.FlameClient

func initFlame() error {
var err error
var opts []option.ClientOption

address := "localhost:9999"
address := os.Getenv("CLI_FLAME_ADDRESS")
if address != "" {
opts = append(opts, option.WithEndpoint(address))
}
conn, err := grpc.Dial(address, grpc.WithInsecure())
if err != nil {
return err

insecure := false
if insecure {
if address == "" {
return fmt.Errorf("Missing address to use with insecure connection")
}

conn, err := grpc.Dial(address, grpc.WithInsecure())
if err != nil {
return err
}
opts = append(opts, option.WithGRPCConn(conn))
}
opts = append(opts, option.WithGRPCConn(conn))

if token := os.Getenv("CLI_FLAME_TOKEN"); token != "" {
opts = append(opts, option.WithTokenSource(oauth2.StaticTokenSource(
&oauth2.Token{
AccessToken: token,
TokenType: "Bearer",
})))
}
ctx := context.TODO()
FlameClient, err = gapic.NewFlameClient(ctx, opts...)

return err
}
29 changes: 21 additions & 8 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,39 +16,52 @@ package main

import (
"context"
"flag"
"crypto/tls"
"crypto/x509"
"fmt"
"log"
"os"
"time"

rpc "apigov.dev/flame/rpc"
"google.golang.org/grpc"
)

var (
serverAddr = flag.String("server_addr", "127.0.0.1:9999", "The server address in the format of host:port")
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/metadata"
)

func main() {
flag.Parse()

systemRoots, err := x509.SystemCertPool()
if err != nil {
log.Fatal("failed to load system root CA cert pool")
}
creds := credentials.NewTLS(&tls.Config{
RootCAs: systemRoots,
})
var opts []grpc.DialOption
opts = append(opts, grpc.WithInsecure())
conn, err := grpc.Dial(*serverAddr, opts...)
opts = append(opts, grpc.WithTransportCredentials(creds))

address := os.Getenv("CLI_FLAME_ADDRESS")
conn, err := grpc.Dial(address, opts...)
if err != nil {
log.Fatalf("fail to dial: %v", err)
}
defer conn.Close()

client := rpc.NewFlameClient(conn)
ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
token := os.Getenv("CLI_FLAME_TOKEN")
ctx = metadata.AppendToOutgoingContext(ctx, "authorization", "Bearer "+token)

req := &rpc.ListProductsRequest{}
req.Parent = "projects/google"
res, err := client.ListProducts(ctx, req)
if res != nil {
fmt.Println("The names of your products:")
for _, product := range res.Products {
fmt.Println(product.Name)
}
} else {
log.Printf("Error %+v", err)
}
}
12 changes: 8 additions & 4 deletions cmd/flamed/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,16 @@

package main

import "apigov.dev/flame/server"
import (
"os"

const (
port = ":9999"
"apigov.dev/flame/server"
)

func main() {
server.RunServer(port)
port := os.Getenv("PORT")
if port == "" {
port = "8080"
}
server.RunServer(":" + port)
}

0 comments on commit 1b41dec

Please sign in to comment.