Skip to content
This repository was archived by the owner on Aug 14, 2020. It is now read-only.

Commit a22774b

Browse files
committed
discovery: correctly split DiscoverEndpoints and DiscoverPublicKeys
currently DiscoverEndpoints and DiscoverPublicKeys, despite their name, returns both endpoints and keys. Additionally their results are different. For example: suppose in `example.com/images/app` we have this meta tags: ``` <meta name="ac-discovery" content="example.com https://storage.example.com/{name}-{version}.{ext}"> ``` while in a parent path like `example.com/images` we have this meta tag: ``` <meta name="ac-discovery-pubkeys" content="example.com https://example.com/pubkeys.gpg"> ``` Calling DiscoverEndpoints will stop at the meta tags in `example.com/images/app` and return 1 endpoint and 0 pubkeys Calling DiscoverPublicKeys won't find any meta tag in `example.com/images/app` so will search in `example.com/images` and return 0 endpoints and 1 keys To avoid these problems these functions should return just their requested type. So the user is not tempted to use the other type just calling one of the functions. This mean that endpoints and keys discovery must do different http calls. * fix actool that used only DiscoverEndpoints to also get discovery keys. * Remove appending of previously discovered endpoint and keys since I can't find a logic in it (simplyfing various functions). * Rework tests to check also this and other kind of problems and be more fine grained.
1 parent ec54868 commit a22774b

File tree

10 files changed

+482
-119
lines changed

10 files changed

+482
-119
lines changed

actool/discover.go

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,25 +64,40 @@ func runDiscover(args []string) (exit int) {
6464
}
6565
eps, attempts, err := discovery.DiscoverEndpoints(*app, nil, insecure)
6666
if err != nil {
67-
stderr("error fetching %s: %s", name, err)
67+
stderr("error fetching endpoints for %s: %s", name, err)
6868
return 1
6969
}
7070
for _, a := range attempts {
71-
fmt.Printf("discover walk: prefix: %s error: %v\n", a.Prefix, a.Error)
71+
fmt.Printf("discover endpoints walk: prefix: %s error: %v\n", a.Prefix, a.Error)
7272
}
73+
keys, attempts, err := discovery.DiscoverPublicKeys(*app, nil, insecure)
74+
if err != nil {
75+
stderr("error fetching keys for %s: %s", name, err)
76+
return 1
77+
}
78+
for _, a := range attempts {
79+
fmt.Printf("discover keys walk: prefix: %s error: %v\n", a.Prefix, a.Error)
80+
}
81+
82+
type discoveryData struct {
83+
ACIEndpoints []discovery.ACIEndpoint
84+
Keys []string
85+
}
86+
7387
if outputJson {
74-
jsonBytes, err := json.MarshalIndent(&eps, "", " ")
88+
dd := discoveryData{ACIEndpoints: eps, Keys: keys}
89+
jsonBytes, err := json.MarshalIndent(dd, "", " ")
7590
if err != nil {
7691
stderr("error generating JSON: %s", err)
7792
return 1
7893
}
7994
fmt.Println(string(jsonBytes))
8095
} else {
81-
for _, aciEndpoint := range eps.ACIEndpoints {
96+
for _, aciEndpoint := range eps {
8297
fmt.Printf("ACI: %s, ASC: %s\n", aciEndpoint.ACI, aciEndpoint.ASC)
8398
}
84-
if len(eps.Keys) > 0 {
85-
fmt.Println("Keys: " + strings.Join(eps.Keys, ","))
99+
if len(keys) > 0 {
100+
fmt.Println("Keys: " + strings.Join(keys, ","))
86101
}
87102
}
88103
}

discovery/discovery.go

Lines changed: 35 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,19 @@ type ACIEndpoint struct {
3737
ASC string
3838
}
3939

40-
type Endpoints struct {
40+
// A struct containing both discovered endpoints and keys. Used to avoid
41+
// function duplication (one for endpoints and one for keys, so to avoid two
42+
// doDiscover, two DiscoverWalkFunc)
43+
type discoveryData struct {
4144
ACIEndpoints []ACIEndpoint
4245
Keys []string
4346
}
4447

45-
func (e *Endpoints) Append(ep Endpoints) {
48+
type Endpoints []ACIEndpoint
49+
50+
type Keys []string
51+
52+
func (e *discoveryData) Append(ep discoveryData) {
4653
e.ACIEndpoints = append(e.ACIEndpoints, ep.ACIEndpoints...)
4754
e.Keys = append(e.Keys, ep.Keys...)
4855
}
@@ -124,7 +131,7 @@ func createTemplateVars(app App) []string {
124131
return tplVars
125132
}
126133

127-
func doDiscover(pre string, hostHeaders map[string]http.Header, app App, insecure InsecureOption) (*Endpoints, error) {
134+
func doDiscover(pre string, hostHeaders map[string]http.Header, app App, insecure InsecureOption) (*discoveryData, error) {
128135
app = *app.Copy()
129136
if app.Labels["version"] == "" {
130137
app.Labels["version"] = defaultVersion
@@ -140,7 +147,7 @@ func doDiscover(pre string, hostHeaders map[string]http.Header, app App, insecur
140147

141148
tplVars := createTemplateVars(app)
142149

143-
de := &Endpoints{}
150+
dd := &discoveryData{}
144151

145152
for _, m := range meta {
146153
if !strings.HasPrefix(app.Name.String(), m.prefix) {
@@ -159,41 +166,37 @@ func doDiscover(pre string, hostHeaders map[string]http.Header, app App, insecur
159166
if !ok {
160167
continue
161168
}
162-
de.ACIEndpoints = append(de.ACIEndpoints, ACIEndpoint{ACI: aci, ASC: asc})
169+
dd.ACIEndpoints = append(dd.ACIEndpoints, ACIEndpoint{ACI: aci, ASC: asc})
163170

164171
case "ac-discovery-pubkeys":
165-
de.Keys = append(de.Keys, m.uri)
172+
dd.Keys = append(dd.Keys, m.uri)
166173
}
167174
}
168175

169-
return de, nil
176+
return dd, nil
170177
}
171178

172179
// DiscoverWalk will make HTTPS requests to find discovery meta tags and
173180
// optionally will use HTTP if insecure is set. hostHeaders specifies the
174181
// header to apply depending on the host (e.g. authentication). Based on the
175182
// response of the discoverFn it will continue to recurse up the tree.
176-
func DiscoverWalk(app App, hostHeaders map[string]http.Header, insecure InsecureOption, discoverFn DiscoverWalkFunc) (err error) {
177-
var (
178-
eps *Endpoints
179-
)
180-
183+
func DiscoverWalk(app App, hostHeaders map[string]http.Header, insecure InsecureOption, discoverFn DiscoverWalkFunc) (dd *discoveryData, err error) {
181184
parts := strings.Split(string(app.Name), "/")
182185
for i := range parts {
183186
end := len(parts) - i
184187
pre := strings.Join(parts[:end], "/")
185188

186-
eps, err = doDiscover(pre, hostHeaders, app, insecure)
187-
if derr := discoverFn(pre, eps, err); derr != nil {
188-
return derr
189+
dd, err = doDiscover(pre, hostHeaders, app, insecure)
190+
if derr := discoverFn(pre, dd, err); derr != nil {
191+
return dd, derr
189192
}
190193
}
191194

192-
return
195+
return nil, fmt.Errorf("discovery failed")
193196
}
194197

195198
// DiscoverWalkFunc can stop a DiscoverWalk by returning non-nil error.
196-
type DiscoverWalkFunc func(prefix string, eps *Endpoints, err error) error
199+
type DiscoverWalkFunc func(prefix string, dd *discoveryData, err error) error
197200

198201
// FailedAttempt represents a failed discovery attempt. This is for debugging
199202
// and user feedback.
@@ -202,14 +205,13 @@ type FailedAttempt struct {
202205
Error error
203206
}
204207

205-
func walker(out *Endpoints, attempts *[]FailedAttempt, testFn DiscoverWalkFunc) DiscoverWalkFunc {
206-
return func(pre string, eps *Endpoints, err error) error {
208+
func walker(attempts *[]FailedAttempt, testFn DiscoverWalkFunc) DiscoverWalkFunc {
209+
return func(pre string, dd *discoveryData, err error) error {
207210
if err != nil {
208211
*attempts = append(*attempts, FailedAttempt{pre, err})
209212
return nil
210213
}
211-
out.Append(*eps)
212-
if err := testFn(pre, eps, err); err != nil {
214+
if err := testFn(pre, dd, err); err != nil {
213215
return err
214216
}
215217
return nil
@@ -221,40 +223,40 @@ func walker(out *Endpoints, attempts *[]FailedAttempt, testFn DiscoverWalkFunc)
221223
// specifies the header to apply depending on the host (e.g. authentication).
222224
// It will not give up until it has exhausted the path or found an image
223225
// discovery.
224-
func DiscoverEndpoints(app App, hostHeaders map[string]http.Header, insecure InsecureOption) (out *Endpoints, attempts []FailedAttempt, err error) {
225-
out = &Endpoints{}
226-
testFn := func(pre string, eps *Endpoints, err error) error {
227-
if len(out.ACIEndpoints) != 0 {
226+
func DiscoverEndpoints(app App, hostHeaders map[string]http.Header, insecure InsecureOption) (Endpoints, []FailedAttempt, error) {
227+
testFn := func(pre string, dd *discoveryData, err error) error {
228+
if len(dd.ACIEndpoints) != 0 {
228229
return errEnough
229230
}
230231
return nil
231232
}
232233

233-
err = DiscoverWalk(app, hostHeaders, insecure, walker(out, &attempts, testFn))
234+
attempts := []FailedAttempt{}
235+
dd, err := DiscoverWalk(app, hostHeaders, insecure, walker(&attempts, testFn))
234236
if err != nil && err != errEnough {
235237
return nil, attempts, err
236238
}
237239

238-
return out, attempts, nil
240+
return dd.ACIEndpoints, attempts, nil
239241
}
240242

241243
// DiscoverPublicKey will make HTTPS requests to find the ac-public-keys meta
242244
// tags and optionally will use HTTP if insecure is set. hostHeaders
243245
// specifies the header to apply depending on the host (e.g. authentication).
244246
// It will not give up until it has exhausted the path or found an public key.
245-
func DiscoverPublicKeys(app App, hostHeaders map[string]http.Header, insecure InsecureOption) (out *Endpoints, attempts []FailedAttempt, err error) {
246-
out = &Endpoints{}
247-
testFn := func(pre string, eps *Endpoints, err error) error {
248-
if len(out.Keys) != 0 {
247+
func DiscoverPublicKeys(app App, hostHeaders map[string]http.Header, insecure InsecureOption) (Keys, []FailedAttempt, error) {
248+
testFn := func(pre string, dd *discoveryData, err error) error {
249+
if len(dd.Keys) != 0 {
249250
return errEnough
250251
}
251252
return nil
252253
}
253254

254-
err = DiscoverWalk(app, hostHeaders, insecure, walker(out, &attempts, testFn))
255+
attempts := []FailedAttempt{}
256+
dd, err := DiscoverWalk(app, hostHeaders, insecure, walker(&attempts, testFn))
255257
if err != nil && err != errEnough {
256258
return nil, attempts, err
257259
}
258260

259-
return out, attempts, nil
261+
return dd.Keys, attempts, nil
260262
}

0 commit comments

Comments
 (0)