Skip to content

Commit

Permalink
Merge pull request #62 from six-group/add_HSTS_header
Browse files Browse the repository at this point in the history
add HTTP Strict Transport Security (HSTS)
  • Loading branch information
xosk31 committed Jun 12, 2024
2 parents 84e0a18 + b9005c1 commit 49090da
Show file tree
Hide file tree
Showing 14 changed files with 1,170 additions and 232 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@ endef

GINKGO = ./bin/ginkgo
ginkgo-bin:
$(call go-get-tool,$(GINKGO),github.com/onsi/ginkgo/v2/ginkgo@v2.15.0)
$(call go-get-tool,$(GINKGO),github.com/onsi/ginkgo/v2/ginkgo@v2.19.0)
44 changes: 44 additions & 0 deletions apis/config/v1alpha1/common_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ type BaseSpec struct {
// +kubebuilder:default=http
// +kubebuilder:validation:Enum=http;tcp
Mode string `json:"mode"`
// HTTPResponse rules define a set of rules which apply to layer 7 processing.
// +optional
HTTPResponse *HTTPResponseRules `json:"httpResponse,omitempty"`
// HTTPRequest rules define a set of rules which apply to layer 7 processing.
// +optional
HTTPRequest *HTTPRequestRules `json:"httpRequest,omitempty"`
Expand Down Expand Up @@ -108,6 +111,25 @@ func (b *BaseSpec) AddToParser(p parser.Parser, sectionType parser.Section, sect
}
}

if b.HTTPResponse != nil {
rules, err := b.HTTPResponse.Model()
if err != nil {
return err
}
for idx, rule := range rules {
if rule != nil {
data, err := configuration.SerializeHTTPResponseRule(*rule)
if err != nil {
return err
}
err = p.Insert(sectionType, sectionName, "http-response", data, idx)
if err != nil {
return err
}
}
}
}

return nil
}

Expand Down Expand Up @@ -878,6 +900,28 @@ func (h *HTTPRequestRules) Model() (models.HTTPRequestRules, error) {
return model, model.Validate(strfmt.Default)
}

type HTTPResponseRules struct {
// SetHeader sets HTTP header fields
SetHeader []HTTPHeaderRule `json:"setHeader,omitempty"`
}

func (h *HTTPResponseRules) Model() (models.HTTPResponseRules, error) {
model := models.HTTPResponseRules{}

for idx, header := range h.SetHeader {
model = append(model, &models.HTTPResponseRule{
Type: "set-header",
Index: ptr.To(int64(idx)),
HdrName: header.Name,
HdrFormat: header.Value.String(),
Cond: header.ConditionType,
CondTest: header.Condition,
})
}

return model, model.Validate(strfmt.Default)
}

type HTTPReturn struct {
// Status can be optionally specified, the default status code used for the response is 200.
// +kubebuilder:default=200
Expand Down
22 changes: 22 additions & 0 deletions apis/config/v1alpha1/frontend_types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
. "github.com/onsi/gomega"
configv1alpha1 "github.com/six-group/haproxy-operator/apis/config/v1alpha1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/ptr"
)

var simpleFrontend = `
Expand Down Expand Up @@ -98,5 +99,26 @@ var _ = Describe("Frontend", Label("type"), func() {
}
Ω(frontend.AddToParser(p)).Should(HaveOccurred())
})
It("should set http response", func() {
frontend := &configv1alpha1.Frontend{
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
Spec: configv1alpha1.FrontendSpec{
BaseSpec: configv1alpha1.BaseSpec{
HTTPResponse: &configv1alpha1.HTTPResponseRules{
SetHeader: []configv1alpha1.HTTPHeaderRule{
{
Name: "Strict-Transport-Security",
Value: configv1alpha1.HTTPHeaderValue{
Str: ptr.To("max-age=16000000; includeSubDomains; preload;"),
},
},
},
},
},
},
}
Ω(frontend.AddToParser(p)).ShouldNot(HaveOccurred())
Ω(p.String()).Should(ContainSubstring("http-response set-header Strict-Transport-Security max-age=16000000; includeSubDomains; preload;"))
})
})
})
15 changes: 15 additions & 0 deletions apis/config/v1alpha1/listen_types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,20 @@ var _ = Describe("Listen", Label("type"), func() {
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
Spec: configv1alpha1.ListenSpec{
BaseSpec: configv1alpha1.BaseSpec{
HTTPResponse: &configv1alpha1.HTTPResponseRules{
SetHeader: []configv1alpha1.HTTPHeaderRule{
{
Rule: configv1alpha1.Rule{
ConditionType: "if",
Condition: "!{ ssl_fc }",
},
Name: "Strict-Transport-Security",
Value: configv1alpha1.HTTPHeaderValue{
Str: ptr.To("max-age=16000000; includeSubDomains; preload;"),
},
},
},
},
HTTPRequest: &configv1alpha1.HTTPRequestRules{
SetHeader: []configv1alpha1.HTTPHeaderRule{
{
Expand Down Expand Up @@ -119,6 +133,7 @@ var _ = Describe("Listen", Label("type"), func() {
Ω(p.String()).Should(ContainSubstring("http-request add-header X-Forwarded-Proto https"))
Ω(p.String()).Should(ContainSubstring("http-request add-header X-Forwarded-Proto-Version \"${PROTO_VERSION}\""))
Ω(p.String()).Should(ContainSubstring("http-request set-path /metrics if !{ ssl_fc }"))
Ω(p.String()).Should(ContainSubstring("http-response set-header Strict-Transport-Security max-age=16000000; includeSubDomains; preload; if !{ ssl_fc }"))
})
It("should create binds", func() {
listen := &configv1alpha1.Listen{
Expand Down
28 changes: 27 additions & 1 deletion apis/config/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion apis/proxy/v1alpha1/instance_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ type Metrics struct {
// RelabelConfigs to apply to samples before scraping.
// More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config
// +optional
RelabelConfigs []*monitoringv1.RelabelConfig `json:"relabelings,omitempty"`
RelabelConfigs []monitoringv1.RelabelConfig `json:"relabelings,omitempty"`
// Interval at which metrics should be scraped
// If not specified Prometheus' global scrape interval is used.
// +optional
Expand Down
14 changes: 7 additions & 7 deletions apis/proxy/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

75 changes: 37 additions & 38 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
module github.com/six-group/haproxy-operator

go 1.21
go 1.22.4

require (
github.com/go-logr/logr v1.4.1 // indirect
github.com/go-openapi/strfmt v0.22.0
github.com/haproxytech/client-native/v5 v5.1.2
github.com/haproxytech/config-parser/v5 v5.1.0
github.com/onsi/ginkgo/v2 v2.15.0
github.com/onsi/gomega v1.31.1
github.com/openshift/api v0.0.0-20231117205818-971e4ba78c9a // latest commit of branch https://github.com/openshift/api/tree/release-4.14
github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.71.2
github.com/go-openapi/strfmt v0.23.0
github.com/haproxytech/client-native/v5 v5.1.7
github.com/haproxytech/config-parser/v5 v5.1.4
github.com/onsi/ginkgo/v2 v2.19.0
github.com/onsi/gomega v1.33.1
github.com/openshift/api v0.0.0-20240611134040-5c2b46e4709a // latest commit of branch https://github.com/openshift/api/tree/release-4.18
github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.74.0
go.uber.org/multierr v1.11.0
go.uber.org/zap v1.26.0
k8s.io/api v0.29.0
k8s.io/apimachinery v0.29.0
k8s.io/client-go v0.29.0
k8s.io/klog/v2 v2.110.1
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect
k8s.io/utils v0.0.0-20231127182322-b307cd553661
sigs.k8s.io/controller-runtime v0.17.1
go.uber.org/zap v1.27.0
k8s.io/api v0.30.1
k8s.io/apimachinery v0.30.1
k8s.io/client-go v0.30.1
k8s.io/klog/v2 v2.120.1
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect
k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0
sigs.k8s.io/controller-runtime v0.18.3
)

require (
Expand All @@ -29,28 +29,28 @@ require (
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
github.com/evanphx/json-patch v5.6.0+incompatible // indirect
github.com/evanphx/json-patch/v5 v5.8.0 // indirect
github.com/evanphx/json-patch/v5 v5.9.0 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/go-logr/zapr v1.3.0 // indirect
github.com/go-openapi/analysis v0.22.0 // indirect
github.com/go-openapi/errors v0.21.0 // indirect
github.com/go-openapi/jsonpointer v0.20.2 // indirect
github.com/go-openapi/jsonreference v0.20.4 // indirect
github.com/go-openapi/loads v0.21.3 // indirect
github.com/go-openapi/spec v0.20.13 // indirect
github.com/go-openapi/swag v0.22.6 // indirect
github.com/go-openapi/validate v0.22.4 // indirect
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
github.com/go-openapi/analysis v0.23.0 // indirect
github.com/go-openapi/errors v0.22.0 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/jsonreference v0.21.0 // indirect
github.com/go-openapi/loads v0.22.0 // indirect
github.com/go-openapi/spec v0.21.0 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
github.com/go-openapi/validate v0.24.0 // indirect
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
github.com/gofrs/flock v0.8.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/gnostic-models v0.6.8 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect
github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 // indirect
github.com/google/renameio v1.0.1 // indirect
github.com/google/uuid v1.5.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/haproxytech/go-logger v1.1.0 // indirect
github.com/imdario/mergo v0.3.12 // indirect
github.com/josharian/intern v1.0.0 // indirect
Expand All @@ -69,23 +69,22 @@ require (
github.com/prometheus/common v0.45.0 // indirect
github.com/prometheus/procfs v0.12.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
go.mongodb.org/mongo-driver v1.13.1 // indirect
go.mongodb.org/mongo-driver v1.15.0 // indirect
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect
golang.org/x/net v0.19.0 // indirect
golang.org/x/net v0.25.0 // indirect
golang.org/x/oauth2 v0.12.0 // indirect
golang.org/x/sys v0.16.0 // indirect
golang.org/x/term v0.15.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/sys v0.20.0 // indirect
golang.org/x/term v0.20.0 // indirect
golang.org/x/text v0.15.0 // indirect
golang.org/x/time v0.3.0 // indirect
golang.org/x/tools v0.16.1 // indirect
golang.org/x/tools v0.21.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/protobuf v1.31.0 // indirect
google.golang.org/protobuf v1.33.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/apiextensions-apiserver v0.29.0 // indirect
k8s.io/component-base v0.29.0 // indirect
k8s.io/apiextensions-apiserver v0.30.1 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
Expand Down
Loading

0 comments on commit 49090da

Please sign in to comment.