Merge pull request #3240 from estaleiro/http2-push-preload

Adds support for HTTP2 Push Preload annotation
This commit is contained in:
Kubernetes Prow Robot 2018-12-24 12:05:47 -08:00 committed by GitHub
commit cac694ecce
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 174 additions and 0 deletions

View file

@ -46,6 +46,7 @@ You can add these Kubernetes annotations to specific Ingress objects to customiz
|[nginx.ingress.kubernetes.io/cors-max-age](#enable-cors)|number|
|[nginx.ingress.kubernetes.io/force-ssl-redirect](#server-side-https-enforcement-through-redirect)|"true" or "false"|
|[nginx.ingress.kubernetes.io/from-to-www-redirect](#redirect-from-to-www)|"true" or "false"|
|[nginx.ingress.kubernetes.io/http2-push-preload](#http2-push-preload)|"true" or "false"|
|[nginx.ingress.kubernetes.io/limit-connections](#rate-limiting)|number|
|[nginx.ingress.kubernetes.io/limit-rps](#rate-limiting)|number|
|[nginx.ingress.kubernetes.io/permanent-redirect](#permanent-redirect)|string|
@ -298,6 +299,14 @@ CORS can be controlled with the following annotations:
!!! note
For more information please see [https://enable-cors.org](https://enable-cors.org/server_nginx.html)
### HTTP2 Push Preload.
Enables automatic conversion of preload links specified in the “Link” response header fields into push requests.
!!! example
* `nginx.ingress.kubernetes.io/http2-push-preload: "true"`
### Server Alias
To add Server Aliases to an Ingress rule add the annotation `nginx.ingress.kubernetes.io/server-alias: "<alias>"`.

View file

@ -37,6 +37,7 @@ import (
"k8s.io/ingress-nginx/internal/ingress/annotations/cors"
"k8s.io/ingress-nginx/internal/ingress/annotations/customhttperrors"
"k8s.io/ingress-nginx/internal/ingress/annotations/defaultbackend"
"k8s.io/ingress-nginx/internal/ingress/annotations/http2pushpreload"
"k8s.io/ingress-nginx/internal/ingress/annotations/influxdb"
"k8s.io/ingress-nginx/internal/ingress/annotations/ipwhitelist"
"k8s.io/ingress-nginx/internal/ingress/annotations/loadbalancing"
@ -80,6 +81,7 @@ type Ingress struct {
DefaultBackend *apiv1.Service
Denied error
ExternalAuth authreq.Config
HTTP2PushPreload bool
Proxy proxy.Config
RateLimit ratelimit.Config
Redirect redirect.Config
@ -122,6 +124,7 @@ func NewAnnotationExtractor(cfg resolver.Resolver) Extractor {
"CustomHTTPErrors": customhttperrors.NewParser(cfg),
"DefaultBackend": defaultbackend.NewParser(cfg),
"ExternalAuth": authreq.NewParser(cfg),
"HTTP2PushPreload": http2pushpreload.NewParser(cfg),
"Proxy": proxy.NewParser(cfg),
"RateLimit": ratelimit.NewParser(cfg),
"Redirect": redirect.NewParser(cfg),

View file

@ -0,0 +1,39 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package http2pushpreload
import (
extensions "k8s.io/api/extensions/v1beta1"
"k8s.io/ingress-nginx/internal/ingress/annotations/parser"
"k8s.io/ingress-nginx/internal/ingress/resolver"
)
type http2PushPreload struct {
r resolver.Resolver
}
// NewParser creates a new http2PushPreload annotation parser
func NewParser(r resolver.Resolver) parser.IngressAnnotation {
return http2PushPreload{r}
}
// Parse parses the annotations contained in the ingress rule
// used to add http2 push preload to the server
func (h2pp http2PushPreload) Parse(ing *extensions.Ingress) (interface{}, error) {
return parser.GetBoolAnnotation("http2-push-preload", ing)
}

View file

@ -0,0 +1,62 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package http2pushpreload
import (
"testing"
api "k8s.io/api/core/v1"
extensions "k8s.io/api/extensions/v1beta1"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/ingress-nginx/internal/ingress/annotations/parser"
"k8s.io/ingress-nginx/internal/ingress/resolver"
)
func TestParse(t *testing.T) {
annotation := parser.GetAnnotationWithPrefix("http2-push-preload")
ap := NewParser(&resolver.Mock{})
if ap == nil {
t.Fatalf("expected a parser.IngressAnnotation but returned nil")
}
testCases := []struct {
annotations map[string]string
expected bool
}{
{map[string]string{annotation: "true"}, true},
{map[string]string{annotation: "1"}, true},
{map[string]string{annotation: ""}, false},
{map[string]string{}, false},
{nil, false},
}
ing := &extensions.Ingress{
ObjectMeta: meta_v1.ObjectMeta{
Name: "foo",
Namespace: api.NamespaceDefault,
},
Spec: extensions.IngressSpec{},
}
for _, testCase := range testCases {
ing.SetAnnotations(testCase.annotations)
result, _ := ap.Parse(ing)
if result != testCase.expected {
t.Errorf("expected %v but returned %v, annotations: %s", testCase.expected, result, testCase.annotations)
}
}
}

View file

@ -473,6 +473,7 @@ func (n *NGINXController) getBackendServers(ingresses []*ingress.Ingress) ([]*in
loc.ConfigurationSnippet = anns.ConfigurationSnippet
loc.CorsConfig = anns.CorsConfig
loc.ExternalAuth = anns.ExternalAuth
loc.HTTP2PushPreload = anns.HTTP2PushPreload
loc.Proxy = anns.Proxy
loc.RateLimit = anns.RateLimit
loc.Redirect = anns.Redirect

View file

@ -238,6 +238,10 @@ type Location struct {
// authentication using an external provider
// +optional
ExternalAuth authreq.Config `json:"externalAuth,omitempty"`
// HTTP2PushPreload allows to configure the HTTP2 Push Preload from backend
// original location.
// +optional
HTTP2PushPreload bool `json:"http2PushPreload,omitempty"`
// RateLimit describes a limit in the number of connections per IP
// address or connections per second.
// The Redirect annotation precedes RateLimit

View file

@ -374,6 +374,9 @@ func (l1 *Location) Equal(l2 *Location) bool {
if !(&l1.ExternalAuth).Equal(&l2.ExternalAuth) {
return false
}
if l1.HTTP2PushPreload != l2.HTTP2PushPreload {
return false
}
if !(&l1.RateLimit).Equal(&l2.RateLimit) {
return false
}

View file

@ -1122,6 +1122,10 @@ stream {
rewrite_log on;
{{ end }}
{{ if $location.HTTP2PushPreload }}
http2_push_preload on;
{{ end }}
port_in_redirect {{ if $location.UsePortInRedirects }}on{{ else }}off{{ end }};
set $proxy_upstream_name "{{ buildUpstreamName $location }}";

View file

@ -0,0 +1,49 @@
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package annotations
import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"k8s.io/ingress-nginx/test/e2e/framework"
)
var _ = framework.IngressNginxDescribe("Annotations - HTTP2 Push Preload", func() {
f := framework.NewDefaultFramework("http2pushpreload")
BeforeEach(func() {
f.NewEchoDeploymentWithReplicas(2)
})
AfterEach(func() {
})
It("enable the http2-push-preload directive", func() {
host := "http2pp.foo.com"
annotations := map[string]string{
"nginx.ingress.kubernetes.io/http2-push-preload": "true",
}
ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, &annotations)
f.EnsureIngress(ing)
f.WaitForNginxServer(host,
func(server string) bool {
return Expect(server).Should(ContainSubstring("http2_push_preload on;"))
})
})
})