Skip to content

Commit

Permalink
REST proxy added
Browse files Browse the repository at this point in the history
  • Loading branch information
sayan-biswas authored and tekton-robot committed Sep 22, 2022
1 parent 8b29603 commit 8312bc9
Show file tree
Hide file tree
Showing 42 changed files with 5,605 additions and 155 deletions.
10 changes: 8 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
results.db
.vscode
# IDE
.vscode
.idea

# Testing
temp
bin
results.db
25 changes: 14 additions & 11 deletions cmd/api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,21 @@

## Variables

| Environment Variable | Description | Example |
|----------------------|---------------------------------|----------------------------------------------|
| DB_USER | MySQL Database user | user |
| DB_PASSWORD | MySQL Database Password | hunter2 |
| DB_PROTOCOL | MySQL Database Network Protocol | unix |
| DB_ADDR | MySQL Database address | /cloudsql/my-project:us-east1:tekton-results |
| DB_NAME | MySQL Database name | tekton_results |
| DB_SSLMODE | Database SSL mode | verify-full |
| Environment Variable | Description | Example |
|----------------------|----------------------------|----------------------------------------------|
| DB_USER | Postgres Database user | user |
| DB_PASSWORD | Postgres Database Password | hunter2 |
| DB_HOST | Postgres Database host | /cloudsql/my-project:us-east1:tekton-results |
| DB_NAME | Postgres Database name | tekton_results |
| DB_SSLMODE | Database SSL mode | verify-full |
| GRPC_PORT | gRPC Server Port | 50051 (default) |
| REST_PORT | REST proxy Port | 8080 (default) |
| PROMETHEUS_PORT | Prometheus Port | 9090 (default) |
| TLS_HOSTNAME_OVERRIDE| Override the hostname used to serve TLS. This should not be set (or set to the empty string) in production environments. | results.tekton.dev |
| TLS_PATH | Path to TLS files | /etc/tls |

These values can also be set in the config file located in the `env/config` directory.

Values derived from MySQL DSN (see
https://github.com/go-sql-driver/mysql#dsn-data-source-name)
Values derived from Postgres DSN

If you use the default MySQL server we provide, the `DB_ADDR` can be set as `tekton-results-mysql.tekton-pipelines`.
If you use the default postgres database we provide, the `DB_HOST` can be set as `tekton-results-postgres-service.tekton-pipelines`.
128 changes: 75 additions & 53 deletions cmd/api/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,23 @@ limitations under the License.
package main

import (
"flag"
"context"
"fmt"
"github.com/tektoncd/results/pkg/api/server/v1alpha2/auth"
_ "go.uber.org/automaxprocs"
"google.golang.org/grpc/credentials/insecure"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"log"
"net"
"net/http"
"os"

// Go runtime is unaware of CPU quota which means it will set GOMAXPROCS
// to underlying host vm node. This high value means that GO runtime
// scheduler assumes that it has more threads and does context switching
// when it might work with fewer threads.
// This doesn't happen# with our other controllers and services because
// sharedmain already import this package for them.
_ "go.uber.org/automaxprocs"
"path"

grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
prometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/spf13/viper"
v1alpha2 "github.com/tektoncd/results/pkg/api/server/v1alpha2"
"github.com/tektoncd/results/pkg/api/server/v1alpha2/auth"
v1alpha2pb "github.com/tektoncd/results/proto/v1alpha2/results_go_proto"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
Expand All @@ -45,17 +42,20 @@ import (
"google.golang.org/grpc/reflection"
"gorm.io/driver/postgres"
"gorm.io/gorm"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
)

type ConfigFile struct {
DB_USER string `mapstructure:"DB_USER"`
DB_PASSWORD string `mapstructure:"DB_PASSWORD"`
DB_PROTOCOL string `mapstructure:"DB_PROTOCOL"`
DB_ADDR string `mapstructure:"DB_ADDR"`
DB_NAME string `mapstructure:"DB_NAME"`
DB_SSLMODE string `mapstructure:"DB_SSLMODE"`
DB_USER string `mapstructure:"DB_USER"`
DB_PASSWORD string `mapstructure:"DB_PASSWORD"`
DB_HOST string `mapstructure:"DB_HOST"`
DB_PORT string `mapstructure:"DB_PORT"`
DB_NAME string `mapstructure:"DB_NAME"`
DB_SSLMODE string `mapstructure:"DB_SSLMODE"`
GRPC_PORT string `mapstructure:"GRPC_PORT"`
REST_PORT string `mapstructure:"REST_PORT"`
PROMETHEUS_PORT string `mapstructure:"PROMETHEUS_PORT"`
TLS_HOSTNAME_OVERRIDE string `mapstructure:"TLS_HOSTNAME_OVERRIDE"`
TLS_PATH string `mapstructure:"TLS_PATH"`
}

func main() {
Expand All @@ -75,54 +75,49 @@ func main() {
err = viper.Unmarshal(&configFile)

if err != nil {
log.Fatal("cannot load config:", err)
log.Fatal("Cannot load config:", err)
}

flag.Parse()

user, pass := configFile.DB_USER, configFile.DB_PASSWORD
if user == "" || pass == "" {
if configFile.DB_USER == "" || configFile.DB_PASSWORD == "" {
log.Fatal("Must provide both DB_USER and DB_PASSWORD")
}
// Connect to the database.
// DSN derived from https://pkg.go.dev/gorm.io/driver/postgres

sslmode := configFile.DB_SSLMODE
if sslmode == "" {
sslmode = "disable"
}
dbURI := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%s sslmode=%s", configFile.DB_HOST, configFile.DB_USER, configFile.DB_PASSWORD, configFile.DB_NAME, configFile.DB_PORT, configFile.DB_SSLMODE)

dbURI := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=5432 sslmode=%s", configFile.DB_ADDR, user, pass, configFile.DB_NAME, configFile.DB_SSLMODE)
db, err := gorm.Open(postgres.Open(dbURI), &gorm.Config{})
if err != nil {
log.Fatalf("failed to open the results.db: %v", err)
log.Fatalf("Failed to open the results.db: %v", err)
}

// Create k8s client
config, err := rest.InClusterConfig()
if err != nil {
log.Fatal("error getting kubernetes client config:", err)
log.Fatal("Error getting kubernetes client config:", err)
}
k8s, err := kubernetes.NewForConfig(config)
if err != nil {
log.Fatal("error creating kubernetes clientset:", err)
log.Fatal("Error creating kubernetes clientset:", err)
}

// Load TLS cert
creds, err := credentials.NewServerTLSFromFile("/etc/tls/tls.crt", "/etc/tls/tls.key")
if err != nil {
log.Fatalf("error loading TLS key pair: %v", err)
// Load TLS cert for server
creds, tlsError := credentials.NewServerTLSFromFile(path.Join(configFile.TLS_PATH, "tls.crt"), path.Join(configFile.TLS_PATH, "tls.key"))
if tlsError != nil {
log.Printf("Error loading TLS key pair for server: %v", tlsError)
log.Println("Creating server without TLS")
creds = insecure.NewCredentials()
}

// Register API server(s)
v1a2, err := v1alpha2.New(db, v1alpha2.WithAuth(auth.NewRBAC(k8s)))
if err != nil {
log.Fatalf("failed to create server: %v", err)
log.Fatalf("Failed to create server: %v", err)
}
s := grpc.NewServer(
grpc.Creds(creds),
grpc.StreamInterceptor(grpc_prometheus.StreamServerInterceptor),
grpc.UnaryInterceptor(grpc_prometheus.UnaryServerInterceptor),
grpc.StreamInterceptor(prometheus.StreamServerInterceptor),
grpc.UnaryInterceptor(prometheus.UnaryServerInterceptor),
)
v1alpha2pb.RegisterResultsServer(s, v1a2)

Expand All @@ -134,25 +129,52 @@ func main() {
hs.SetServingStatus("tekton.results.v1alpha2.Results", healthpb.HealthCheckResponse_SERVING)
healthpb.RegisterHealthServer(s, hs)

// Prometheus metrics
grpc_prometheus.Register(s)
// Start prometheus metrics server
prometheus.Register(s)
http.Handle("/metrics", promhttp.Handler())
go func() {
if err := http.ListenAndServe(":8080", promhttp.Handler()); err != nil {
log.Fatalf("error running Prometheus HTTP handler: %v", err)
log.Printf("Prometheus server listening on: %s", configFile.PROMETHEUS_PORT)
if err := http.ListenAndServe(":"+configFile.PROMETHEUS_PORT, promhttp.Handler()); err != nil {
log.Fatalf("Error running Prometheus HTTP handler: %v", err)
}
}()

// Listen on port and serve.
port := os.Getenv("PORT")
if port == "" {
// Default gRPC server port to this value from tutorials (e.g., https://grpc.io/docs/guides/auth/#go)
port = "50051"
// Start gRPC server
lis, err := net.Listen("tcp", ":"+configFile.GRPC_PORT)
if err != nil {
log.Fatalf("Failed to listen: %v", err)
}
go func() {
log.Printf("gRPC server listening on: %s", configFile.GRPC_PORT)
log.Fatal(s.Serve(lis))
}()

// Load REST client TLS cert to connect to the gRPC server
if tlsError == nil {
creds, err = credentials.NewClientTLSFromFile(path.Join(configFile.TLS_PATH, "tls.crt"), configFile.TLS_HOSTNAME_OVERRIDE)
if err != nil {
log.Fatalf("Error loading TLS certificate for REST: %v", err)
}
}
lis, err := net.Listen("tcp", ":"+port)

opts := []grpc.DialOption{grpc.WithTransportCredentials(creds)}

// Register gRPC server endpoint for gRPC gateway
ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
defer cancel()
mux := runtime.NewServeMux()
err = v1alpha2pb.RegisterResultsHandlerFromEndpoint(ctx, mux, ":"+configFile.GRPC_PORT, opts)
if err != nil {
log.Fatalf("failed to listen: %v", err)
log.Fatal("Error registering gRPC server endpoint: ", err)
}
log.Printf("Listening on :%s...", port)
log.Fatal(s.Serve(lis))

// Start REST proxy server
log.Printf("REST server Listening on: %s", configFile.REST_PORT)
if tlsError != nil {
log.Fatal(http.ListenAndServe(":"+configFile.REST_PORT, mux))
} else {
log.Fatal(http.ListenAndServeTLS(":"+configFile.REST_PORT, path.Join(configFile.TLS_PATH, "tls.crt"), path.Join(configFile.TLS_PATH, "tls.key"), mux))
}

}
10 changes: 6 additions & 4 deletions config/api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,7 @@ spec:
secretKeyRef:
name: tekton-results-postgres
key: POSTGRES_PASSWORD
- name: DB_PROTOCOL
value: tcp
- name: DB_ADDR
- name: DB_HOST
value: tekton-results-postgres-service.tekton-pipelines.svc.cluster.local
- name: DB_NAME
value: tekton-results
Expand All @@ -75,7 +73,11 @@ spec:
protocol: TCP
port: 50051
targetPort: 50051
- name: prometheus
- name: rest
protocol: TCP
port: 8080
targetPort: 8080
- name: prometheus
protocol: TCP
port: 9090
targetPort: 9090
11 changes: 8 additions & 3 deletions env/config
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
DB_USER=
DB_PASSWORD=
DB_PROTOCOL=
DB_ADDR=
DB_HOST=
DB_PORT=5432
DB_NAME=
DB_SSLMODE=
DB_SSLMODE=disable
GRPC_PORT=50051
REST_PORT=8080
PROMETHEUS_PORT=9090
TLS_HOSTNAME_OVERRIDE=
TLS_PATH=/etc/tls
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ require (
github.com/google/uuid v1.3.0
github.com/gorilla/mux v1.8.0
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
github.com/grpc-ecosystem/grpc-gateway/v2 v2.10.3
github.com/jackc/pgconn v1.11.0
github.com/jonboulle/clockwork v0.2.3
github.com/mattn/go-sqlite3 v2.0.3+incompatible
Expand Down Expand Up @@ -76,7 +77,7 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dimchansky/utfbom v1.1.1 // indirect
github.com/docker/cli v20.10.12+incompatible // indirect
github.com/docker/distribution v2.8.0+incompatible // indirect
github.com/docker/distribution v2.8.1+incompatible // indirect
github.com/docker/docker v20.10.12+incompatible // indirect
github.com/docker/docker-credential-helpers v0.6.4 // indirect
github.com/emicklei/go-restful v2.15.0+incompatible // indirect
Expand Down
7 changes: 5 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -278,8 +278,8 @@ github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi
github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE=
github.com/docker/cli v20.10.12+incompatible h1:lZlz0uzG+GH+c0plStMUdF/qk3ppmgnswpR5EbqzVGA=
github.com/docker/cli v20.10.12+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/distribution v2.8.0+incompatible h1:l9EaZDICImO1ngI+uTifW+ZYvvz7fKISBAKpg+MbWbY=
github.com/docker/distribution v2.8.0+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68=
github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v20.10.12+incompatible h1:CEeNmFM0QZIsJCZKMkZx0ZcahTiewkrgiwfYD+dfl1U=
github.com/docker/docker v20.10.12+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y=
Expand Down Expand Up @@ -401,6 +401,7 @@ github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzw
github.com/golang-jwt/jwt/v4 v4.3.0 h1:kHL1vqdqWNfATmA0FNMdmZNMyZI1U6O31X4rlIPoBog=
github.com/golang-jwt/jwt/v4 v4.3.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ=
github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4=
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
Expand Down Expand Up @@ -560,6 +561,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.12.1/go.mod h1:8XEsbTttt/W+VvjtQhLACqC
github.com/grpc-ecosystem/grpc-gateway v1.14.6/go.mod h1:zdiPV4Yse/1gnckTHtghG4GkDEdKCRJduHpTxT3/jcw=
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.10.3 h1:BGNSrTRW4rwfhJiFwvwF4XQ0Y72Jj9YEgxVrtovbD5o=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.10.3/go.mod h1:VHn7KgNsRriXa4mcgtkpR00OXyQY6g67JWMvn+R27A4=
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
github.com/hashicorp/consul/api v1.10.1/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M=
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
Expand Down
2 changes: 1 addition & 1 deletion proto/v1alpha2/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@

//go:generate rm -rf results_go_proto
//go:generate mkdir results_go_proto
//go:generate protoc --go_out=results_go_proto --go-grpc_out=results_go_proto --go_opt=paths=source_relative --go-grpc_opt=paths=source_relative -I$GOPATH/src/github.com/googleapis/googleapis -I../pipeline/v1beta1 -I. api.proto resources.proto
//go:generate protoc --go_out=results_go_proto --go-grpc_out=results_go_proto --go_opt=paths=source_relative --go-grpc_opt=paths=source_relative --grpc-gateway_out=results_go_proto --grpc-gateway_opt paths=source_relative -I$GOPATH/src/github.com/googleapis/googleapis -I../pipeline/v1beta1 -I. api.proto resources.proto

package v1alpha2
Loading

0 comments on commit 8312bc9

Please sign in to comment.