diff --git a/discovery/discovery.go b/discovery/discovery.go
index 2160f60b..89c4d290 100644
--- a/discovery/discovery.go
+++ b/discovery/discovery.go
@@ -111,6 +111,9 @@ func renderTemplate(tpl string, kvs ...string) (string, bool) {
for i := 0; i < len(kvs); i += 2 {
k := kvs[i]
v := kvs[i+1]
+ if !strings.Contains(tpl, k) {
+ return tpl, false
+ }
tpl = strings.Replace(tpl, k, v, -1)
}
return tpl, !templateExpression.MatchString(tpl)
@@ -118,9 +121,11 @@ func renderTemplate(tpl string, kvs ...string) (string, bool) {
func createTemplateVars(app App) []string {
tplVars := []string{"{name}", app.Name.String()}
- // If a label is called "name", it will be ignored as it appears after
- // in the slice
+ // Ignore labels called "name"
for n, v := range app.Labels {
+ if n == "name" {
+ continue
+ }
tplVars = append(tplVars, fmt.Sprintf("{%s}", n), v)
}
return tplVars
@@ -151,13 +156,14 @@ func doDiscover(pre string, hostHeaders map[string]http.Header, app App, insecur
switch m.name {
case "ac-discovery":
- // Ignore not handled variables as {ext} isn't already rendered.
- uri, _ := renderTemplate(m.uri, tplVars...)
- asc, ok := renderTemplate(uri, "{ext}", "aci.asc")
+ // Ignore not handled variables as only {ext} has been rendered
+ aci, _ := renderTemplate(m.uri, "{ext}", "aci")
+ asc, _ := renderTemplate(m.uri, "{ext}", "aci.asc")
+ aci, ok := renderTemplate(aci, tplVars...)
if !ok {
continue
}
- aci, ok := renderTemplate(uri, "{ext}", "aci")
+ asc, ok = renderTemplate(asc, tplVars...)
if !ok {
continue
}
diff --git a/discovery/discovery_test.go b/discovery/discovery_test.go
index bb2ca254..10d7901c 100644
--- a/discovery/discovery_test.go
+++ b/discovery/discovery_test.go
@@ -460,7 +460,9 @@ func TestDiscoverEndpoints(t *testing.T) {
[]string{"https://example.com/pubkeys.gpg"},
nil,
},
- // Test multiple ACIEndpoints.
+ // Test multiple endpoints.
+ // Should render two endpoint, since ''
+ // doesn't contain all the required labels
{
&mockHTTPDoer{
doer: fakeHTTPGet(
@@ -487,10 +489,6 @@ func TestDiscoverEndpoints(t *testing.T) {
ACI: "https://storage.example.com/example.com/myapp-1.0.0-linux-amd64.aci",
ASC: "https://storage.example.com/example.com/myapp-1.0.0-linux-amd64.aci.asc",
},
- ACIEndpoint{
- ACI: "https://storage.example.com/example.com/myapp-1.0.0.aci",
- ASC: "https://storage.example.com/example.com/myapp-1.0.0.aci.asc",
- },
ACIEndpoint{
ACI: "hdfs://storage.example.com/example.com/myapp-1.0.0-linux-amd64.aci",
ASC: "hdfs://storage.example.com/example.com/myapp-1.0.0-linux-amd64.aci.asc",
diff --git a/spec/discovery.md b/spec/discovery.md
index b5033ef3..1a671c58 100644
--- a/spec/discovery.md
+++ b/spec/discovery.md
@@ -59,6 +59,17 @@ curl $(echo "$urltmpl" | sed -e "s/{name}/$name/" -e "s/{version}/$version/" -e
where _name_, _version_, _os_, and _arch_ are set to their respective values for the image, and _ext_ is either `aci` or `aci.asc` for retrieving an App Container Image or signature respectively.
+The client MUST accept only templates that can be fully substituted and that satisfy all the required labels.
+
+For example given these meta tags:
+```html
+
+
+```
+
+If the client requires the labels _name_, _version_, _os_, _arch_ only the first template will be rendered since the second doesn't satisfy the _version_ label.
+If the client requires the labels _name_, _os_, _arch_ only the second template will be rendered since in the first template '{version}' cannot be substituted.
+
Note that multiple `ac-discovery` tags MAY be returned for a given prefix-match (for example, with different scheme names representing different transport mechanisms).
In this case, the client implementation MAY choose which to use at its own discretion.
Public discovery implementations SHOULD always provide at least one HTTPS URL template.