Disable user snippets per default (#10393)

* Disable user snippets per default

* Enable snippet on tests
This commit is contained in:
Ricardo Katz 2023-09-11 00:02:10 -03:00 committed by GitHub
parent 121b97a734
commit 6b132ac9b1
35 changed files with 494 additions and 288 deletions

1
.gitignore vendored
View file

@ -60,3 +60,4 @@ cmd/plugin/release/ingress-nginx.yaml
cmd/plugin/release/*.tar.gz cmd/plugin/release/*.tar.gz
cmd/plugin/release/LICENSE cmd/plugin/release/LICENSE
tmp/ tmp/
test/junitreports/

View file

@ -274,7 +274,7 @@ As of version `1.26.0` of this chart, by simply not providing any clusterIP valu
| controller.admissionWebhooks.service.servicePort | int | `443` | | | controller.admissionWebhooks.service.servicePort | int | `443` | |
| controller.admissionWebhooks.service.type | string | `"ClusterIP"` | | | controller.admissionWebhooks.service.type | string | `"ClusterIP"` | |
| controller.affinity | object | `{}` | Affinity and anti-affinity rules for server scheduling to nodes # Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity # | | controller.affinity | object | `{}` | Affinity and anti-affinity rules for server scheduling to nodes # Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity # |
| controller.allowSnippetAnnotations | bool | `true` | This configuration defines if Ingress Controller should allow users to set their own *-snippet annotations, otherwise this is forbidden / dropped when users add those annotations. Global snippets in ConfigMap are still respected | | controller.allowSnippetAnnotations | bool | `false` | This configuration defines if Ingress Controller should allow users to set their own *-snippet annotations, otherwise this is forbidden / dropped when users add those annotations. Global snippets in ConfigMap are still respected |
| controller.annotations | object | `{}` | Annotations to be added to the controller Deployment or DaemonSet # | | controller.annotations | object | `{}` | Annotations to be added to the controller Deployment or DaemonSet # |
| controller.autoscaling.annotations | object | `{}` | | | controller.autoscaling.annotations | object | `{}` | |
| controller.autoscaling.behavior | object | `{}` | | | controller.autoscaling.behavior | object | `{}` | |

View file

@ -81,7 +81,7 @@ controller:
# their own *-snippet annotations, otherwise this is forbidden / dropped # their own *-snippet annotations, otherwise this is forbidden / dropped
# when users add those annotations. # when users add those annotations.
# Global snippets in ConfigMap are still respected # Global snippets in ConfigMap are still respected
allowSnippetAnnotations: true allowSnippetAnnotations: false
# -- Required for use with CNI based kubernetes installations (such as ones set up by kubeadm), # -- Required for use with CNI based kubernetes installations (such as ones set up by kubeadm),
# since CNI and hostport don't mix yet. Can be deprecated once https://github.com/kubernetes/kubernetes/issues/23920 # since CNI and hostport don't mix yet. Can be deprecated once https://github.com/kubernetes/kubernetes/issues/23920
# is merged # is merged

View file

@ -29,8 +29,8 @@ import (
// The default deployment and service names for ingress-nginx // The default deployment and service names for ingress-nginx
const ( const (
DefaultIngressDeploymentName = "ingress-nginx-controller" DefaultIngressDeploymentName = "ingress-nginx-controller" //#nosec G101
DefaultIngressServiceName = "ingress-nginx-controller" DefaultIngressServiceName = "ingress-nginx-controller" //#nosec G101
DefaultIngressContainerName = "controller" DefaultIngressContainerName = "controller"
) )

View file

@ -30,7 +30,7 @@ The following table shows a configuration option's name, type, and the default v
|[add-headers](#add-headers)|string|""|| |[add-headers](#add-headers)|string|""||
|[allow-backend-server-header](#allow-backend-server-header)|bool|"false"|| |[allow-backend-server-header](#allow-backend-server-header)|bool|"false"||
|[allow-cross-namespace-resources](#allow-cross-namespace-resources)|bool|"true"|| |[allow-cross-namespace-resources](#allow-cross-namespace-resources)|bool|"true"||
|[allow-snippet-annotations](#allow-snippet-annotations)|bool|true|| |[allow-snippet-annotations](#allow-snippet-annotations)|bool|false||
|[annotations-risk-level](#annotations-risk-level)|string|Critical|| |[annotations-risk-level](#annotations-risk-level)|string|Critical||
|[annotation-value-word-blocklist](#annotation-value-word-blocklist)|string array|""|| |[annotation-value-word-blocklist](#annotation-value-word-blocklist)|string array|""||
|[hide-headers](#hide-headers)|string array|empty|| |[hide-headers](#hide-headers)|string array|empty||
@ -257,7 +257,7 @@ Enables users to consume cross namespace resource on annotations, when was previ
## allow-snippet-annotations ## allow-snippet-annotations
Enables Ingress to parse and add *-snippet annotations/directives created by the user. _**default:**_ `true` Enables Ingress to parse and add *-snippet annotations/directives created by the user. _**default:**_ `false`
Warning: We recommend enabling this option only if you TRUST users with permission to create Ingress objects, as this Warning: We recommend enabling this option only if you TRUST users with permission to create Ingress objects, as this
may allow a user to add restricted configurations to the final nginx.conf file may allow a user to add restricted configurations to the final nginx.conf file

View file

@ -32,7 +32,7 @@ import (
const ( const (
fastCGIIndexAnnotation = "fastcgi-index" fastCGIIndexAnnotation = "fastcgi-index"
fastCGIParamsAnnotation = "fastcgi-params-configmap" fastCGIParamsAnnotation = "fastcgi-params-configmap" //#nosec G101
) )
// fast-cgi valid parameters is just a single file name (like index.php) // fast-cgi valid parameters is just a single file name (like index.php)

View file

@ -67,7 +67,7 @@ func TestParse(t *testing.T) {
Spec: networking.IngressSpec{}, Spec: networking.IngressSpec{},
} }
for _, testCase := range testCases { for i, testCase := range testCases {
ing.SetAnnotations(testCase.annotations) ing.SetAnnotations(testCase.annotations)
result, err := ap.Parse(ing) result, err := ap.Parse(ing)
if err != nil { if err != nil {
@ -77,7 +77,7 @@ func TestParse(t *testing.T) {
if !ok { if !ok {
t.Errorf("unexpected type: %T", result) t.Errorf("unexpected type: %T", result)
} }
if !config.Equal(&testCase.expected) { if !config.Equal(&testCases[i].expected) {
t.Errorf("expected %v but returned %v, annotations: %s", testCase.expected, result, testCase.annotations) t.Errorf("expected %v but returned %v, annotations: %s", testCase.expected, result, testCase.annotations)
} }
} }

View file

@ -42,7 +42,7 @@ const (
proxyRedirectToAnnotation = "proxy-redirect-to" proxyRedirectToAnnotation = "proxy-redirect-to"
proxyBufferingAnnotation = "proxy-buffering" proxyBufferingAnnotation = "proxy-buffering"
proxyHTTPVersionAnnotation = "proxy-http-version" proxyHTTPVersionAnnotation = "proxy-http-version"
proxyMaxTempFileSizeAnnotation = "proxy-max-temp-file-size" proxyMaxTempFileSizeAnnotation = "proxy-max-temp-file-size" //#nosec G101
) )
var validUpstreamAnnotation = regexp.MustCompile(`^((error|timeout|invalid_header|http_500|http_502|http_503|http_504|http_403|http_404|http_429|non_idempotent|off)\s?)+$`) var validUpstreamAnnotation = regexp.MustCompile(`^((error|timeout|invalid_header|http_500|http_502|http_503|http_504|http_403|http_404|http_429|non_idempotent|off)\s?)+$`)

View file

@ -64,13 +64,13 @@ func TestParse(t *testing.T) {
Spec: networking.IngressSpec{}, Spec: networking.IngressSpec{},
} }
for _, testCase := range testCases { for i, testCase := range testCases {
ing.SetAnnotations(testCase.annotations) ing.SetAnnotations(testCase.annotations)
result, err := ap.Parse(ing) result, err := ap.Parse(ing)
if (err != nil) != testCase.expectErr { if (err != nil) != testCase.expectErr {
t.Fatalf("expected error: %t got error: %t err value: %s. %+v", testCase.expectErr, err != nil, err, testCase.annotations) t.Fatalf("expected error: %t got error: %t err value: %s. %+v", testCase.expectErr, err != nil, err, testCase.annotations)
} }
if !reflect.DeepEqual(result, &testCase.expected) { if !reflect.DeepEqual(result, &testCases[i].expected) {
t.Errorf("expected %v but returned %v, annotations: %s", testCase.expected, result, testCase.annotations) t.Errorf("expected %v but returned %v, annotations: %s", testCase.expected, result, testCase.annotations)
} }
} }

View file

@ -865,7 +865,7 @@ func NewDefault() Configuration {
defGlobalExternalAuth := GlobalExternalAuth{"", "", "", "", "", append(defResponseHeaders, ""), "", "", "", []string{}, map[string]string{}, false} defGlobalExternalAuth := GlobalExternalAuth{"", "", "", "", "", append(defResponseHeaders, ""), "", "", "", []string{}, map[string]string{}, false}
cfg := Configuration{ cfg := Configuration{
AllowSnippetAnnotations: true, AllowSnippetAnnotations: false,
AllowCrossNamespaceResources: true, AllowCrossNamespaceResources: true,
AllowBackendServerHeader: false, AllowBackendServerHeader: false,
AnnotationValueWordBlocklist: "", AnnotationValueWordBlocklist: "",

View file

@ -1057,7 +1057,7 @@ func (n *NGINXController) createUpstreams(data []*ingress.Ingress, du *ingress.B
continue continue
} }
for _, path := range rule.HTTP.Paths { for i, path := range rule.HTTP.Paths {
if path.Backend.Service == nil { if path.Backend.Service == nil {
// skip non-service backends // skip non-service backends
klog.V(3).Infof("Ingress %q and path %q does not contain a service backend, using default backend", ingKey, path.Path) klog.V(3).Infof("Ingress %q and path %q does not contain a service backend, using default backend", ingKey, path.Path)
@ -1087,7 +1087,7 @@ func (n *NGINXController) createUpstreams(data []*ingress.Ingress, du *ingress.B
// add the service ClusterIP as a single Endpoint instead of individual Endpoints // add the service ClusterIP as a single Endpoint instead of individual Endpoints
if anns.ServiceUpstream { if anns.ServiceUpstream {
endpoint, err := n.getServiceClusterEndpoint(svcKey, &path.Backend) endpoint, err := n.getServiceClusterEndpoint(svcKey, &rule.HTTP.Paths[i].Backend)
if err != nil { if err != nil {
klog.Errorf("Failed to determine a suitable ClusterIP Endpoint for Service %q: %v", svcKey, err) klog.Errorf("Failed to determine a suitable ClusterIP Endpoint for Service %q: %v", svcKey, err)
} else { } else {
@ -1844,7 +1844,7 @@ func ingressForHostPath(hostname, path string, servers []*ingress.Server) []*net
continue continue
} }
for _, location := range server.Locations { for i, location := range server.Locations {
if location.Path != path { if location.Path != path {
continue continue
} }
@ -1853,7 +1853,7 @@ func ingressForHostPath(hostname, path string, servers []*ingress.Server) []*net
continue continue
} }
ingresses = append(ingresses, &location.Ingress.Ingress) ingresses = append(ingresses, &server.Locations[i].Ingress.Ingress)
} }
} }

View file

@ -17,4 +17,4 @@ limitations under the License.
package collectors package collectors
// PrometheusNamespace default metric namespace // PrometheusNamespace default metric namespace
var PrometheusNamespace = "nginx_ingress_controller" var PrometheusNamespace = "nginx_ingress_controller" //#nosec G101

View file

@ -55,7 +55,7 @@ var FakeSSLCertificateUID = "00000000-0000-0000-0000-000000000000"
var oidExtensionSubjectAltName = asn1.ObjectIdentifier{2, 5, 29, 17} var oidExtensionSubjectAltName = asn1.ObjectIdentifier{2, 5, 29, 17}
const ( const (
fakeCertificateName = "default-fake-certificate" fakeCertificateName = "default-fake-certificate" //#nosec G101
) )
// getPemFileName returns absolute file path and file name of pem cert related to given fullSecretName // getPemFileName returns absolute file path and file name of pem cert related to given fullSecretName

View file

@ -32,8 +32,10 @@ import (
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
) )
const HelmChartPath = "charts/ingress-nginx/Chart.yaml" const (
const HelmChartValues = "charts/ingress-nginx/values.yaml" HelmChartPath = "charts/ingress-nginx/Chart.yaml"
HelmChartValues = "charts/ingress-nginx/values.yaml"
)
type Helm mg.Namespace type Helm mg.Namespace
@ -43,7 +45,6 @@ func (Helm) UpdateAppVersion() {
} }
func updateAppVersion() { func updateAppVersion() {
} }
// UpdateVersion Update Helm Version of the Chart // UpdateVersion Update Helm Version of the Chart
@ -113,7 +114,6 @@ func updateChartReleaseNotes(releasesNotes []string) {
} }
func UpdateChartChangelog() { func UpdateChartChangelog() {
} }
// UpdateChartValue Updates the Helm ChartValue // UpdateChartValue Updates the Helm ChartValue
@ -152,7 +152,7 @@ func updateChartValue(key, value string) {
yamlEncoder.SetIndent(2) yamlEncoder.SetIndent(2)
err = yamlEncoder.Encode(&n) err = yamlEncoder.Encode(&n)
CheckIfError(err, "HELM Could not Marshal new Values file") CheckIfError(err, "HELM Could not Marshal new Values file")
err = os.WriteFile(HelmChartValues, b.Bytes(), 0644) err = os.WriteFile(HelmChartValues, b.Bytes(), 0o644)
CheckIfError(err, "HELM Could not write new Values file to %s", HelmChartValues) CheckIfError(err, "HELM Could not write new Values file to %s", HelmChartValues)
Info("HELM Ingress Nginx Helm Chart update %s %s", key, value) Info("HELM Ingress Nginx Helm Chart update %s %s", key, value)
@ -161,6 +161,7 @@ func updateChartValue(key, value string) {
func (Helm) Helmdocs() error { func (Helm) Helmdocs() error {
return runHelmDocs() return runHelmDocs()
} }
func runHelmDocs() error { func runHelmDocs() error {
err := installHelmDocs() err := installHelmDocs()
if err != nil { if err != nil {
@ -175,7 +176,7 @@ func runHelmDocs() error {
func installHelmDocs() error { func installHelmDocs() error {
Info("HELM Install HelmDocs") Info("HELM Install HelmDocs")
var g0 = sh.RunCmd("go") g0 := sh.RunCmd("go")
err := g0("install", "github.com/norwoodj/helm-docs/cmd/helm-docs@v1.11.0") err := g0("install", "github.com/norwoodj/helm-docs/cmd/helm-docs@v1.11.0")
if err != nil { if err != nil {
@ -186,12 +187,10 @@ func installHelmDocs() error {
func parsePath(key string) []string { return strings.Split(key, ".") } func parsePath(key string) []string { return strings.Split(key, ".") }
func updateHelmDocs() { func updateHelmDocs() {
} }
type IngressChartValue struct { type IngressChartValue struct {
CommonLabels struct { CommonLabels struct{} `yaml:"commonLabels"`
} `yaml:"commonLabels"`
Controller struct { Controller struct {
Name string `yaml:"name"` Name string `yaml:"name"`
Image struct { Image struct {
@ -211,18 +210,12 @@ type IngressChartValue struct {
HTTP int `yaml:"http"` HTTP int `yaml:"http"`
HTTPS int `yaml:"https"` HTTPS int `yaml:"https"`
} `yaml:"containerPort"` } `yaml:"containerPort"`
Config struct { Config struct{} `yaml:"config"`
} `yaml:"config"` ConfigAnnotations struct{} `yaml:"configAnnotations"`
ConfigAnnotations struct { ProxySetHeaders struct{} `yaml:"proxySetHeaders"`
} `yaml:"configAnnotations"` AddHeaders struct{} `yaml:"addHeaders"`
ProxySetHeaders struct { DNSConfig struct{} `yaml:"dnsConfig"`
} `yaml:"proxySetHeaders"` Hostname struct{} `yaml:"hostname"`
AddHeaders struct {
} `yaml:"addHeaders"`
DNSConfig struct {
} `yaml:"dnsConfig"`
Hostname struct {
} `yaml:"hostname"`
DNSPolicy string `yaml:"dnsPolicy"` DNSPolicy string `yaml:"dnsPolicy"`
ReportNodeInternalIP bool `yaml:"reportNodeInternalIp"` ReportNodeInternalIP bool `yaml:"reportNodeInternalIp"`
WatchIngressWithoutClass bool `yaml:"watchIngressWithoutClass"` WatchIngressWithoutClass bool `yaml:"watchIngressWithoutClass"`
@ -242,16 +235,12 @@ type IngressChartValue struct {
Enabled bool `yaml:"enabled"` Enabled bool `yaml:"enabled"`
Default bool `yaml:"default"` Default bool `yaml:"default"`
ControllerValue string `yaml:"controllerValue"` ControllerValue string `yaml:"controllerValue"`
Parameters struct { Parameters struct{} `yaml:"parameters"`
} `yaml:"parameters"`
} `yaml:"ingressClassResource"` } `yaml:"ingressClassResource"`
IngressClass string `yaml:"ingressClass"` IngressClass string `yaml:"ingressClass"`
PodLabels struct { PodLabels struct{} `yaml:"podLabels"`
} `yaml:"podLabels"` PodSecurityContext struct{} `yaml:"podSecurityContext"`
PodSecurityContext struct { Sysctls struct{} `yaml:"sysctls"`
} `yaml:"podSecurityContext"`
Sysctls struct {
} `yaml:"sysctls"`
PublishService struct { PublishService struct {
Enabled bool `yaml:"enabled"` Enabled bool `yaml:"enabled"`
PathOverride string `yaml:"pathOverride"` PathOverride string `yaml:"pathOverride"`
@ -264,29 +253,22 @@ type IngressChartValue struct {
ConfigMapNamespace string `yaml:"configMapNamespace"` ConfigMapNamespace string `yaml:"configMapNamespace"`
TCP struct { TCP struct {
ConfigMapNamespace string `yaml:"configMapNamespace"` ConfigMapNamespace string `yaml:"configMapNamespace"`
Annotations struct { Annotations struct{} `yaml:"annotations"`
} `yaml:"annotations"`
} `yaml:"tcp"` } `yaml:"tcp"`
UDP struct { UDP struct {
ConfigMapNamespace string `yaml:"configMapNamespace"` ConfigMapNamespace string `yaml:"configMapNamespace"`
Annotations struct { Annotations struct{} `yaml:"annotations"`
} `yaml:"annotations"`
} `yaml:"udp"` } `yaml:"udp"`
MaxmindLicenseKey string `yaml:"maxmindLicenseKey"` MaxmindLicenseKey string `yaml:"maxmindLicenseKey"`
ExtraArgs struct { ExtraArgs struct{} `yaml:"extraArgs"`
} `yaml:"extraArgs"`
ExtraEnvs []interface{} `yaml:"extraEnvs"` ExtraEnvs []interface{} `yaml:"extraEnvs"`
Kind string `yaml:"kind"` Kind string `yaml:"kind"`
Annotations struct { Annotations struct{} `yaml:"annotations"`
} `yaml:"annotations"` Labels struct{} `yaml:"labels"`
Labels struct { UpdateStrategy struct{} `yaml:"updateStrategy"`
} `yaml:"labels"`
UpdateStrategy struct {
} `yaml:"updateStrategy"`
MinReadySeconds int `yaml:"minReadySeconds"` MinReadySeconds int `yaml:"minReadySeconds"`
Tolerations []interface{} `yaml:"tolerations"` Tolerations []interface{} `yaml:"tolerations"`
Affinity struct { Affinity struct{} `yaml:"affinity"`
} `yaml:"affinity"`
TopologySpreadConstraints []interface{} `yaml:"topologySpreadConstraints"` TopologySpreadConstraints []interface{} `yaml:"topologySpreadConstraints"`
TerminationGracePeriodSeconds int `yaml:"terminationGracePeriodSeconds"` TerminationGracePeriodSeconds int `yaml:"terminationGracePeriodSeconds"`
NodeSelector struct { NodeSelector struct {
@ -318,8 +300,7 @@ type IngressChartValue struct {
} `yaml:"readinessProbe"` } `yaml:"readinessProbe"`
HealthCheckPath string `yaml:"healthCheckPath"` HealthCheckPath string `yaml:"healthCheckPath"`
HealthCheckHost string `yaml:"healthCheckHost"` HealthCheckHost string `yaml:"healthCheckHost"`
PodAnnotations struct { PodAnnotations struct{} `yaml:"podAnnotations"`
} `yaml:"podAnnotations"`
ReplicaCount int `yaml:"replicaCount"` ReplicaCount int `yaml:"replicaCount"`
MinAvailable int `yaml:"minAvailable"` MinAvailable int `yaml:"minAvailable"`
Resources struct { Resources struct {
@ -331,14 +312,12 @@ type IngressChartValue struct {
Autoscaling struct { Autoscaling struct {
APIVersion string `yaml:"apiVersion"` APIVersion string `yaml:"apiVersion"`
Enabled bool `yaml:"enabled"` Enabled bool `yaml:"enabled"`
Annotations struct { Annotations struct{} `yaml:"annotations"`
} `yaml:"annotations"`
MinReplicas int `yaml:"minReplicas"` MinReplicas int `yaml:"minReplicas"`
MaxReplicas int `yaml:"maxReplicas"` MaxReplicas int `yaml:"maxReplicas"`
TargetCPUUtilizationPercentage int `yaml:"targetCPUUtilizationPercentage"` TargetCPUUtilizationPercentage int `yaml:"targetCPUUtilizationPercentage"`
TargetMemoryUtilizationPercentage int `yaml:"targetMemoryUtilizationPercentage"` TargetMemoryUtilizationPercentage int `yaml:"targetMemoryUtilizationPercentage"`
Behavior struct { Behavior struct{} `yaml:"behavior"`
} `yaml:"behavior"`
} `yaml:"autoscaling"` } `yaml:"autoscaling"`
AutoscalingTemplate []interface{} `yaml:"autoscalingTemplate"` AutoscalingTemplate []interface{} `yaml:"autoscalingTemplate"`
Keda struct { Keda struct {
@ -350,12 +329,10 @@ type IngressChartValue struct {
CooldownPeriod int `yaml:"cooldownPeriod"` CooldownPeriod int `yaml:"cooldownPeriod"`
RestoreToOriginalReplicaCount bool `yaml:"restoreToOriginalReplicaCount"` RestoreToOriginalReplicaCount bool `yaml:"restoreToOriginalReplicaCount"`
ScaledObject struct { ScaledObject struct {
Annotations struct { Annotations struct{} `yaml:"annotations"`
} `yaml:"annotations"`
} `yaml:"scaledObject"` } `yaml:"scaledObject"`
Triggers []interface{} `yaml:"triggers"` Triggers []interface{} `yaml:"triggers"`
Behavior struct { Behavior struct{} `yaml:"behavior"`
} `yaml:"behavior"`
} `yaml:"keda"` } `yaml:"keda"`
EnableMimalloc bool `yaml:"enableMimalloc"` EnableMimalloc bool `yaml:"enableMimalloc"`
CustomTemplate struct { CustomTemplate struct {
@ -365,10 +342,8 @@ type IngressChartValue struct {
Service struct { Service struct {
Enabled bool `yaml:"enabled"` Enabled bool `yaml:"enabled"`
AppProtocol bool `yaml:"appProtocol"` AppProtocol bool `yaml:"appProtocol"`
Annotations struct { Annotations struct{} `yaml:"annotations"`
} `yaml:"annotations"` Labels struct{} `yaml:"labels"`
Labels struct {
} `yaml:"labels"`
ExternalIPs []interface{} `yaml:"externalIPs"` ExternalIPs []interface{} `yaml:"externalIPs"`
LoadBalancerIP string `yaml:"loadBalancerIP"` LoadBalancerIP string `yaml:"loadBalancerIP"`
LoadBalancerSourceRanges []interface{} `yaml:"loadBalancerSourceRanges"` LoadBalancerSourceRanges []interface{} `yaml:"loadBalancerSourceRanges"`
@ -388,18 +363,15 @@ type IngressChartValue struct {
NodePorts struct { NodePorts struct {
HTTP string `yaml:"http"` HTTP string `yaml:"http"`
HTTPS string `yaml:"https"` HTTPS string `yaml:"https"`
TCP struct { TCP struct{} `yaml:"tcp"`
} `yaml:"tcp"` UDP struct{} `yaml:"udp"`
UDP struct {
} `yaml:"udp"`
} `yaml:"nodePorts"` } `yaml:"nodePorts"`
External struct { External struct {
Enabled bool `yaml:"enabled"` Enabled bool `yaml:"enabled"`
} `yaml:"external"` } `yaml:"external"`
Internal struct { Internal struct {
Enabled bool `yaml:"enabled"` Enabled bool `yaml:"enabled"`
Annotations struct { Annotations struct{} `yaml:"annotations"`
} `yaml:"annotations"`
LoadBalancerSourceRanges []interface{} `yaml:"loadBalancerSourceRanges"` LoadBalancerSourceRanges []interface{} `yaml:"loadBalancerSourceRanges"`
} `yaml:"internal"` } `yaml:"internal"`
} `yaml:"service"` } `yaml:"service"`
@ -417,25 +389,20 @@ type IngressChartValue struct {
} `yaml:"containerSecurityContext"` } `yaml:"containerSecurityContext"`
} `yaml:"opentelemetry"` } `yaml:"opentelemetry"`
AdmissionWebhooks struct { AdmissionWebhooks struct {
Annotations struct { Annotations struct{} `yaml:"annotations"`
} `yaml:"annotations"`
Enabled bool `yaml:"enabled"` Enabled bool `yaml:"enabled"`
ExtraEnvs []interface{} `yaml:"extraEnvs"` ExtraEnvs []interface{} `yaml:"extraEnvs"`
FailurePolicy string `yaml:"failurePolicy"` FailurePolicy string `yaml:"failurePolicy"`
Port int `yaml:"port"` Port int `yaml:"port"`
Certificate string `yaml:"certificate"` Certificate string `yaml:"certificate"`
Key string `yaml:"key"` Key string `yaml:"key"`
NamespaceSelector struct { NamespaceSelector struct{} `yaml:"namespaceSelector"`
} `yaml:"namespaceSelector"` ObjectSelector struct{} `yaml:"objectSelector"`
ObjectSelector struct { Labels struct{} `yaml:"labels"`
} `yaml:"objectSelector"`
Labels struct {
} `yaml:"labels"`
ExistingPsp string `yaml:"existingPsp"` ExistingPsp string `yaml:"existingPsp"`
NetworkPolicyEnabled bool `yaml:"networkPolicyEnabled"` NetworkPolicyEnabled bool `yaml:"networkPolicyEnabled"`
Service struct { Service struct {
Annotations struct { Annotations struct{} `yaml:"annotations"`
} `yaml:"annotations"`
ExternalIPs []interface{} `yaml:"externalIPs"` ExternalIPs []interface{} `yaml:"externalIPs"`
LoadBalancerSourceRanges []interface{} `yaml:"loadBalancerSourceRanges"` LoadBalancerSourceRanges []interface{} `yaml:"loadBalancerSourceRanges"`
ServicePort int `yaml:"servicePort"` ServicePort int `yaml:"servicePort"`
@ -445,15 +412,13 @@ type IngressChartValue struct {
SecurityContext struct { SecurityContext struct {
AllowPrivilegeEscalation bool `yaml:"allowPrivilegeEscalation"` AllowPrivilegeEscalation bool `yaml:"allowPrivilegeEscalation"`
} `yaml:"securityContext"` } `yaml:"securityContext"`
Resources struct { Resources struct{} `yaml:"resources"`
} `yaml:"resources"`
} `yaml:"createSecretJob"` } `yaml:"createSecretJob"`
PatchWebhookJob struct { PatchWebhookJob struct {
SecurityContext struct { SecurityContext struct {
AllowPrivilegeEscalation bool `yaml:"allowPrivilegeEscalation"` AllowPrivilegeEscalation bool `yaml:"allowPrivilegeEscalation"`
} `yaml:"securityContext"` } `yaml:"securityContext"`
Resources struct { Resources struct{} `yaml:"resources"`
} `yaml:"resources"`
} `yaml:"patchWebhookJob"` } `yaml:"patchWebhookJob"`
Patch struct { Patch struct {
Enabled bool `yaml:"enabled"` Enabled bool `yaml:"enabled"`
@ -465,14 +430,12 @@ type IngressChartValue struct {
PullPolicy string `yaml:"pullPolicy"` PullPolicy string `yaml:"pullPolicy"`
} `yaml:"image"` } `yaml:"image"`
PriorityClassName string `yaml:"priorityClassName"` PriorityClassName string `yaml:"priorityClassName"`
PodAnnotations struct { PodAnnotations struct{} `yaml:"podAnnotations"`
} `yaml:"podAnnotations"`
NodeSelector struct { NodeSelector struct {
KubernetesIoOs string `yaml:"kubernetes.io/os"` KubernetesIoOs string `yaml:"kubernetes.io/os"`
} `yaml:"nodeSelector"` } `yaml:"nodeSelector"`
Tolerations []interface{} `yaml:"tolerations"` Tolerations []interface{} `yaml:"tolerations"`
Labels struct { Labels struct{} `yaml:"labels"`
} `yaml:"labels"`
SecurityContext struct { SecurityContext struct {
RunAsNonRoot bool `yaml:"runAsNonRoot"` RunAsNonRoot bool `yaml:"runAsNonRoot"`
RunAsUser int `yaml:"runAsUser"` RunAsUser int `yaml:"runAsUser"`
@ -494,8 +457,7 @@ type IngressChartValue struct {
PortName string `yaml:"portName"` PortName string `yaml:"portName"`
Enabled bool `yaml:"enabled"` Enabled bool `yaml:"enabled"`
Service struct { Service struct {
Annotations struct { Annotations struct{} `yaml:"annotations"`
} `yaml:"annotations"`
ExternalIPs []interface{} `yaml:"externalIPs"` ExternalIPs []interface{} `yaml:"externalIPs"`
LoadBalancerSourceRanges []interface{} `yaml:"loadBalancerSourceRanges"` LoadBalancerSourceRanges []interface{} `yaml:"loadBalancerSourceRanges"`
ServicePort int `yaml:"servicePort"` ServicePort int `yaml:"servicePort"`
@ -503,11 +465,9 @@ type IngressChartValue struct {
} `yaml:"service"` } `yaml:"service"`
ServiceMonitor struct { ServiceMonitor struct {
Enabled bool `yaml:"enabled"` Enabled bool `yaml:"enabled"`
AdditionalLabels struct { AdditionalLabels struct{} `yaml:"additionalLabels"`
} `yaml:"additionalLabels"`
Namespace string `yaml:"namespace"` Namespace string `yaml:"namespace"`
NamespaceSelector struct { NamespaceSelector struct{} `yaml:"namespaceSelector"`
} `yaml:"namespaceSelector"`
ScrapeInterval string `yaml:"scrapeInterval"` ScrapeInterval string `yaml:"scrapeInterval"`
TargetLabels []interface{} `yaml:"targetLabels"` TargetLabels []interface{} `yaml:"targetLabels"`
Relabelings []interface{} `yaml:"relabelings"` Relabelings []interface{} `yaml:"relabelings"`
@ -515,8 +475,7 @@ type IngressChartValue struct {
} `yaml:"serviceMonitor"` } `yaml:"serviceMonitor"`
PrometheusRule struct { PrometheusRule struct {
Enabled bool `yaml:"enabled"` Enabled bool `yaml:"enabled"`
AdditionalLabels struct { AdditionalLabels struct{} `yaml:"additionalLabels"`
} `yaml:"additionalLabels"`
Rules []interface{} `yaml:"rules"` Rules []interface{} `yaml:"rules"`
} `yaml:"prometheusRule"` } `yaml:"prometheusRule"`
} `yaml:"metrics"` } `yaml:"metrics"`
@ -544,8 +503,7 @@ type IngressChartValue struct {
AllowPrivilegeEscalation bool `yaml:"allowPrivilegeEscalation"` AllowPrivilegeEscalation bool `yaml:"allowPrivilegeEscalation"`
} `yaml:"image"` } `yaml:"image"`
ExistingPsp string `yaml:"existingPsp"` ExistingPsp string `yaml:"existingPsp"`
ExtraArgs struct { ExtraArgs struct{} `yaml:"extraArgs"`
} `yaml:"extraArgs"`
ServiceAccount struct { ServiceAccount struct {
Create bool `yaml:"create"` Create bool `yaml:"create"`
Name string `yaml:"name"` Name string `yaml:"name"`
@ -568,28 +526,21 @@ type IngressChartValue struct {
TimeoutSeconds int `yaml:"timeoutSeconds"` TimeoutSeconds int `yaml:"timeoutSeconds"`
} `yaml:"readinessProbe"` } `yaml:"readinessProbe"`
Tolerations []interface{} `yaml:"tolerations"` Tolerations []interface{} `yaml:"tolerations"`
Affinity struct { Affinity struct{} `yaml:"affinity"`
} `yaml:"affinity"` PodSecurityContext struct{} `yaml:"podSecurityContext"`
PodSecurityContext struct { ContainerSecurityContext struct{} `yaml:"containerSecurityContext"`
} `yaml:"podSecurityContext"` PodLabels struct{} `yaml:"podLabels"`
ContainerSecurityContext struct {
} `yaml:"containerSecurityContext"`
PodLabels struct {
} `yaml:"podLabels"`
NodeSelector struct { NodeSelector struct {
KubernetesIoOs string `yaml:"kubernetes.io/os"` KubernetesIoOs string `yaml:"kubernetes.io/os"`
} `yaml:"nodeSelector"` } `yaml:"nodeSelector"`
PodAnnotations struct { PodAnnotations struct{} `yaml:"podAnnotations"`
} `yaml:"podAnnotations"`
ReplicaCount int `yaml:"replicaCount"` ReplicaCount int `yaml:"replicaCount"`
MinAvailable int `yaml:"minAvailable"` MinAvailable int `yaml:"minAvailable"`
Resources struct { Resources struct{} `yaml:"resources"`
} `yaml:"resources"`
ExtraVolumeMounts []interface{} `yaml:"extraVolumeMounts"` ExtraVolumeMounts []interface{} `yaml:"extraVolumeMounts"`
ExtraVolumes []interface{} `yaml:"extraVolumes"` ExtraVolumes []interface{} `yaml:"extraVolumes"`
Autoscaling struct { Autoscaling struct {
Annotations struct { Annotations struct{} `yaml:"annotations"`
} `yaml:"annotations"`
Enabled bool `yaml:"enabled"` Enabled bool `yaml:"enabled"`
MinReplicas int `yaml:"minReplicas"` MinReplicas int `yaml:"minReplicas"`
MaxReplicas int `yaml:"maxReplicas"` MaxReplicas int `yaml:"maxReplicas"`
@ -597,16 +548,14 @@ type IngressChartValue struct {
TargetMemoryUtilizationPercentage int `yaml:"targetMemoryUtilizationPercentage"` TargetMemoryUtilizationPercentage int `yaml:"targetMemoryUtilizationPercentage"`
} `yaml:"autoscaling"` } `yaml:"autoscaling"`
Service struct { Service struct {
Annotations struct { Annotations struct{} `yaml:"annotations"`
} `yaml:"annotations"`
ExternalIPs []interface{} `yaml:"externalIPs"` ExternalIPs []interface{} `yaml:"externalIPs"`
LoadBalancerSourceRanges []interface{} `yaml:"loadBalancerSourceRanges"` LoadBalancerSourceRanges []interface{} `yaml:"loadBalancerSourceRanges"`
ServicePort int `yaml:"servicePort"` ServicePort int `yaml:"servicePort"`
Type string `yaml:"type"` Type string `yaml:"type"`
} `yaml:"service"` } `yaml:"service"`
PriorityClassName string `yaml:"priorityClassName"` PriorityClassName string `yaml:"priorityClassName"`
Labels struct { Labels struct{} `yaml:"labels"`
} `yaml:"labels"`
} `yaml:"defaultBackend"` } `yaml:"defaultBackend"`
Rbac struct { Rbac struct {
Create bool `yaml:"create"` Create bool `yaml:"create"`
@ -619,14 +568,11 @@ type IngressChartValue struct {
Create bool `yaml:"create"` Create bool `yaml:"create"`
Name string `yaml:"name"` Name string `yaml:"name"`
AutomountServiceAccountToken bool `yaml:"automountServiceAccountToken"` AutomountServiceAccountToken bool `yaml:"automountServiceAccountToken"`
Annotations struct { Annotations struct{} `yaml:"annotations"`
} `yaml:"annotations"`
} `yaml:"serviceAccount"` } `yaml:"serviceAccount"`
ImagePullSecrets []interface{} `yaml:"imagePullSecrets"` ImagePullSecrets []interface{} `yaml:"imagePullSecrets"`
TCP struct { TCP struct{} `yaml:"tcp"`
} `yaml:"tcp"` UDP struct{} `yaml:"udp"`
UDP struct {
} `yaml:"udp"`
PortNamePrefix string `yaml:"portNamePrefix"` PortNamePrefix string `yaml:"portNamePrefix"`
DhParam interface{} `yaml:"dhParam"` DhParam interface{} `yaml:"dhParam"`
} }

View file

@ -20,8 +20,9 @@ limitations under the License.
package main package main
import ( import (
"github.com/magefile/mage/mage"
"os" "os"
"github.com/magefile/mage/mage"
) )
func main() { func main() {

View file

@ -22,39 +22,45 @@ import (
"context" "context"
"errors" "errors"
"fmt" "fmt"
"io"
"net"
"net/http"
"os"
"regexp"
"strings"
"text/template"
"time"
"github.com/google/go-github/v48/github" "github.com/google/go-github/v48/github"
"github.com/magefile/mage/mg" "github.com/magefile/mage/mg"
"github.com/magefile/mage/sh" "github.com/magefile/mage/sh"
"golang.org/x/oauth2" "golang.org/x/oauth2"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
"io"
"net"
"net/http"
"os"
"text/template"
"regexp"
"strings"
"time"
) )
type Release mg.Namespace type Release mg.Namespace
var INGRESS_ORG = "kubernetes" // the owner so we can test from forks var (
var INGRESS_REPO = "ingress-nginx" // the repo to pull from INGRESS_ORG = "kubernetes" // the owner so we can test from forks
var RELEASE_BRANCH = "main" //we only release from main INGRESS_REPO = "ingress-nginx" // the repo to pull from
var GITHUB_TOKEN string // the Google/gogithub lib needs an PAT to access the GitHub API RELEASE_BRANCH = "main" // we only release from main
var K8S_IO_ORG = "kubernetes" //the owner or organization for the k8s.io repo GITHUB_TOKEN string // the Google/gogithub lib needs an PAT to access the GitHub API
var K8S_IO_REPO = "k8s.io" //the repo that holds the images yaml for production promotion K8S_IO_ORG = "kubernetes" // the owner or organization for the k8s.io repo
var INGRESS_REGISTRY = "registry.k8s.io" //Container registry for storage Ingress-nginx images K8S_IO_REPO = "k8s.io" // the repo that holds the images yaml for production promotion
var KUSTOMIZE_INSTALL_VERSION = "sigs.k8s.io/kustomize/kustomize/v4@v4.5.4" //static deploys needs kustomize to generate the template INGRESS_REGISTRY = "registry.k8s.io" // Container registry for storage Ingress-nginx images
KUSTOMIZE_INSTALL_VERSION = "sigs.k8s.io/kustomize/kustomize/v4@v4.5.4" // static deploys needs kustomize to generate the template
)
// ingress-nginx releases start with a TAG then a cloudbuild, then a promotion through a PR, this the location of that PR // ingress-nginx releases start with a TAG then a cloudbuild, then a promotion through a PR, this the location of that PR
var IMAGES_YAML = "https://raw.githubusercontent.com/kubernetes/k8s.io/main/registry.k8s.io/images/k8s-staging-ingress-nginx/images.yaml" var (
var ctx = context.Background() // Context used for GitHub Client IMAGES_YAML = "https://raw.githubusercontent.com/kubernetes/k8s.io/main/registry.k8s.io/images/k8s-staging-ingress-nginx/images.yaml"
ctx = context.Background() // Context used for GitHub Client
)
const INDEX_DOCS = "docs/deploy/index.md" //index.md has a version of the controller and needs to updated const (
const CHANGELOG = "Changelog.md" //Name of the changelog INDEX_DOCS = "docs/deploy/index.md" // index.md has a version of the controller and needs to updated
CHANGELOG = "Changelog.md" // Name of the changelog
)
// ControllerImage - struct with info about controllers // ControllerImage - struct with info about controllers
type ControllerImage struct { type ControllerImage struct {
@ -101,7 +107,6 @@ func init() {
// PromoteImage Creates PR into the k8s.io repo for promotion of ingress from staging to production // PromoteImage Creates PR into the k8s.io repo for promotion of ingress from staging to production
func (Release) PromoteImage(version, sha string) { func (Release) PromoteImage(version, sha string) {
} }
// Release Create a new release of ingress nginx controller // Release Create a new release of ingress nginx controller
@ -204,7 +209,7 @@ func updateE2EDocs() {
// The static deploy scripts use kustomize to generate them, this function ensures kustomize is installed // The static deploy scripts use kustomize to generate them, this function ensures kustomize is installed
func installKustomize() error { func installKustomize() error {
Info("Install Kustomize") Info("Install Kustomize")
var g0 = sh.RunCmd("go") g0 := sh.RunCmd("go")
// somewhere in your main code // somewhere in your main code
err := g0("install", KUSTOMIZE_INSTALL_VERSION) err := g0("install", KUSTOMIZE_INSTALL_VERSION)
if err != nil { if err != nil {
@ -270,7 +275,7 @@ func (Release) ReleaseNotes(newVersion string) error {
} }
func makeReleaseNotes(newVersion string) (*ReleaseNote, error) { func makeReleaseNotes(newVersion string) (*ReleaseNote, error) {
var newReleaseNotes = ReleaseNote{} newReleaseNotes := ReleaseNote{}
newReleaseNotes.Version = newVersion newReleaseNotes.Version = newVersion
allControllerTags := getAllControllerTags() allControllerTags := getAllControllerTags()
@ -317,7 +322,6 @@ func makeReleaseNotes(newVersion string) (*ReleaseNote, error) {
helmUpdates = append(helmUpdates, u[1]) helmUpdates = append(helmUpdates, u[1])
} }
} }
} }
} }
helmUpdates = append(helmUpdates, fmt.Sprintf("Update Ingress-Nginx version %s", newReleaseNotes.NewControllerVersion)) helmUpdates = append(helmUpdates, fmt.Sprintf("Update Ingress-Nginx version %s", newReleaseNotes.NewControllerVersion))

View file

@ -20,11 +20,12 @@ package main
import ( import (
"fmt" "fmt"
"os"
"strings"
semver "github.com/blang/semver/v4" semver "github.com/blang/semver/v4"
"github.com/magefile/mage/mg" "github.com/magefile/mage/mg"
"github.com/magefile/mage/sh" "github.com/magefile/mage/sh"
"os"
"strings"
) )
type Tag mg.Namespace type Tag mg.Namespace
@ -95,7 +96,7 @@ func bump(currentTag, newTag string) {
} }
Info("Updating Tag %v to %v", currentTag, newTag) Info("Updating Tag %v to %v", currentTag, newTag)
err := os.WriteFile("TAG", []byte(newTag), 0666) err := os.WriteFile("TAG", []byte(newTag), 0o666)
CheckIfError(err, "Error Writing New Tag File") CheckIfError(err, "Error Writing New Tag File")
} }

View file

@ -127,6 +127,15 @@ var _ = framework.IngressNginxDescribeSerial("[Admission] admission controller",
}) })
ginkgo.It("should return an error if there is an error validating the ingress definition", func() { ginkgo.It("should return an error if there is an error validating the ingress definition", func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "true",
})
defer func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "false",
})
}()
host := admissionTestHost host := admissionTestHost
annotations := map[string]string{ annotations := map[string]string{
@ -232,6 +241,15 @@ var _ = framework.IngressNginxDescribeSerial("[Admission] admission controller",
}) })
ginkgo.It("should return an error if the Ingress V1 definition contains invalid annotations", func() { ginkgo.It("should return an error if the Ingress V1 definition contains invalid annotations", func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "true",
})
defer func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "false",
})
}()
out, err := createIngress(f.Namespace, invalidV1Ingress) out, err := createIngress(f.Namespace, invalidV1Ingress)
assert.Empty(ginkgo.GinkgoT(), out) assert.Empty(ginkgo.GinkgoT(), out)
assert.NotNil(ginkgo.GinkgoT(), err, "creating an ingress using kubectl") assert.NotNil(ginkgo.GinkgoT(), err, "creating an ingress using kubectl")
@ -243,6 +261,14 @@ var _ = framework.IngressNginxDescribeSerial("[Admission] admission controller",
}) })
ginkgo.It("should not return an error for an invalid Ingress when it has unknown class", func() { ginkgo.It("should not return an error for an invalid Ingress when it has unknown class", func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "true",
})
defer func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "false",
})
}()
out, err := createIngress(f.Namespace, invalidV1IngressWithOtherClass) out, err := createIngress(f.Namespace, invalidV1IngressWithOtherClass)
assert.Equal(ginkgo.GinkgoT(), "ingress.networking.k8s.io/extensions-invalid-other created\n", out) assert.Equal(ginkgo.GinkgoT(), "ingress.networking.k8s.io/extensions-invalid-other created\n", out)
assert.Nil(ginkgo.GinkgoT(), err, "creating an invalid ingress with unknown class using kubectl") assert.Nil(ginkgo.GinkgoT(), err, "creating an invalid ingress with unknown class using kubectl")

View file

@ -277,6 +277,14 @@ var _ = framework.DescribeAnnotation("auth-*", func() {
"nginx.ingress.kubernetes.io/auth-snippet": ` "nginx.ingress.kubernetes.io/auth-snippet": `
proxy_set_header My-Custom-Header 42;`, proxy_set_header My-Custom-Header 42;`,
} }
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "true",
})
defer func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "false",
})
}()
ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, annotations) ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, annotations)
f.EnsureIngress(ing) f.EnsureIngress(ing)
@ -290,6 +298,15 @@ var _ = framework.DescribeAnnotation("auth-*", func() {
ginkgo.It(`should not set snippet "proxy_set_header My-Custom-Header 42;" when external auth is not configured`, func() { ginkgo.It(`should not set snippet "proxy_set_header My-Custom-Header 42;" when external auth is not configured`, func() {
host := authHost host := authHost
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "true",
})
defer func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "false",
})
}()
annotations := map[string]string{ annotations := map[string]string{
"nginx.ingress.kubernetes.io/auth-snippet": ` "nginx.ingress.kubernetes.io/auth-snippet": `
proxy_set_header My-Custom-Header 42;`, proxy_set_header My-Custom-Header 42;`,

View file

@ -82,7 +82,7 @@ var _ = framework.DescribeAnnotation("backend-protocol - FastCGI", func() {
f.EnsureConfigMap(configuration) f.EnsureConfigMap(configuration)
host := "fastcgi-params-configmap" host := "fastcgi-params-configmap" //#nosec G101
annotations := map[string]string{ annotations := map[string]string{
"nginx.ingress.kubernetes.io/backend-protocol": "FCGI", "nginx.ingress.kubernetes.io/backend-protocol": "FCGI",

View file

@ -62,6 +62,15 @@ var _ = framework.DescribeAnnotation("from-to-www-redirect", func() {
}) })
ginkgo.It("should redirect from www HTTPS to HTTPS", func() { ginkgo.It("should redirect from www HTTPS to HTTPS", func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "true",
})
defer func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "false",
})
}()
ginkgo.By("setting up server for redirect from www") ginkgo.By("setting up server for redirect from www")
fromHost := fmt.Sprintf("%s.nip.io", f.GetNginxIP()) fromHost := fmt.Sprintf("%s.nip.io", f.GetNginxIP())

View file

@ -189,6 +189,15 @@ var _ = framework.DescribeAnnotation("backend-protocol - GRPC", func() {
ginkgo.It("should return OK for service with backend protocol GRPCS", func() { ginkgo.It("should return OK for service with backend protocol GRPCS", func() {
f.NewGRPCBinDeployment() f.NewGRPCBinDeployment()
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "true",
})
defer func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "false",
})
}()
host := echoHost host := echoHost
svc := &corev1.Service{ svc := &corev1.Service{

View file

@ -100,6 +100,15 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() {
}) })
ginkgo.It("should enable modsecurity with snippet", func() { ginkgo.It("should enable modsecurity with snippet", func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "true",
})
defer func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "false",
})
}()
host := modSecurityFooHost host := modSecurityFooHost
nameSpace := f.Namespace nameSpace := f.Namespace
@ -164,6 +173,15 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() {
}) })
ginkgo.It("should enable modsecurity with snippet and block requests", func() { ginkgo.It("should enable modsecurity with snippet and block requests", func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "true",
})
defer func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "false",
})
}()
host := modSecurityFooHost host := modSecurityFooHost
nameSpace := f.Namespace nameSpace := f.Namespace
@ -194,6 +212,15 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() {
}) })
ginkgo.It("should enable modsecurity globally and with modsecurity-snippet block requests", func() { ginkgo.It("should enable modsecurity globally and with modsecurity-snippet block requests", func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "true",
})
defer func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "false",
})
}()
host := modSecurityFooHost host := modSecurityFooHost
nameSpace := f.Namespace nameSpace := f.Namespace
@ -224,6 +251,17 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() {
}) })
ginkgo.It("should enable modsecurity when enable-owasp-modsecurity-crs is set to true", func() { ginkgo.It("should enable modsecurity when enable-owasp-modsecurity-crs is set to true", func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "true",
"enable-modsecurity": "true",
"enable-owasp-modsecurity-crs": "true",
})
defer func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "false",
})
}()
host := modSecurityFooHost host := modSecurityFooHost
nameSpace := f.Namespace nameSpace := f.Namespace
@ -238,11 +276,6 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() {
ing := framework.NewSingleIngress(host, "/", host, nameSpace, framework.EchoService, 80, annotations) ing := framework.NewSingleIngress(host, "/", host, nameSpace, framework.EchoService, 80, annotations)
f.EnsureIngress(ing) f.EnsureIngress(ing)
f.SetNginxConfigMapData(map[string]string{
"enable-modsecurity": "true",
"enable-owasp-modsecurity-crs": "true",
})
f.WaitForNginxServer(host, f.WaitForNginxServer(host,
func(server string) bool { func(server string) bool {
return strings.Contains(server, "SecRuleEngine On") return strings.Contains(server, "SecRuleEngine On")
@ -277,12 +310,17 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() {
f.EnsureIngress(ing) f.EnsureIngress(ing)
expectedComment := "SecRuleEngine On" expectedComment := "SecRuleEngine On"
f.SetNginxConfigMapData(map[string]string{ f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "true",
"enable-modsecurity": "true", "enable-modsecurity": "true",
"enable-owasp-modsecurity-crs": "true", "enable-owasp-modsecurity-crs": "true",
"modsecurity-snippet": expectedComment, "modsecurity-snippet": expectedComment,
}) })
defer func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "false",
})
}()
f.WaitForNginxServer(host, f.WaitForNginxServer(host,
func(server string) bool { func(server string) bool {
@ -340,6 +378,14 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() {
}) })
ginkgo.It("should disable default modsecurity conf setting when modsecurity-snippet is specified", func() { ginkgo.It("should disable default modsecurity conf setting when modsecurity-snippet is specified", func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "true",
})
defer func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "false",
})
}()
host := modSecurityFooHost host := modSecurityFooHost
nameSpace := f.Namespace nameSpace := f.Namespace

View file

@ -33,6 +33,15 @@ var _ = framework.DescribeAnnotation("server-snippet", func() {
}) })
ginkgo.It(`add valid directives to server via server snippet`, func() { ginkgo.It(`add valid directives to server via server snippet`, func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "true",
})
defer func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "false",
})
}()
host := "serversnippet.foo.com" host := "serversnippet.foo.com"
annotations := map[string]string{ annotations := map[string]string{
"nginx.ingress.kubernetes.io/server-snippet": ` "nginx.ingress.kubernetes.io/server-snippet": `
@ -59,6 +68,15 @@ var _ = framework.DescribeAnnotation("server-snippet", func() {
}) })
ginkgo.It(`drops server snippet if disabled by the administrator`, func() { ginkgo.It(`drops server snippet if disabled by the administrator`, func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "true",
})
defer func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "false",
})
}()
host := "noserversnippet.foo.com" host := "noserversnippet.foo.com"
annotations := map[string]string{ annotations := map[string]string{
"nginx.ingress.kubernetes.io/server-snippet": ` "nginx.ingress.kubernetes.io/server-snippet": `

View file

@ -33,6 +33,16 @@ var _ = framework.DescribeAnnotation("configuration-snippet", func() {
ginkgo.It("set snippet more_set_headers in all locations", func() { ginkgo.It("set snippet more_set_headers in all locations", func() {
host := "configurationsnippet.foo.com" host := "configurationsnippet.foo.com"
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "true",
})
defer func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "false",
})
}()
annotations := map[string]string{ annotations := map[string]string{
"nginx.ingress.kubernetes.io/configuration-snippet": `more_set_headers "Foo1: Bar1";`, "nginx.ingress.kubernetes.io/configuration-snippet": `more_set_headers "Foo1: Bar1";`,
} }
@ -76,10 +86,6 @@ var _ = framework.DescribeAnnotation("configuration-snippet", func() {
annotations) annotations)
f.UpdateNginxConfigMapData("allow-snippet-annotations", "false") f.UpdateNginxConfigMapData("allow-snippet-annotations", "false")
defer func() {
// Return to the original value
f.UpdateNginxConfigMapData("allow-snippet-annotations", "true")
}()
// Sleep a while just to guarantee that the configmap is applied // Sleep a while just to guarantee that the configmap is applied
framework.Sleep() framework.Sleep()

View file

@ -39,6 +39,15 @@ var _ = framework.DescribeSetting("stream-snippet", func() {
}) })
ginkgo.It("should add value of stream-snippet to nginx config", func() { ginkgo.It("should add value of stream-snippet to nginx config", func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "true",
})
defer func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "false",
})
}()
host := "foo.com" host := "foo.com"
snippet := `server {listen 8000; proxy_pass 127.0.0.1:80;}` snippet := `server {listen 8000; proxy_pass 127.0.0.1:80;}`

View file

@ -47,7 +47,7 @@ const NIPService = "external-nip"
var HTTPBunImage = os.Getenv("HTTPBUN_IMAGE") var HTTPBunImage = os.Getenv("HTTPBUN_IMAGE")
// EchoImage is the default image to be used by the echo service // EchoImage is the default image to be used by the echo service
const EchoImage = "registry.k8s.io/ingress-nginx/e2e-test-echo@sha256:4938d1d91a2b7d19454460a8c1b010b89f6ff92d2987fd889ac3e8fc3b70d91a" const EchoImage = "registry.k8s.io/ingress-nginx/e2e-test-echo@sha256:4938d1d91a2b7d19454460a8c1b010b89f6ff92d2987fd889ac3e8fc3b70d91a" //#nosec G101
// TODO: change all Deployment functions to use these options // TODO: change all Deployment functions to use these options
// in order to reduce complexity and have a unified API across the // in order to reduce complexity and have a unified API across the

View file

@ -36,6 +36,15 @@ var _ = framework.IngressNginxDescribe("single ingress - multiple hosts", func()
}) })
ginkgo.It("should set the correct $service_name NGINX variable", func() { ginkgo.It("should set the correct $service_name NGINX variable", func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "true",
})
defer func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "false",
})
}()
annotations := map[string]string{ annotations := map[string]string{
"nginx.ingress.kubernetes.io/configuration-snippet": `more_set_input_headers "service-name: $service_name";`, "nginx.ingress.kubernetes.io/configuration-snippet": `more_set_input_headers "service-name: $service_name";`,
} }

View file

@ -35,6 +35,15 @@ var _ = framework.IngressNginxDescribe("[Ingress] [PathType] exact", func() {
}) })
ginkgo.It("should choose exact location for /exact", func() { ginkgo.It("should choose exact location for /exact", func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "true",
})
defer func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "false",
})
}()
host := "exact.path" host := "exact.path"
annotations := map[string]string{ annotations := map[string]string{

View file

@ -37,6 +37,15 @@ var _ = framework.IngressNginxDescribe("[Ingress] [PathType] mix Exact and Prefi
exactPathType := networking.PathTypeExact exactPathType := networking.PathTypeExact
ginkgo.It("should choose the correct location", func() { ginkgo.It("should choose the correct location", func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "true",
})
defer func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "false",
})
}()
host := "mixed.path" host := "mixed.path"
annotations := map[string]string{ annotations := map[string]string{

View file

@ -34,6 +34,14 @@ var _ = framework.DescribeAnnotation("Bad annotation values", func() {
}) })
ginkgo.It("[BAD_ANNOTATIONS] should drop an ingress if there is an invalid character in some annotation", func() { ginkgo.It("[BAD_ANNOTATIONS] should drop an ingress if there is an invalid character in some annotation", func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "true",
})
defer func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "false",
})
}()
host := "invalid-value-test" host := "invalid-value-test"
annotations := map[string]string{ annotations := map[string]string{
@ -65,6 +73,15 @@ var _ = framework.DescribeAnnotation("Bad annotation values", func() {
}) })
ginkgo.It("[BAD_ANNOTATIONS] should drop an ingress if there is a forbidden word in some annotation", func() { ginkgo.It("[BAD_ANNOTATIONS] should drop an ingress if there is a forbidden word in some annotation", func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "true",
})
defer func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "false",
})
}()
host := "forbidden-value-test" host := "forbidden-value-test"
annotations := map[string]string{ annotations := map[string]string{
@ -100,6 +117,14 @@ var _ = framework.DescribeAnnotation("Bad annotation values", func() {
}) })
ginkgo.It("[BAD_ANNOTATIONS] should allow an ingress if there is a default blocklist config in place", func() { ginkgo.It("[BAD_ANNOTATIONS] should allow an ingress if there is a default blocklist config in place", func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "true",
})
defer func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "false",
})
}()
hostValid := "custom-allowed-value-test" hostValid := "custom-allowed-value-test"
annotationsValid := map[string]string{ annotationsValid := map[string]string{
"nginx.ingress.kubernetes.io/configuration-snippet": ` "nginx.ingress.kubernetes.io/configuration-snippet": `
@ -130,6 +155,14 @@ var _ = framework.DescribeAnnotation("Bad annotation values", func() {
}) })
ginkgo.It("[BAD_ANNOTATIONS] should drop an ingress if there is a custom blocklist config in place and allow others to pass", func() { ginkgo.It("[BAD_ANNOTATIONS] should drop an ingress if there is a custom blocklist config in place and allow others to pass", func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "true",
})
defer func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "false",
})
}()
host := "custom-forbidden-value-test" host := "custom-forbidden-value-test"
annotations := map[string]string{ annotations := map[string]string{

View file

@ -69,7 +69,15 @@ var _ = framework.DescribeSetting("Geoip2", func() {
ginkgo.It("should only allow requests from specific countries", func() { ginkgo.It("should only allow requests from specific countries", func() {
ginkgo.Skip("GeoIP test are temporarily disabled") ginkgo.Skip("GeoIP test are temporarily disabled")
f.UpdateNginxConfigMapData("use-geoip2", "true") f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "true",
"use-geoip2": "true",
})
defer func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "false",
})
}()
httpSnippetAllowingOnlyAustralia := `map $geoip2_city_country_code $blocked_country { httpSnippetAllowingOnlyAustralia := `map $geoip2_city_country_code $blocked_country {
default 1; default 1;

View file

@ -34,6 +34,14 @@ var _ = framework.IngressNginxDescribe("Dynamic $proxy_host", func() {
}) })
ginkgo.It("should exist a proxy_host", func() { ginkgo.It("should exist a proxy_host", func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "true",
})
defer func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "false",
})
}()
upstreamName := fmt.Sprintf("%v-%v-80", f.Namespace, framework.EchoService) upstreamName := fmt.Sprintf("%v-%v-80", f.Namespace, framework.EchoService)
annotations := map[string]string{ annotations := map[string]string{
"nginx.ingress.kubernetes.io/configuration-snippet": `more_set_headers "Custom-Header: $proxy_host"`, "nginx.ingress.kubernetes.io/configuration-snippet": `more_set_headers "Custom-Header: $proxy_host"`,
@ -55,6 +63,15 @@ var _ = framework.IngressNginxDescribe("Dynamic $proxy_host", func() {
}) })
ginkgo.It("should exist a proxy_host using the upstream-vhost annotation value", func() { ginkgo.It("should exist a proxy_host using the upstream-vhost annotation value", func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "true",
})
defer func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "false",
})
}()
upstreamName := fmt.Sprintf("%v-%v-80", f.Namespace, framework.EchoService) upstreamName := fmt.Sprintf("%v-%v-80", f.Namespace, framework.EchoService)
upstreamVHost := "different.host" upstreamVHost := "different.host"
annotations := map[string]string{ annotations := map[string]string{

View file

@ -37,10 +37,16 @@ var _ = framework.DescribeSetting("configmap server-snippet", func() {
hostAnnots := "serverannotssnippet1.foo.com" hostAnnots := "serverannotssnippet1.foo.com"
f.SetNginxConfigMapData(map[string]string{ f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "true",
"server-snippet": ` "server-snippet": `
more_set_headers "Globalfoo: Foooo";`, more_set_headers "Globalfoo: Foooo";`,
}) })
defer func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "false",
})
}()
annotations := map[string]string{ annotations := map[string]string{
"nginx.ingress.kubernetes.io/server-snippet": ` "nginx.ingress.kubernetes.io/server-snippet": `
more_set_headers "Foo: Bar"; more_set_headers "Foo: Bar";
@ -99,6 +105,11 @@ var _ = framework.DescribeSetting("configmap server-snippet", func() {
more_set_headers "Globalfoo: Foooo";`, more_set_headers "Globalfoo: Foooo";`,
}) })
defer func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "false",
})
}()
annotations := map[string]string{ annotations := map[string]string{
"nginx.ingress.kubernetes.io/server-snippet": ` "nginx.ingress.kubernetes.io/server-snippet": `
more_set_headers "Foo: Bar"; more_set_headers "Foo: Bar";

View file

@ -31,6 +31,15 @@ var _ = framework.IngressNginxDescribeSerial("annotation validations", func() {
f := framework.NewDefaultFramework("validations") f := framework.NewDefaultFramework("validations")
//nolint:dupl // Ignore dupl errors for similar test case //nolint:dupl // Ignore dupl errors for similar test case
ginkgo.It("should allow ingress based on their risk on webhooks", func() { ginkgo.It("should allow ingress based on their risk on webhooks", func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "true",
})
defer func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "false",
})
}()
host := "annotation-validations" host := "annotation-validations"
// Low and Medium Risk annotations should be allowed, the rest should be denied // Low and Medium Risk annotations should be allowed, the rest should be denied
@ -57,6 +66,14 @@ var _ = framework.IngressNginxDescribeSerial("annotation validations", func() {
}) })
//nolint:dupl // Ignore dupl errors for similar test case //nolint:dupl // Ignore dupl errors for similar test case
ginkgo.It("should allow ingress based on their risk on webhooks", func() { ginkgo.It("should allow ingress based on their risk on webhooks", func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "true",
})
defer func() {
f.SetNginxConfigMapData(map[string]string{
"allow-snippet-annotations": "false",
})
}()
host := "annotation-validations" host := "annotation-validations"
// Low and Medium Risk annotations should be allowed, the rest should be denied // Low and Medium Risk annotations should be allowed, the rest should be denied