Skip to content

Commit

Permalink
Merge pull request #64 from andrewhowdencom/make-the-pr-gods-happy
Browse files Browse the repository at this point in the history
make the pr gods happy
  • Loading branch information
andrewhowdencom committed Apr 10, 2024
2 parents 8692103 + 6755d24 commit d5f7d32
Show file tree
Hide file tree
Showing 13 changed files with 294 additions and 6 deletions.
13 changes: 13 additions & 0 deletions .bingo/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

# Ignore everything
*

# But not these files:
!.gitignore
!*.mod
!*.sum
!README.md
!Variables.mk
!variables.env

*tmp.mod
14 changes: 14 additions & 0 deletions .bingo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Project Development Dependencies.

This is directory which stores Go modules with pinned buildable package that is used within this repository, managed by https://github.com/bwplotka/bingo.

* Run `bingo get` to install all tools having each own module file in this directory.
* Run `bingo get <tool>` to install <tool> that have own module file in this directory.
* For Makefile: Make sure to put `include .bingo/Variables.mk` in your Makefile, then use $(<upper case tool name>) variable where <tool> is the .bingo/<tool>.mod.
* For shell: Run `source .bingo/variables.env` to source all environment variable for each tool.
* For go: Import `.bingo/variables.go` to for variable names.
* See https://github.com/bwplotka/bingo or -h on how to add, remove or change binaries dependencies.

## Requirements

* Go 1.14+
25 changes: 25 additions & 0 deletions .bingo/Variables.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Auto generated binary variables helper managed by https://github.com/bwplotka/bingo v0.9. DO NOT EDIT.
# All tools are designed to be build inside $GOBIN.
BINGO_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
GOPATH ?= $(shell go env GOPATH)
GOBIN ?= $(firstword $(subst :, ,${GOPATH}))/bin
GO ?= $(shell which go)

# Below generated variables ensure that every time a tool under each variable is invoked, the correct version
# will be used; reinstalling only if needed.
# For example for task variable:
#
# In your main Makefile (for non array binaries):
#
#include .bingo/Variables.mk # Assuming -dir was set to .bingo .
#
#command: $(TASK)
# @echo "Running task"
# @$(TASK) <flags/args..>
#
TASK := $(GOBIN)/task-v3.36.0
$(TASK): $(BINGO_DIR)/task.mod
@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.
@echo "(re)installing $(GOBIN)/task-v3.36.0"
@cd $(BINGO_DIR) && GOWORK=off $(GO) build -mod=mod -modfile=task.mod -o=$(GOBIN)/task-v3.36.0 "github.com/go-task/task/v3/cmd/task"

1 change: 1 addition & 0 deletions .bingo/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module _ // Fake go.mod auto-created by 'bingo' for go -moddir compatibility with non-Go projects. Commit this file, together with other .mod files.
5 changes: 5 additions & 0 deletions .bingo/task.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT

go 1.21.4

require github.com/go-task/task/v3 v3.36.0 // cmd/task
44 changes: 44 additions & 0 deletions .bingo/task.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0=
github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/go-task/task/v3 v3.36.0 h1:XVJ5hQ5hdzTAulHpAGzbUMUuYr9MUOEQFOFazI3hUsY=
github.com/go-task/task/v3 v3.36.0/go.mod h1:XBCIAzuyG/mgZVHMUm3cCznz4+IpsBQRlW1gw7OA5sA=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-zglob v0.0.4 h1:LQi2iOm0/fGgu80AioIJ/1j9w9Oh+9DZ39J4VAGzHQM=
github.com/mattn/go-zglob v0.0.4/go.mod h1:MxxjyoXXnMxfIpxTK2GAkw1w8glPsQILx3N5wrKakiY=
github.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4NcD46KavDd4=
github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/zz4kQkprJgF2EVszyDE=
github.com/radovskyb/watcher v1.0.7 h1:AYePLih6dpmS32vlHfhCeli8127LzkIgwJGcwwe8tUE=
github.com/radovskyb/watcher v1.0.7/go.mod h1:78okwvY5wPdzcb1UYnip1pvrZNIVEIh/Cm+ZuvsUYIg=
github.com/sajari/fuzzy v1.0.0 h1:+FmwVvJErsd0d0hAPlj4CxqxUtQY/fOoY0DwX4ykpRY=
github.com/sajari/fuzzy v1.0.0/go.mod h1:OjYR6KxoWOe9+dOlXeiCJd4dIbED4Oo8wpS89o0pwOo=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0=
github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q=
golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
mvdan.cc/sh/v3 v3.8.0 h1:ZxuJipLZwr/HLbASonmXtcvvC9HXY9d2lXZHnKGjFc8=
mvdan.cc/sh/v3 v3.8.0/go.mod h1:w04623xkgBVo7/IUK89E0g8hBykgEpN0vgOj3RJr6MY=
12 changes: 12 additions & 0 deletions .bingo/variables.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Auto generated binary variables helper managed by https://github.com/bwplotka/bingo v0.9. DO NOT EDIT.
# All tools are designed to be build inside $GOBIN.
# Those variables will work only until 'bingo get' was invoked, or if tools were installed via Makefile's Variables.mk.
GOBIN=${GOBIN:=$(go env GOBIN)}

if [ -z "$GOBIN" ]; then
GOBIN="$(go env GOPATH)/bin"
fi


TASK="${GOBIN}/task-v3.36.0"

3 changes: 2 additions & 1 deletion Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ tasks:
cmds:
# Generate the required files
- mkdir -p "dist/{{ .GOOS }}+{{ .GOARCH }}"
- go build -o "dist/{{ .GOOS }}+{{ .GOARCH }}/x40.link{{ exeExt }}"
- go build -o "dist/{{ .GOOS }}+{{ .GOARCH }}/x40.link{{ exeExt }}" main.go
- go build -o "dist/{{ .GOOS }}+{{ .GOARCH }}/@{{ exeExt }}" cli/main.go

bin/all:
desc: "Builds the go binaries"
Expand Down
28 changes: 28 additions & 0 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,31 @@
package api

import (
"crypto/x509"
"errors"
"fmt"
"strings"

"github.com/andrewhowdencom/x40.link/api/dev"
gendev "github.com/andrewhowdencom/x40.link/api/gen/dev"
"github.com/andrewhowdencom/x40.link/storage"
"github.com/andrewhowdencom/x40.link/uid"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/reflection"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/reflect/protoregistry"
descpb "google.golang.org/protobuf/types/descriptorpb"
)

var ErrCannotDialServer = errors.New("cannot connect to grpc server")
var ErrMissingCertificates = errors.New("cannot get system certificates")

type Client interface {
gendev.ManageURLsClient
}

// ProtoPackages is a list of all protobuf packages this API cares about.
var ProtoPackages = []string{
"x40.dev.url",
Expand Down Expand Up @@ -95,3 +106,20 @@ func NewGRPCMux(storer storage.Storer, opts ...grpc.ServerOption) *grpc.Server {

return m
}

func NewGRPCClient(addr string, opts ...grpc.DialOption) (Client, error) {

// Use the default system certiifcate pool.
cp, err := x509.SystemCertPool()
if err != nil {
return nil, fmt.Errorf("%w: %s", ErrMissingCertificates, err)
}

opts = append(opts, grpc.WithTransportCredentials(credentials.NewClientTLSFromCert(cp, "")))
conn, err := grpc.Dial(addr, opts...)
if err != nil {
return nil, fmt.Errorf("%w: %s", ErrCannotDialServer, err)
}

return gendev.NewManageURLsClient(conn), nil
}
2 changes: 1 addition & 1 deletion cfg/cfg.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ var (

// The actual configuration values.
var (
APIEndpoint = &String{V: V{Path: "api.endpoint", Default: "https://api.x40.link", Usage: "The endpoint to talk to for links", mu: &sync.Mutex{}}}
APIEndpoint = &String{V: V{Path: "api.endpoint", Default: "api.x40.link:443", Usage: "The endpoint to talk to for links", mu: &sync.Mutex{}}}

// AuthX40 just means "authenticate this against the public X40 endpoints"
AuthX40 = &Bool{V: V{Path: "auth.x40", Default: false, Usage: "Whether to configure the application to authenticate against the public x40 links", mu: &sync.Mutex{}}}
Expand Down
45 changes: 45 additions & 0 deletions cli/auth/auth.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package auth

import (
"context"
"path"

"github.com/adrg/xdg"
"github.com/andrewhowdencom/x40.link/api"
"github.com/andrewhowdencom/x40.link/api/auth/jwts"
"github.com/andrewhowdencom/x40.link/api/auth/tokens"
"github.com/andrewhowdencom/x40.link/api/auth/tokens/seeds"
"github.com/andrewhowdencom/x40.link/api/auth/tokens/storage"
"github.com/andrewhowdencom/x40.link/cfg"
"github.com/spf13/viper"
"golang.org/x/oauth2"
)

// TokenSource returns a TokenSource appropriate for the CLI Application, or an error if this failed.
func TokenSource() (oauth2.TokenSource, error) {
ctx := context.Background()

cfg := &oauth2.Config{
ClientID: viper.GetString(cfg.OAuth2ClientID.Path),
Endpoint: oauth2.Endpoint{
DeviceAuthURL: viper.GetString(cfg.OAuth2DeviceAuthorizationEndpoint.Path),
TokenURL: viper.GetString(cfg.OAuth2TokenURL.Path),
},
Scopes: api.X40PermissionsList(),
}

tokPath, err := xdg.DataFile(path.Join("x40", "cli-token"))
if err != nil {
return nil, err
}

ts, err := tokens.NewCachingSource(ctx, cfg.TokenSource, seeds.DeviceAuth(jwts.AudienceX40API, cfg), &storage.File{
Path: tokPath,
})

if err != nil {
return nil, err
}

return ts, nil
}
99 changes: 99 additions & 0 deletions cli/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package main

import (
"context"
"fmt"
"os"
"strings"
"time"

"github.com/andrewhowdencom/sysexits"
"github.com/andrewhowdencom/x40.link/api"
"github.com/andrewhowdencom/x40.link/api/gen/dev"
"github.com/andrewhowdencom/x40.link/cfg"
"github.com/andrewhowdencom/x40.link/cli/auth"
"github.com/andrewhowdencom/x40.link/cmd"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/spf13/viper"
"google.golang.org/grpc/metadata"
)

var (
urlFlagSet = func() *pflag.FlagSet {
fs := &pflag.FlagSet{}

for _, f := range []interface {
AddFlagTo(*pflag.FlagSet)
}{
cfg.APIEndpoint,

cfg.OAuth2ClientID,
cfg.OAuth2AuthorizationURL,
cfg.OAuth2DeviceAuthorizationEndpoint,
cfg.OAuth2TokenURL,
} {
f.AddFlagTo(fs)
}

return fs
}()
)

// Root represents the url command
var Root = &cobra.Command{
Use: "@",
Short: "The client tool for generating URLs",
Args: cobra.ExactArgs(1),
RunE: DoURL,
}

func DoURL(cmd *cobra.Command, args []string) error {
ts, err := auth.TokenSource()
if err != nil {
return fmt.Errorf("%w: %s", sysexits.Software, err)
}

client, err := api.NewGRPCClient(viper.GetString(cfg.APIEndpoint.Path))
if err != nil {
return fmt.Errorf("%w: %s", sysexits.NoHost, err)
}

tok, err := ts.Token()
if err != nil {
return fmt.Errorf("%w: %s", sysexits.Software, err)
}

md := metadata.New(map[string]string{
"Authorization": "Bearer " + tok.AccessToken,
})

ctx, cxl := context.WithTimeout(context.Background(), time.Second*10)
defer cxl()

ctx = metadata.NewOutgoingContext(ctx, md)

resp, err := client.New(ctx, &dev.NewRequest{
SendTo: args[0],
})

if err != nil {
return fmt.Errorf("%w: %s", sysexits.Protocol, err)
}

url, _ := strings.CutPrefix(resp.Url, "//")
fmt.Println(url)

return nil
}

func init() {
Root.Flags().AddFlagSet(urlFlagSet)
}

func main() {
// Cobra will print the exit.String() as part of its Execute method. Here, we only need to check
// what the exit code should be.
exit := cmd.Execute(Root)
os.Exit(exit.Code)
}
9 changes: 5 additions & 4 deletions deploy/prod/tf/cr.tf
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,15 @@ resource "google_compute_global_address" "x40-link" {
name = "x40-link"
}

resource "google_compute_managed_ssl_certificate" "all-link-shorteners" {
name = "all-link-shorteners"
resource "google_compute_managed_ssl_certificate" "all-link-shorteners-v2" {
name = "all-link-shorteners-v2"

managed {
domains = concat(var.x40_link_domains, var.h4n_me_domains)
domains = concat(var.x40_link_domains, var.h4n_me_domains, ["andrewhowden.com"])
}
}


resource "google_compute_region_network_endpoint_group" "x40-link" {
name = "x40-link"
network_endpoint_type = "SERVERLESS"
Expand Down Expand Up @@ -106,7 +107,7 @@ resource "google_compute_target_https_proxy" "x40-link" {
url_map = google_compute_url_map.x40-link.id

ssl_certificates = [
google_compute_managed_ssl_certificate.all-link-shorteners.id
google_compute_managed_ssl_certificate.all-link-shorteners-v2.id
]
}

Expand Down

0 comments on commit d5f7d32

Please sign in to comment.