Skip to content

Commit 3e56356

Browse files
Add v1 and v2 machine names to access tokens (#14)
* Use host.Parse to construct correct machine names * Allow changing the legacy mlab-ns server * Guarantee that Nearest returns v2 hostnames * Create access tokens with v1 and v2 hostnames * Pass platform project to LegacyLocator
1 parent 2dbc759 commit 3e56356

File tree

10 files changed

+49
-20
lines changed

10 files changed

+49
-20
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
language: go
22

33
go:
4-
- 1.13
4+
- 1.14.2
55

66
install:
77
- go get -v -t ./...

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22

33
[![Version](https://img.shields.io/github/tag/m-lab/locate.svg)](https://github.com/m-lab/locate/releases) [![Build Status](https://travis-ci.com/m-lab/locate.svg?branch=master)](https://travis-ci.com/m-lab/locate) [![Coverage Status](https://coveralls.io/repos/m-lab/locate/badge.svg?branch=master)](https://coveralls.io/github/m-lab/locate?branch=master) [![GoDoc](https://godoc.org/github.com/m-lab/locate?status.svg)](https://godoc.org/github.com/m-lab/locate) [![Go Report Card](https://goreportcard.com/badge/github.com/m-lab/locate)](https://goreportcard.com/report/github.com/m-lab/locate)
44

5-
M-Lab Locate Service, a load balancer providing consistent “expected measurement quality” using access control
5+
M-Lab Locate Service, a load balancer providing consistent “expected
6+
measurement quality” using access control.

app.yaml.mlab-ns

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,7 @@ manual_scaling:
1010
instances: 2
1111

1212
env_variables:
13+
LEGACY_SERVER: https://mlab-ns.appspot.com
14+
PLATFORM_PROJECT: mlab-oti
1315
LOCATE_SIGNER_KEY: "CiQACaQCar+BO5frUJv1XYxMS+tjdBGdOa7tZDqb1L6zn38HWp8S3QEApOc0SqhOmXanuWUJK36obD1hA0Qg+JTkifO96fq6NnW0iMDuGVFEHp4LJkfpjcGDE5ibMhPFnb3SIGk9kMg54Qk/3HkNTGONjoY2xAKuuNG0kH3W5nvJS2AK452boMLvK74pQCCmJCvw0FTDQFrNDSdv/NMHRJCxCik2pbIbpAqGcj+6WB/jo3sqGzupdRpTdV5ErC5t0GETqopcC3XBnLJh+HbpK7rIn9dDgR8oJcSiG4xCYhZGOATbJ9V1/O3V+cuXFrH1qpqM/uSUdSO4clqUTBcpshPFY/Njiw=="
1416
MONITORING_VERIFY_KEY: "CiQACaQCath3g+zc257EYcrN7fyhHDChcdlOHrgSeYMZSmd1jqsSrwEApOc0Silmr9MA0tvS+44Eo53p1tI6F9emIFYS4UP5BRhKCB4Svi5sFzGQUqgDlZq5AHGCwvIlzr4TvncpYvaBbtwccj/0W15ItNmzFwqq7mP0rqA/SVhv/8e6usfkFZIDVIuEXzjhf4jw56u2yttZgEhutOvMNUXExNh6TKZcMPaD8XX/LGgPF9qw7E8qTV7Rm7CVwyvzWR6hhpAUsRegTrH+YKgCNiox51o1HjZU"

app.yaml.mlab-sandbox

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,7 @@ manual_scaling:
1010
instances: 2
1111

1212
env_variables:
13+
LEGACY_SERVER: https://mlab-ns.appspot.com
14+
PLATFORM_PROJECT: mlab-oti
1315
LOCATE_SIGNER_KEY: "CiQAdG57X+eNfzELY0Z4DT4kJo8H/8zHE6iAb24zrwOxS548I8US3QEAymHd3rWzCjLXVWYB9IdZQ7ZB2v7b8hSPtAX3Xuw7eeBrK/PhDRBIpJW7ziGeJZ+TfEYxek2XSfR+4hWVPZ9QD4EY5VoALMNt6uCU/DOemBwo1Sehln5sZEtjN7A/FXDun+VNraIASmOplTIyywlxJaoY2o0tJGI3WYurwL2MjkmhbMao8nlvKF7tavaNgB2KKfNkz1vWFqNskRSBfpAzZvqWSteRXMRaQdtC6+FUWmGILGzm2M6QhuL8sjnRayjO+3t5vL3hcwdcjf+lybI8N3RqUrbiBo11sWU6mA=="
1416
MONITORING_VERIFY_KEY: "CiQAdG57X9xPoBQYA4RbXuNhOGXyqwH9jjQ3FiVaVZkqXtuvw54SrwEAymHd3mcGtKCAVnMj59OmrvRM6m2HgEiqoWwt8N16LjZiI6e0/Sj8V1xH9WXER5QkpBCLgdphQbpy2B8WV4AeBqujABNJkiXzWvQRbWqkZnnrCXXx3FIlMOUqe0p8qZxnOTtALDlKHphjxmccWqevZYq4LMrz+qTRSRUH7UH+VyB0TNPBncFczUMM0ysZtY/yLcXlUSMz8JTlPbKUsBn6Xty7xhwNqyOIazK6wKKh"

app.yaml.mlab-staging

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,7 @@ manual_scaling:
1010
instances: 2
1111

1212
env_variables:
13+
LEGACY_SERVER: https://mlab-ns.appspot.com
14+
PLATFORM_PROJECT: mlab-oti
1315
LOCATE_SIGNER_KEY: "CiQA1JQH7XBe+fVeL2x2Y8de6Lt3SsB+CA4HzJSNMuac6rq01u8S3QEAIb7fPKzhq0lGB8Nw9J4CNOuGEJVfO8KDrCf4dH1X6ULIAHRBf6RLN8tg0FxXvx8aMYmu1ree5ERVkD4proREtU4Gh3Y/lZHmpdjgrjJ3pM/jNQawfqUHBlGVkAn6trrOdSG5X4molBUL7Dr+M4YFwc+40ByTagFEintSQGvLRpGsHyrj43v3kSwjzWi6UgPjXNoLJYTY10gEEm+QGhne5IUnbVcYEVqtGQKzPPQnelDDD3120XuN0tUhvVgBIq3g96SxwJN/EAoSJENHa3SZ8BetEJC7WTu/58+VpQ=="
1416
MONITORING_VERIFY_KEY: "CiQA1JQH7Zp2+UW/CgEW7KIaAsjDAjZZUBcuiMVhBoJzH7xK5MwSrwEAIb7fPG/G2DN+O4DAIy0i8gOm4NsuZWqT/Nc7eYK3EJjr8/WchEFvWkKd5a8D/SQrl+Ui7oHNPjyMtFP+VjH+8DAJX/5P1lHvdl4exYr4flkDJ3GcE7eWy1YcAcuLPTqrjcYQaegqQllDDJdlNDeYn+FGRkr6nDHrGbvuYevTC5Tz+MTBYLVQrgNnRGlQ54BMK9UPmmcO6bHSjnSUlC4y2FZmCIiq2IERJquMwOfK"

cloudbuild/cloudbuild.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ options:
88
steps:
99
# Run unit tests for environment.
1010
- name: gcr.io/$PROJECT_ID/golang-cbif
11+
env:
12+
- GONOPROXY=github.com/m-lab/go/*
1113
args:
1214
- go version
1315
- go get -v -t ./...

handler/handler.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414

1515
"gopkg.in/square/go-jose.v2/jwt"
1616

17+
"github.com/m-lab/go/host"
1718
"github.com/m-lab/go/rtx"
1819
v2 "github.com/m-lab/locate/api/v2"
1920
"github.com/m-lab/locate/static"
@@ -101,11 +102,19 @@ func (c *Client) Heartbeat(rw http.ResponseWriter, req *http.Request) {
101102
// getAccessToken allocates a new access token using the given machine name as
102103
// the intended audience and the subject as the target service.
103104
func (c *Client) getAccessToken(machine, subject string) string {
105+
// Create canonical v1 and v2 machine names.
106+
name, err := host.Parse(machine)
107+
rtx.PanicOnError(err, "failed to parse given machine name")
108+
aud := jwt.Audience{name.String()}
109+
// TODO: after the v2 migration, eliminate machine parsing and v1 logic.
110+
name.Version = "v1"
111+
aud = append(aud, name.String())
112+
104113
// Create the token. The same access token is used for each target port.
105114
cl := jwt.Claims{
106115
Issuer: static.IssuerLocate,
107116
Subject: subject,
108-
Audience: jwt.Audience{machine},
117+
Audience: aud,
109118
Expiry: jwt.NewNumericDate(time.Now().Add(time.Minute)),
110119
}
111120
token, err := c.Sign(cl)

locate.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ import (
2323
var (
2424
listenPort string
2525
project string
26+
platform string
27+
legacyServer string
2628
locateSignerKey string
2729
monitoringVerifyKey = flagx.StringArray{}
2830
)
@@ -31,6 +33,8 @@ func init() {
3133
// PORT and GOOGLE_CLOUD_PROJECT are part of the default App Engine environment.
3234
flag.StringVar(&listenPort, "port", "8080", "AppEngine port environment variable")
3335
flag.StringVar(&project, "google-cloud-project", "", "AppEngine project environment variable")
36+
flag.StringVar(&platform, "platform-project", "", "GCP project for platform machine names")
37+
flag.StringVar(&legacyServer, "legacy-server", proxy.DefaultLegacyServer, "Base URL to mlab-ns server")
3438
flag.StringVar(&locateSignerKey, "locate-signer-key", "", "Private key of the locate+service key pair")
3539
flag.Var(&monitoringVerifyKey, "monitoring-verify-key", "Public keys of the monitoring+locate key pair")
3640
}
@@ -49,7 +53,7 @@ func main() {
4953
// Load encrypted signer key from environment, using variable name derived from project.
5054
signer, err := cfg.LoadSigner(mainCtx, client, locateSignerKey)
5155
rtx.Must(err, "Failed to load signer key")
52-
locator := proxy.MustNewLegacyLocator(proxy.DefaultLegacyServer)
56+
locator := proxy.MustNewLegacyLocator(legacyServer, platform)
5357
c := handler.NewClient(project, signer, locator)
5458

5559
// MONITORING VERIFIER - for access tokens provided by monitoring.

proxy/proxy.go

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ import (
99
"io/ioutil"
1010
"net/http"
1111
"net/url"
12-
"regexp"
1312
"time"
1413

14+
"github.com/m-lab/go/host"
1515
"github.com/m-lab/go/rtx"
1616
"github.com/m-lab/locate/static"
1717
)
@@ -30,16 +30,18 @@ type target struct {
3030

3131
// LegacyLocator manages requests to the legacy mlab-ns service.
3232
type LegacyLocator struct {
33-
Server url.URL
33+
Server url.URL
34+
project string
3435
}
3536

3637
// MustNewLegacyLocator creates a new LegacyLocator instance. If the given url
3738
// fails to parse, the function will exit.
38-
func MustNewLegacyLocator(u string) *LegacyLocator {
39+
func MustNewLegacyLocator(u, project string) *LegacyLocator {
3940
server, err := url.Parse(u)
4041
rtx.Must(err, "Failed to parse given url: %q", u)
4142
return &LegacyLocator{
42-
Server: *server,
43+
Server: *server,
44+
project: project,
4345
}
4446
}
4547

@@ -74,7 +76,7 @@ func (ll *LegacyLocator) Nearest(ctx context.Context, service, lat, lon string)
7476
if err != nil {
7577
return nil, err
7678
}
77-
return collect(opts), nil
79+
return ll.collect(opts), nil
7880
}
7981

8082
// UnmarshalResponse reads the response from the given request and unmarshals
@@ -96,18 +98,23 @@ func UnmarshalResponse(req *http.Request, result interface{}) error {
9698
return json.Unmarshal(b, result)
9799
}
98100

99-
// NOTE: this pattern assumes mlab-ns is returning flat host names, and should
100-
// be future compatible with project-decorated DNS names.
101-
var machinePattern = regexp.MustCompile("([a-z-]+)-(mlab[1-4][.-][a-z]{3}[0-9ct]{2}(\\.mlab-[a-z]+)?.measurement-lab.org)")
102-
103-
func collect(opts *geoOptions) []string {
101+
// collect reads all FQDN results from the given options and guarantees to
102+
// return v2 formatted hostnames.
103+
func (ll *LegacyLocator) collect(opts *geoOptions) []string {
104104
targets := []string{}
105105
for _, opt := range *opts {
106-
fields := machinePattern.FindStringSubmatch(opt.FQDN)
107-
if len(fields) < 3 {
106+
name, err := host.Parse(opt.FQDN)
107+
if err != nil {
108108
continue
109109
}
110-
targets = append(targets, fields[2])
110+
// TODO: after the v2 migration, eliminate v1 logic.
111+
if name.Version == "v1" {
112+
// Convert name to v2.
113+
name.Project = ll.project
114+
name.Version = "v2"
115+
}
116+
// Convert the service name into a canonical machine name.
117+
targets = append(targets, name.String())
111118
}
112119
return targets
113120
}

proxy/proxy_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ func TestNearest(t *testing.T) {
143143
content: legacyNames,
144144
status: http.StatusOK,
145145
want: []string{
146-
"mlab1-lga06.measurement-lab.org", "mlab3-lga05.measurement-lab.org",
146+
"mlab1-lga06.mlab-testing.measurement-lab.org", "mlab3-lga05.mlab-testing.measurement-lab.org",
147147
},
148148
},
149149
{
@@ -165,7 +165,7 @@ func TestNearest(t *testing.T) {
165165
content: shortNames,
166166
status: http.StatusOK,
167167
want: []string{
168-
"mlab2-lga03.measurement-lab.org", "mlab3-lga08.measurement-lab.org",
168+
"mlab2-lga03.mlab-testing.measurement-lab.org", "mlab3-lga08.mlab-testing.measurement-lab.org",
169169
},
170170
},
171171
{
@@ -222,7 +222,7 @@ func TestNearest(t *testing.T) {
222222
mux := http.NewServeMux()
223223
mux.HandleFunc("/"+static.LegacyServices[tt.service], f.defaultHandler)
224224
srv := httptest.NewServer(mux)
225-
ll := MustNewLegacyLocator(srv.URL)
225+
ll := MustNewLegacyLocator(srv.URL, "mlab-testing")
226226
if tt.badScheme != "" {
227227
// While a url with a bad scheme can be converted using .String(),
228228
// it will fail to parse again. This injects an error in NewRequestWithContext().

0 commit comments

Comments
 (0)