diff --git a/.gitignore b/.gitignore index 2c0accad75..60bf6a304c 100644 --- a/.gitignore +++ b/.gitignore @@ -60,3 +60,4 @@ cmd/plugin/release/ingress-nginx.yaml cmd/plugin/release/*.tar.gz cmd/plugin/release/LICENSE tmp/ +test/junitreports/ diff --git a/charts/ingress-nginx/README.md b/charts/ingress-nginx/README.md index 77f7110427..3bfb4c2ab6 100644 --- a/charts/ingress-nginx/README.md +++ b/charts/ingress-nginx/README.md @@ -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.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.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.autoscaling.annotations | object | `{}` | | | controller.autoscaling.behavior | object | `{}` | | diff --git a/charts/ingress-nginx/values.yaml b/charts/ingress-nginx/values.yaml index 6762c0d851..bb665359f0 100644 --- a/charts/ingress-nginx/values.yaml +++ b/charts/ingress-nginx/values.yaml @@ -73,7 +73,7 @@ controller: # their own *-snippet annotations, otherwise this is forbidden / dropped # when users add those annotations. # 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), # since CNI and hostport don't mix yet. Can be deprecated once https://github.com/kubernetes/kubernetes/issues/23920 # is merged diff --git a/cmd/plugin/util/util.go b/cmd/plugin/util/util.go index aa753689aa..7457b8c536 100644 --- a/cmd/plugin/util/util.go +++ b/cmd/plugin/util/util.go @@ -29,8 +29,8 @@ import ( // The default deployment and service names for ingress-nginx const ( - DefaultIngressDeploymentName = "ingress-nginx-controller" - DefaultIngressServiceName = "ingress-nginx-controller" + DefaultIngressDeploymentName = "ingress-nginx-controller" //#nosec G101 + DefaultIngressServiceName = "ingress-nginx-controller" //#nosec G101 DefaultIngressContainerName = "controller" ) diff --git a/docs/user-guide/nginx-configuration/configmap.md b/docs/user-guide/nginx-configuration/configmap.md index 0a7e44dce4..d771d16b2f 100644 --- a/docs/user-guide/nginx-configuration/configmap.md +++ b/docs/user-guide/nginx-configuration/configmap.md @@ -30,7 +30,7 @@ The following table shows a configuration option's name, type, and the default v |[add-headers](#add-headers)|string|""|| |[allow-backend-server-header](#allow-backend-server-header)|bool|"false"|| |[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|| |[annotation-value-word-blocklist](#annotation-value-word-blocklist)|string array|""|| |[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 -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 may allow a user to add restricted configurations to the final nginx.conf file diff --git a/internal/ingress/annotations/fastcgi/main.go b/internal/ingress/annotations/fastcgi/main.go index 882de5b1ca..52384a9691 100644 --- a/internal/ingress/annotations/fastcgi/main.go +++ b/internal/ingress/annotations/fastcgi/main.go @@ -32,7 +32,7 @@ import ( const ( 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) diff --git a/internal/ingress/annotations/modsecurity/main_test.go b/internal/ingress/annotations/modsecurity/main_test.go index 0c9b3a9c70..5cb05f201a 100644 --- a/internal/ingress/annotations/modsecurity/main_test.go +++ b/internal/ingress/annotations/modsecurity/main_test.go @@ -67,7 +67,7 @@ func TestParse(t *testing.T) { Spec: networking.IngressSpec{}, } - for _, testCase := range testCases { + for i, testCase := range testCases { ing.SetAnnotations(testCase.annotations) result, err := ap.Parse(ing) if err != nil { @@ -77,7 +77,7 @@ func TestParse(t *testing.T) { if !ok { 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) } } diff --git a/internal/ingress/annotations/proxy/main.go b/internal/ingress/annotations/proxy/main.go index 7fb1c814ec..9d26462616 100644 --- a/internal/ingress/annotations/proxy/main.go +++ b/internal/ingress/annotations/proxy/main.go @@ -42,7 +42,7 @@ const ( proxyRedirectToAnnotation = "proxy-redirect-to" proxyBufferingAnnotation = "proxy-buffering" 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?)+$`) diff --git a/internal/ingress/annotations/sslcipher/main_test.go b/internal/ingress/annotations/sslcipher/main_test.go index 167466fefd..20cb4d7af1 100644 --- a/internal/ingress/annotations/sslcipher/main_test.go +++ b/internal/ingress/annotations/sslcipher/main_test.go @@ -64,13 +64,13 @@ func TestParse(t *testing.T) { Spec: networking.IngressSpec{}, } - for _, testCase := range testCases { + for i, testCase := range testCases { ing.SetAnnotations(testCase.annotations) result, err := ap.Parse(ing) if (err != nil) != testCase.expectErr { 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) } } diff --git a/internal/ingress/controller/config/config.go b/internal/ingress/controller/config/config.go index 0dafa78a29..09983308e3 100644 --- a/internal/ingress/controller/config/config.go +++ b/internal/ingress/controller/config/config.go @@ -865,7 +865,7 @@ func NewDefault() Configuration { defGlobalExternalAuth := GlobalExternalAuth{"", "", "", "", "", append(defResponseHeaders, ""), "", "", "", []string{}, map[string]string{}, false} cfg := Configuration{ - AllowSnippetAnnotations: true, + AllowSnippetAnnotations: false, AllowCrossNamespaceResources: true, AllowBackendServerHeader: false, AnnotationValueWordBlocklist: "", diff --git a/internal/ingress/controller/controller.go b/internal/ingress/controller/controller.go index f2ad4639b7..bbcde1d4f3 100644 --- a/internal/ingress/controller/controller.go +++ b/internal/ingress/controller/controller.go @@ -1057,7 +1057,7 @@ func (n *NGINXController) createUpstreams(data []*ingress.Ingress, du *ingress.B continue } - for _, path := range rule.HTTP.Paths { + for i, path := range rule.HTTP.Paths { if path.Backend.Service == nil { // 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) @@ -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 if anns.ServiceUpstream { - endpoint, err := n.getServiceClusterEndpoint(svcKey, &path.Backend) + endpoint, err := n.getServiceClusterEndpoint(svcKey, &rule.HTTP.Paths[i].Backend) if err != nil { klog.Errorf("Failed to determine a suitable ClusterIP Endpoint for Service %q: %v", svcKey, err) } else { @@ -1844,7 +1844,7 @@ func ingressForHostPath(hostname, path string, servers []*ingress.Server) []*net continue } - for _, location := range server.Locations { + for i, location := range server.Locations { if location.Path != path { continue } @@ -1853,7 +1853,7 @@ func ingressForHostPath(hostname, path string, servers []*ingress.Server) []*net continue } - ingresses = append(ingresses, &location.Ingress.Ingress) + ingresses = append(ingresses, &server.Locations[i].Ingress.Ingress) } } diff --git a/internal/ingress/metric/collectors/main.go b/internal/ingress/metric/collectors/main.go index 2c57ad774d..b2479929b7 100644 --- a/internal/ingress/metric/collectors/main.go +++ b/internal/ingress/metric/collectors/main.go @@ -17,4 +17,4 @@ limitations under the License. package collectors // PrometheusNamespace default metric namespace -var PrometheusNamespace = "nginx_ingress_controller" +var PrometheusNamespace = "nginx_ingress_controller" //#nosec G101 diff --git a/internal/net/ssl/ssl.go b/internal/net/ssl/ssl.go index 516b1ec9ce..26fd706e11 100644 --- a/internal/net/ssl/ssl.go +++ b/internal/net/ssl/ssl.go @@ -55,7 +55,7 @@ var FakeSSLCertificateUID = "00000000-0000-0000-0000-000000000000" var oidExtensionSubjectAltName = asn1.ObjectIdentifier{2, 5, 29, 17} 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 diff --git a/magefiles/helm.go b/magefiles/helm.go index 585a934134..c11fc9ec2a 100644 --- a/magefiles/helm.go +++ b/magefiles/helm.go @@ -32,8 +32,10 @@ import ( "gopkg.in/yaml.v3" ) -const HelmChartPath = "charts/ingress-nginx/Chart.yaml" -const HelmChartValues = "charts/ingress-nginx/values.yaml" +const ( + HelmChartPath = "charts/ingress-nginx/Chart.yaml" + HelmChartValues = "charts/ingress-nginx/values.yaml" +) type Helm mg.Namespace @@ -43,7 +45,6 @@ func (Helm) UpdateAppVersion() { } func updateAppVersion() { - } // UpdateVersion Update Helm Version of the Chart @@ -69,11 +70,11 @@ func updateVersion(version string) { chart, err := chartutil.LoadChartfile(HelmChartPath) CheckIfError(err, "HELM Could not Load Chart") - //Get the current tag - //appVersionV, err := getIngressNGINXVersion() - //CheckIfError(err, "HELM Issue Retrieving the Current Ingress Nginx Version") + // Get the current tag + // appVersionV, err := getIngressNGINXVersion() + // CheckIfError(err, "HELM Issue Retrieving the Current Ingress Nginx Version") - //remove the v from TAG + // remove the v from TAG appVersion := version Info("HELM Ingress-Nginx App Version: %s Chart AppVersion: %s", appVersion, chart.AppVersion) @@ -82,7 +83,7 @@ func updateVersion(version string) { return } - //Update the helm chart + // Update the helm chart chart.AppVersion = appVersion cTag, err := semver.Make(chart.Version) CheckIfError(err, "HELM Creating Chart Version: %v", err) @@ -113,7 +114,6 @@ func updateChartReleaseNotes(releasesNotes []string) { } func UpdateChartChangelog() { - } // UpdateChartValue Updates the Helm ChartValue @@ -124,16 +124,16 @@ func (Helm) UpdateChartValue(key, value string) { func updateChartValue(key, value string) { Info("HELM Updating Chart %s %s:%s", HelmChartValues, key, value) - //read current values.yaml + // read current values.yaml data, err := os.ReadFile(HelmChartValues) CheckIfError(err, "HELM Could not Load Helm Chart Values files %s", HelmChartValues) - //var valuesStruct IngressChartValue + // var valuesStruct IngressChartValue var n yaml.Node CheckIfError(yaml.Unmarshal(data, &n), "HELM Could not Unmarshal %s", HelmChartValues) - //update value - //keyParse := parsePath(key) + // update value + // keyParse := parsePath(key) p, err := yamlpath.NewPath(key) CheckIfError(err, "HELM cannot create path") @@ -152,7 +152,7 @@ func updateChartValue(key, value string) { yamlEncoder.SetIndent(2) err = yamlEncoder.Encode(&n) 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) Info("HELM Ingress Nginx Helm Chart update %s %s", key, value) @@ -161,6 +161,7 @@ func updateChartValue(key, value string) { func (Helm) Helmdocs() error { return runHelmDocs() } + func runHelmDocs() error { err := installHelmDocs() if err != nil { @@ -175,7 +176,7 @@ func runHelmDocs() error { func installHelmDocs() error { 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") if err != nil { @@ -186,13 +187,11 @@ func installHelmDocs() error { func parsePath(key string) []string { return strings.Split(key, ".") } func updateHelmDocs() { - } type IngressChartValue struct { - CommonLabels struct { - } `yaml:"commonLabels"` - Controller struct { + CommonLabels struct{} `yaml:"commonLabels"` + Controller struct { Name string `yaml:"name"` Image struct { Chroot bool `yaml:"chroot"` @@ -211,24 +210,18 @@ type IngressChartValue struct { HTTP int `yaml:"http"` HTTPS int `yaml:"https"` } `yaml:"containerPort"` - Config struct { - } `yaml:"config"` - ConfigAnnotations struct { - } `yaml:"configAnnotations"` - ProxySetHeaders struct { - } `yaml:"proxySetHeaders"` - AddHeaders struct { - } `yaml:"addHeaders"` - DNSConfig struct { - } `yaml:"dnsConfig"` - Hostname struct { - } `yaml:"hostname"` - DNSPolicy string `yaml:"dnsPolicy"` - ReportNodeInternalIP bool `yaml:"reportNodeInternalIp"` - WatchIngressWithoutClass bool `yaml:"watchIngressWithoutClass"` - IngressClassByName bool `yaml:"ingressClassByName"` - AllowSnippetAnnotations bool `yaml:"allowSnippetAnnotations"` - HostNetwork bool `yaml:"hostNetwork"` + Config struct{} `yaml:"config"` + ConfigAnnotations struct{} `yaml:"configAnnotations"` + ProxySetHeaders struct{} `yaml:"proxySetHeaders"` + AddHeaders struct{} `yaml:"addHeaders"` + DNSConfig struct{} `yaml:"dnsConfig"` + Hostname struct{} `yaml:"hostname"` + DNSPolicy string `yaml:"dnsPolicy"` + ReportNodeInternalIP bool `yaml:"reportNodeInternalIp"` + WatchIngressWithoutClass bool `yaml:"watchIngressWithoutClass"` + IngressClassByName bool `yaml:"ingressClassByName"` + AllowSnippetAnnotations bool `yaml:"allowSnippetAnnotations"` + HostNetwork bool `yaml:"hostNetwork"` HostPort struct { Enabled bool `yaml:"enabled"` Ports struct { @@ -238,21 +231,17 @@ type IngressChartValue struct { } `yaml:"hostPort"` ElectionID string `yaml:"electionID"` IngressClassResource struct { - Name string `yaml:"name"` - Enabled bool `yaml:"enabled"` - Default bool `yaml:"default"` - ControllerValue string `yaml:"controllerValue"` - Parameters struct { - } `yaml:"parameters"` + Name string `yaml:"name"` + Enabled bool `yaml:"enabled"` + Default bool `yaml:"default"` + ControllerValue string `yaml:"controllerValue"` + Parameters struct{} `yaml:"parameters"` } `yaml:"ingressClassResource"` - IngressClass string `yaml:"ingressClass"` - PodLabels struct { - } `yaml:"podLabels"` - PodSecurityContext struct { - } `yaml:"podSecurityContext"` - Sysctls struct { - } `yaml:"sysctls"` - PublishService struct { + IngressClass string `yaml:"ingressClass"` + PodLabels struct{} `yaml:"podLabels"` + PodSecurityContext struct{} `yaml:"podSecurityContext"` + Sysctls struct{} `yaml:"sysctls"` + PublishService struct { Enabled bool `yaml:"enabled"` PathOverride string `yaml:"pathOverride"` } `yaml:"publishService"` @@ -263,30 +252,23 @@ type IngressChartValue struct { } `yaml:"scope"` ConfigMapNamespace string `yaml:"configMapNamespace"` TCP struct { - ConfigMapNamespace string `yaml:"configMapNamespace"` - Annotations struct { - } `yaml:"annotations"` + ConfigMapNamespace string `yaml:"configMapNamespace"` + Annotations struct{} `yaml:"annotations"` } `yaml:"tcp"` UDP struct { - ConfigMapNamespace string `yaml:"configMapNamespace"` - Annotations struct { - } `yaml:"annotations"` + ConfigMapNamespace string `yaml:"configMapNamespace"` + Annotations struct{} `yaml:"annotations"` } `yaml:"udp"` - MaxmindLicenseKey string `yaml:"maxmindLicenseKey"` - ExtraArgs struct { - } `yaml:"extraArgs"` - ExtraEnvs []interface{} `yaml:"extraEnvs"` - Kind string `yaml:"kind"` - Annotations struct { - } `yaml:"annotations"` - Labels struct { - } `yaml:"labels"` - UpdateStrategy struct { - } `yaml:"updateStrategy"` - MinReadySeconds int `yaml:"minReadySeconds"` - Tolerations []interface{} `yaml:"tolerations"` - Affinity struct { - } `yaml:"affinity"` + MaxmindLicenseKey string `yaml:"maxmindLicenseKey"` + ExtraArgs struct{} `yaml:"extraArgs"` + ExtraEnvs []interface{} `yaml:"extraEnvs"` + Kind string `yaml:"kind"` + Annotations struct{} `yaml:"annotations"` + Labels struct{} `yaml:"labels"` + UpdateStrategy struct{} `yaml:"updateStrategy"` + MinReadySeconds int `yaml:"minReadySeconds"` + Tolerations []interface{} `yaml:"tolerations"` + Affinity struct{} `yaml:"affinity"` TopologySpreadConstraints []interface{} `yaml:"topologySpreadConstraints"` TerminationGracePeriodSeconds int `yaml:"terminationGracePeriodSeconds"` NodeSelector struct { @@ -316,29 +298,26 @@ type IngressChartValue struct { SuccessThreshold int `yaml:"successThreshold"` FailureThreshold int `yaml:"failureThreshold"` } `yaml:"readinessProbe"` - HealthCheckPath string `yaml:"healthCheckPath"` - HealthCheckHost string `yaml:"healthCheckHost"` - PodAnnotations struct { - } `yaml:"podAnnotations"` - ReplicaCount int `yaml:"replicaCount"` - MinAvailable int `yaml:"minAvailable"` - Resources struct { + HealthCheckPath string `yaml:"healthCheckPath"` + HealthCheckHost string `yaml:"healthCheckHost"` + PodAnnotations struct{} `yaml:"podAnnotations"` + ReplicaCount int `yaml:"replicaCount"` + MinAvailable int `yaml:"minAvailable"` + Resources struct { Requests struct { CPU string `yaml:"cpu"` Memory string `yaml:"memory"` } `yaml:"requests"` } `yaml:"resources"` Autoscaling struct { - APIVersion string `yaml:"apiVersion"` - Enabled bool `yaml:"enabled"` - Annotations struct { - } `yaml:"annotations"` - MinReplicas int `yaml:"minReplicas"` - MaxReplicas int `yaml:"maxReplicas"` - TargetCPUUtilizationPercentage int `yaml:"targetCPUUtilizationPercentage"` - TargetMemoryUtilizationPercentage int `yaml:"targetMemoryUtilizationPercentage"` - Behavior struct { - } `yaml:"behavior"` + APIVersion string `yaml:"apiVersion"` + Enabled bool `yaml:"enabled"` + Annotations struct{} `yaml:"annotations"` + MinReplicas int `yaml:"minReplicas"` + MaxReplicas int `yaml:"maxReplicas"` + TargetCPUUtilizationPercentage int `yaml:"targetCPUUtilizationPercentage"` + TargetMemoryUtilizationPercentage int `yaml:"targetMemoryUtilizationPercentage"` + Behavior struct{} `yaml:"behavior"` } `yaml:"autoscaling"` AutoscalingTemplate []interface{} `yaml:"autoscalingTemplate"` Keda struct { @@ -350,12 +329,10 @@ type IngressChartValue struct { CooldownPeriod int `yaml:"cooldownPeriod"` RestoreToOriginalReplicaCount bool `yaml:"restoreToOriginalReplicaCount"` ScaledObject struct { - Annotations struct { - } `yaml:"annotations"` + Annotations struct{} `yaml:"annotations"` } `yaml:"scaledObject"` Triggers []interface{} `yaml:"triggers"` - Behavior struct { - } `yaml:"behavior"` + Behavior struct{} `yaml:"behavior"` } `yaml:"keda"` EnableMimalloc bool `yaml:"enableMimalloc"` CustomTemplate struct { @@ -363,12 +340,10 @@ type IngressChartValue struct { ConfigMapKey string `yaml:"configMapKey"` } `yaml:"customTemplate"` Service struct { - Enabled bool `yaml:"enabled"` - AppProtocol bool `yaml:"appProtocol"` - Annotations struct { - } `yaml:"annotations"` - Labels struct { - } `yaml:"labels"` + Enabled bool `yaml:"enabled"` + AppProtocol bool `yaml:"appProtocol"` + Annotations struct{} `yaml:"annotations"` + Labels struct{} `yaml:"labels"` ExternalIPs []interface{} `yaml:"externalIPs"` LoadBalancerIP string `yaml:"loadBalancerIP"` LoadBalancerSourceRanges []interface{} `yaml:"loadBalancerSourceRanges"` @@ -386,20 +361,17 @@ type IngressChartValue struct { } `yaml:"targetPorts"` Type string `yaml:"type"` NodePorts struct { - HTTP string `yaml:"http"` - HTTPS string `yaml:"https"` - TCP struct { - } `yaml:"tcp"` - UDP struct { - } `yaml:"udp"` + HTTP string `yaml:"http"` + HTTPS string `yaml:"https"` + TCP struct{} `yaml:"tcp"` + UDP struct{} `yaml:"udp"` } `yaml:"nodePorts"` External struct { Enabled bool `yaml:"enabled"` } `yaml:"external"` Internal struct { - Enabled bool `yaml:"enabled"` - Annotations struct { - } `yaml:"annotations"` + Enabled bool `yaml:"enabled"` + Annotations struct{} `yaml:"annotations"` LoadBalancerSourceRanges []interface{} `yaml:"loadBalancerSourceRanges"` } `yaml:"internal"` } `yaml:"service"` @@ -417,25 +389,20 @@ type IngressChartValue struct { } `yaml:"containerSecurityContext"` } `yaml:"opentelemetry"` AdmissionWebhooks struct { - Annotations struct { - } `yaml:"annotations"` - Enabled bool `yaml:"enabled"` - ExtraEnvs []interface{} `yaml:"extraEnvs"` - FailurePolicy string `yaml:"failurePolicy"` - Port int `yaml:"port"` - Certificate string `yaml:"certificate"` - Key string `yaml:"key"` - NamespaceSelector struct { - } `yaml:"namespaceSelector"` - ObjectSelector struct { - } `yaml:"objectSelector"` - Labels struct { - } `yaml:"labels"` - ExistingPsp string `yaml:"existingPsp"` - NetworkPolicyEnabled bool `yaml:"networkPolicyEnabled"` + Annotations struct{} `yaml:"annotations"` + Enabled bool `yaml:"enabled"` + ExtraEnvs []interface{} `yaml:"extraEnvs"` + FailurePolicy string `yaml:"failurePolicy"` + Port int `yaml:"port"` + Certificate string `yaml:"certificate"` + Key string `yaml:"key"` + NamespaceSelector struct{} `yaml:"namespaceSelector"` + ObjectSelector struct{} `yaml:"objectSelector"` + Labels struct{} `yaml:"labels"` + ExistingPsp string `yaml:"existingPsp"` + NetworkPolicyEnabled bool `yaml:"networkPolicyEnabled"` Service struct { - Annotations struct { - } `yaml:"annotations"` + Annotations struct{} `yaml:"annotations"` ExternalIPs []interface{} `yaml:"externalIPs"` LoadBalancerSourceRanges []interface{} `yaml:"loadBalancerSourceRanges"` ServicePort int `yaml:"servicePort"` @@ -445,15 +412,13 @@ type IngressChartValue struct { SecurityContext struct { AllowPrivilegeEscalation bool `yaml:"allowPrivilegeEscalation"` } `yaml:"securityContext"` - Resources struct { - } `yaml:"resources"` + Resources struct{} `yaml:"resources"` } `yaml:"createSecretJob"` PatchWebhookJob struct { SecurityContext struct { AllowPrivilegeEscalation bool `yaml:"allowPrivilegeEscalation"` } `yaml:"securityContext"` - Resources struct { - } `yaml:"resources"` + Resources struct{} `yaml:"resources"` } `yaml:"patchWebhookJob"` Patch struct { Enabled bool `yaml:"enabled"` @@ -464,15 +429,13 @@ type IngressChartValue struct { Digest string `yaml:"digest"` PullPolicy string `yaml:"pullPolicy"` } `yaml:"image"` - PriorityClassName string `yaml:"priorityClassName"` - PodAnnotations struct { - } `yaml:"podAnnotations"` - NodeSelector struct { + PriorityClassName string `yaml:"priorityClassName"` + PodAnnotations struct{} `yaml:"podAnnotations"` + NodeSelector struct { KubernetesIoOs string `yaml:"kubernetes.io/os"` } `yaml:"nodeSelector"` - Tolerations []interface{} `yaml:"tolerations"` - Labels struct { - } `yaml:"labels"` + Tolerations []interface{} `yaml:"tolerations"` + Labels struct{} `yaml:"labels"` SecurityContext struct { RunAsNonRoot bool `yaml:"runAsNonRoot"` RunAsUser int `yaml:"runAsUser"` @@ -494,30 +457,26 @@ type IngressChartValue struct { PortName string `yaml:"portName"` Enabled bool `yaml:"enabled"` Service struct { - Annotations struct { - } `yaml:"annotations"` + Annotations struct{} `yaml:"annotations"` ExternalIPs []interface{} `yaml:"externalIPs"` LoadBalancerSourceRanges []interface{} `yaml:"loadBalancerSourceRanges"` ServicePort int `yaml:"servicePort"` Type string `yaml:"type"` } `yaml:"service"` ServiceMonitor struct { - Enabled bool `yaml:"enabled"` - AdditionalLabels struct { - } `yaml:"additionalLabels"` - Namespace string `yaml:"namespace"` - NamespaceSelector struct { - } `yaml:"namespaceSelector"` + Enabled bool `yaml:"enabled"` + AdditionalLabels struct{} `yaml:"additionalLabels"` + Namespace string `yaml:"namespace"` + NamespaceSelector struct{} `yaml:"namespaceSelector"` ScrapeInterval string `yaml:"scrapeInterval"` TargetLabels []interface{} `yaml:"targetLabels"` Relabelings []interface{} `yaml:"relabelings"` MetricRelabelings []interface{} `yaml:"metricRelabelings"` } `yaml:"serviceMonitor"` PrometheusRule struct { - Enabled bool `yaml:"enabled"` - AdditionalLabels struct { - } `yaml:"additionalLabels"` - Rules []interface{} `yaml:"rules"` + Enabled bool `yaml:"enabled"` + AdditionalLabels struct{} `yaml:"additionalLabels"` + Rules []interface{} `yaml:"rules"` } `yaml:"prometheusRule"` } `yaml:"metrics"` Lifecycle struct { @@ -543,9 +502,8 @@ type IngressChartValue struct { ReadOnlyRootFilesystem bool `yaml:"readOnlyRootFilesystem"` AllowPrivilegeEscalation bool `yaml:"allowPrivilegeEscalation"` } `yaml:"image"` - ExistingPsp string `yaml:"existingPsp"` - ExtraArgs struct { - } `yaml:"extraArgs"` + ExistingPsp string `yaml:"existingPsp"` + ExtraArgs struct{} `yaml:"extraArgs"` ServiceAccount struct { Create bool `yaml:"create"` Name string `yaml:"name"` @@ -567,46 +525,37 @@ type IngressChartValue struct { SuccessThreshold int `yaml:"successThreshold"` TimeoutSeconds int `yaml:"timeoutSeconds"` } `yaml:"readinessProbe"` - Tolerations []interface{} `yaml:"tolerations"` - Affinity struct { - } `yaml:"affinity"` - PodSecurityContext struct { - } `yaml:"podSecurityContext"` - ContainerSecurityContext struct { - } `yaml:"containerSecurityContext"` - PodLabels struct { - } `yaml:"podLabels"` - NodeSelector struct { + Tolerations []interface{} `yaml:"tolerations"` + Affinity struct{} `yaml:"affinity"` + PodSecurityContext struct{} `yaml:"podSecurityContext"` + ContainerSecurityContext struct{} `yaml:"containerSecurityContext"` + PodLabels struct{} `yaml:"podLabels"` + NodeSelector struct { KubernetesIoOs string `yaml:"kubernetes.io/os"` } `yaml:"nodeSelector"` - PodAnnotations struct { - } `yaml:"podAnnotations"` - ReplicaCount int `yaml:"replicaCount"` - MinAvailable int `yaml:"minAvailable"` - Resources struct { - } `yaml:"resources"` + PodAnnotations struct{} `yaml:"podAnnotations"` + ReplicaCount int `yaml:"replicaCount"` + MinAvailable int `yaml:"minAvailable"` + Resources struct{} `yaml:"resources"` ExtraVolumeMounts []interface{} `yaml:"extraVolumeMounts"` ExtraVolumes []interface{} `yaml:"extraVolumes"` Autoscaling struct { - Annotations struct { - } `yaml:"annotations"` - Enabled bool `yaml:"enabled"` - MinReplicas int `yaml:"minReplicas"` - MaxReplicas int `yaml:"maxReplicas"` - TargetCPUUtilizationPercentage int `yaml:"targetCPUUtilizationPercentage"` - TargetMemoryUtilizationPercentage int `yaml:"targetMemoryUtilizationPercentage"` + Annotations struct{} `yaml:"annotations"` + Enabled bool `yaml:"enabled"` + MinReplicas int `yaml:"minReplicas"` + MaxReplicas int `yaml:"maxReplicas"` + TargetCPUUtilizationPercentage int `yaml:"targetCPUUtilizationPercentage"` + TargetMemoryUtilizationPercentage int `yaml:"targetMemoryUtilizationPercentage"` } `yaml:"autoscaling"` Service struct { - Annotations struct { - } `yaml:"annotations"` + Annotations struct{} `yaml:"annotations"` ExternalIPs []interface{} `yaml:"externalIPs"` LoadBalancerSourceRanges []interface{} `yaml:"loadBalancerSourceRanges"` ServicePort int `yaml:"servicePort"` Type string `yaml:"type"` } `yaml:"service"` - PriorityClassName string `yaml:"priorityClassName"` - Labels struct { - } `yaml:"labels"` + PriorityClassName string `yaml:"priorityClassName"` + Labels struct{} `yaml:"labels"` } `yaml:"defaultBackend"` Rbac struct { Create bool `yaml:"create"` @@ -616,17 +565,14 @@ type IngressChartValue struct { Enabled bool `yaml:"enabled"` } `yaml:"podSecurityPolicy"` ServiceAccount struct { - Create bool `yaml:"create"` - Name string `yaml:"name"` - AutomountServiceAccountToken bool `yaml:"automountServiceAccountToken"` - Annotations struct { - } `yaml:"annotations"` + Create bool `yaml:"create"` + Name string `yaml:"name"` + AutomountServiceAccountToken bool `yaml:"automountServiceAccountToken"` + Annotations struct{} `yaml:"annotations"` } `yaml:"serviceAccount"` ImagePullSecrets []interface{} `yaml:"imagePullSecrets"` - TCP struct { - } `yaml:"tcp"` - UDP struct { - } `yaml:"udp"` - PortNamePrefix string `yaml:"portNamePrefix"` - DhParam interface{} `yaml:"dhParam"` + TCP struct{} `yaml:"tcp"` + UDP struct{} `yaml:"udp"` + PortNamePrefix string `yaml:"portNamePrefix"` + DhParam interface{} `yaml:"dhParam"` } diff --git a/magefiles/mage.go b/magefiles/mage.go index 605d687a98..ef54ee0f7d 100644 --- a/magefiles/mage.go +++ b/magefiles/mage.go @@ -20,8 +20,9 @@ limitations under the License. package main import ( - "github.com/magefile/mage/mage" "os" + + "github.com/magefile/mage/mage" ) func main() { diff --git a/magefiles/release.go b/magefiles/release.go index 6e5efb4902..e6dc6401dd 100644 --- a/magefiles/release.go +++ b/magefiles/release.go @@ -22,39 +22,45 @@ import ( "context" "errors" "fmt" - "github.com/google/go-github/v48/github" - "github.com/magefile/mage/mg" - "github.com/magefile/mage/sh" - "golang.org/x/oauth2" - "gopkg.in/yaml.v3" "io" "net" "net/http" "os" - "text/template" - "regexp" "strings" + "text/template" "time" + + "github.com/google/go-github/v48/github" + "github.com/magefile/mage/mg" + "github.com/magefile/mage/sh" + "golang.org/x/oauth2" + "gopkg.in/yaml.v3" ) type Release mg.Namespace -var INGRESS_ORG = "kubernetes" // the owner so we can test from forks -var INGRESS_REPO = "ingress-nginx" // the repo to pull from -var RELEASE_BRANCH = "main" //we only release from main -var GITHUB_TOKEN string // the Google/gogithub lib needs an PAT to access the GitHub API -var K8S_IO_ORG = "kubernetes" //the owner or organization for the k8s.io repo -var K8S_IO_REPO = "k8s.io" //the repo that holds the images yaml for production promotion -var INGRESS_REGISTRY = "registry.k8s.io" //Container registry for storage Ingress-nginx images -var KUSTOMIZE_INSTALL_VERSION = "sigs.k8s.io/kustomize/kustomize/v4@v4.5.4" //static deploys needs kustomize to generate the template +var ( + INGRESS_ORG = "kubernetes" // the owner so we can test from forks + INGRESS_REPO = "ingress-nginx" // the repo to pull from + RELEASE_BRANCH = "main" // we only release from main + GITHUB_TOKEN string // the Google/gogithub lib needs an PAT to access the GitHub API + K8S_IO_ORG = "kubernetes" // the owner or organization for the k8s.io repo + K8S_IO_REPO = "k8s.io" // the repo that holds the images yaml for production promotion + 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 -var IMAGES_YAML = "https://raw.githubusercontent.com/kubernetes/k8s.io/main/registry.k8s.io/images/k8s-staging-ingress-nginx/images.yaml" -var ctx = context.Background() // Context used for GitHub Client +var ( + 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 CHANGELOG = "Changelog.md" //Name of the changelog +const ( + 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 type ControllerImage struct { @@ -101,81 +107,80 @@ func init() { // PromoteImage Creates PR into the k8s.io repo for promotion of ingress from staging to production func (Release) PromoteImage(version, sha string) { - } // Release Create a new release of ingress nginx controller func (Release) NewRelease(version string) { - //newRelease := Release{} + // newRelease := Release{} - //update ingress-nginx version - //This is the step that kicks all the release process - //it is already done, so it kicks off the gcloud build of the controller images - //mg.Deps(mg.F(Tag.BumpNginx, version)) + // update ingress-nginx version + // This is the step that kicks all the release process + // it is already done, so it kicks off the gcloud build of the controller images + // mg.Deps(mg.F(Tag.BumpNginx, version)) tag, err := getIngressNGINXVersion() CheckIfError(err, "RELEASE Retrieving the current Ingress Nginx Version") Info("RELEASE Checking Current Version %s to New Version %s", tag, version) - //if the version were upgrading does not match the TAG file, lets update the TAG file + // if the version were upgrading does not match the TAG file, lets update the TAG file if tag[1:] != version { Warning("RELEASE Ingress Nginx TAG %s and new version %s do not match", tag, version) mg.Deps(mg.F(Tag.BumpNginx, fmt.Sprintf("v%s", version))) } - //update git controller tag controller-v$version + // update git controller tag controller-v$version mg.Deps(mg.F(Tag.NewControllerTag, version)) - //make release notes + // make release notes releaseNotes, err := makeReleaseNotes(version) CheckIfError(err, "RELEASE Creating Release Notes for version %s", version) Info("RELEASE Release Notes %s completed", releaseNotes.Version) - //update chart values.yaml new controller tag and image digest + // update chart values.yaml new controller tag and image digest releaseNotes.PreviousHelmChartVersion = currentChartVersion() - //controller tag + // controller tag updateChartValue("controller.image.tag", fmt.Sprintf("v%s", releaseNotes.Version)) Debug("releaseNotes.ControllerImages[0].Name %s", releaseNotes.ControllerImages[0].Name) Debug("releaseNotes.ControllerImages[1].Name %s", releaseNotes.ControllerImages[1].Name) - //controller digest + // controller digest if releaseNotes.ControllerImages[0].Name == "ingress-nginx/controller" { Debug("Updating Chart Value %s with %s", "controller.image.digest", releaseNotes.ControllerImages[0].Digest) updateChartValue("controller.image.digest", releaseNotes.ControllerImages[0].Digest) } - //controller chroot digest + // controller chroot digest if releaseNotes.ControllerImages[1].Name == "ingress-nginx/controller-chroot" { Debug("Updating Chart Value %s with %s", "controller.image.digestChroot", releaseNotes.ControllerImages[1].Digest) updateChartValue("controller.image.digestChroot", releaseNotes.ControllerImages[1].Digest) } - //update helm chart app version + // update helm chart app version mg.Deps(mg.F(Helm.UpdateVersion, version)) releaseNotes.NewHelmChartVersion = currentChartVersion() - //update helm chart release notes + // update helm chart release notes updateChartReleaseNotes(releaseNotes.HelmUpdates) - //Run helm docs update + // Run helm docs update CheckIfError(runHelmDocs(), "Error Updating Helm Docs ") releaseNotes.helmTemplate() - //update static manifest + // update static manifest CheckIfError(updateStaticManifest(), "Error Updating Static manifests") ////update e2e docs updateE2EDocs() - //update documentation with ingress-nginx version + // update documentation with ingress-nginx version CheckIfError(updateIndexMD(releaseNotes.PreviousControllerVersion, releaseNotes.NewControllerVersion), "Error Updating %s", INDEX_DOCS) - //keeping these manual for now - //git commit TODO - //make Pull Request TODO - //make release TODO - //mg.Deps(mg.F(Release.CreateRelease, version)) + // keeping these manual for now + // git commit TODO + // make Pull Request TODO + // make release TODO + // mg.Deps(mg.F(Release.CreateRelease, version)) } // the index.md doc needs the controller version updated @@ -204,7 +209,7 @@ func updateE2EDocs() { // The static deploy scripts use kustomize to generate them, this function ensures kustomize is installed func installKustomize() error { Info("Install Kustomize") - var g0 = sh.RunCmd("go") + g0 := sh.RunCmd("go") // somewhere in your main code err := g0("install", KUSTOMIZE_INSTALL_VERSION) if err != nil { @@ -215,7 +220,7 @@ func installKustomize() error { func updateStaticManifest() error { CheckIfError(installKustomize(), "error installing kustomize") - //hack/generate-deploy-scripts.sh + // hack/generate-deploy-scripts.sh err := sh.RunV("./hack/generate-deploy-scripts.sh") if err != nil { return err @@ -270,28 +275,28 @@ func (Release) ReleaseNotes(newVersion string) error { } func makeReleaseNotes(newVersion string) (*ReleaseNote, error) { - var newReleaseNotes = ReleaseNote{} + newReleaseNotes := ReleaseNote{} newReleaseNotes.Version = newVersion allControllerTags := getAllControllerTags() - //new version + // new version newReleaseNotes.NewControllerVersion = allControllerTags[0] newControllerVersion := fmt.Sprintf("controller-v%s", newVersion) - //the newControllerVersion should match the latest tag + // the newControllerVersion should match the latest tag if newControllerVersion != allControllerTags[0] { return nil, errors.New(fmt.Sprintf("Generating release new version %s didnt match the current latest tag %s", newControllerVersion, allControllerTags[0])) } - //previous version + // previous version newReleaseNotes.PreviousControllerVersion = allControllerTags[1] Info("New Version: %s Old Version: %s", newReleaseNotes.NewControllerVersion, newReleaseNotes.PreviousControllerVersion) commits := commitsBetweenTags() - //dependency_updates - //all_updates + // dependency_updates + // all_updates var allUpdates []string var depUpdates []string var helmUpdates []string @@ -299,9 +304,9 @@ func makeReleaseNotes(newVersion string) (*ReleaseNote, error) { depBot := regexp.MustCompile("^(\\w){1,10} Bump ") helmRegex := regexp.MustCompile("helm|chart") for i, s := range commits { - //matches on PR + // matches on PR if prRegex.Match([]byte(s)) { - //matches a dependant bot update + // matches a dependant bot update if depBot.Match([]byte(s)) { // Debug("#%v DEPENDABOT %v", i, s) u := strings.SplitN(s, " ", 2) @@ -311,13 +316,12 @@ func makeReleaseNotes(newVersion string) (*ReleaseNote, error) { u := strings.SplitN(s, " ", 2) allUpdates = append(allUpdates, u[1]) - //helm chart updates + // helm chart updates if helmRegex.Match([]byte(s)) { u := strings.SplitN(s, " ", 2) helmUpdates = append(helmUpdates, u[1]) } } - } } helmUpdates = append(helmUpdates, fmt.Sprintf("Update Ingress-Nginx version %s", newReleaseNotes.NewControllerVersion)) @@ -326,7 +330,7 @@ func makeReleaseNotes(newVersion string) (*ReleaseNote, error) { newReleaseNotes.DepUpdates = depUpdates newReleaseNotes.HelmUpdates = helmUpdates - //controller_image_digests + // controller_image_digests imagesYaml, err := downloadFile(IMAGES_YAML) if err != nil { ErrorF("Could not download file %s : %s", IMAGES_YAML, err) @@ -342,7 +346,7 @@ func makeReleaseNotes(newVersion string) (*ReleaseNote, error) { return nil, err } - //controller + // controller controllerDigest := findImageDigest(data, "controller", newVersion) if len(controllerDigest) == 0 { ErrorF("Controller Digest could not be found") @@ -379,7 +383,7 @@ func makeReleaseNotes(newVersion string) (*ReleaseNote, error) { newReleaseNotes.printRelease() } - //write it all out to the changelog file + // write it all out to the changelog file newReleaseNotes.template() return &newReleaseNotes, nil diff --git a/magefiles/tags.go b/magefiles/tags.go index 02bbbcb373..ca02c2cc36 100644 --- a/magefiles/tags.go +++ b/magefiles/tags.go @@ -20,11 +20,12 @@ package main import ( "fmt" + "os" + "strings" + semver "github.com/blang/semver/v4" "github.com/magefile/mage/mg" "github.com/magefile/mage/sh" - "os" - "strings" ) type Tag mg.Namespace @@ -42,7 +43,7 @@ func getIngressNGINXVersion() (string, error) { dat, err := os.ReadFile("TAG") CheckIfError(err, "Could not read TAG file") datString := string(dat) - //remove newline + // remove newline datString = strings.Replace(datString, "\n", "", -1) return datString, nil } @@ -88,14 +89,14 @@ func (Tag) BumpNginx(newTag string) { } func bump(currentTag, newTag string) { - //check if semver is valid + // check if semver is valid if !checkSemVer(currentTag, newTag) { ErrorF("ERROR: Semver is not valid %v", newTag) os.Exit(1) } 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") } diff --git a/test/e2e/admission/admission.go b/test/e2e/admission/admission.go index 726e16f0b6..c41105e2df 100644 --- a/test/e2e/admission/admission.go +++ b/test/e2e/admission/admission.go @@ -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() { + f.SetNginxConfigMapData(map[string]string{ + "allow-snippet-annotations": "true", + }) + defer func() { + f.SetNginxConfigMapData(map[string]string{ + "allow-snippet-annotations": "false", + }) + }() + host := admissionTestHost 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() { + 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) assert.Empty(ginkgo.GinkgoT(), out) 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() { + 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) 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") diff --git a/test/e2e/annotations/auth.go b/test/e2e/annotations/auth.go index be915a7223..415ffd951f 100644 --- a/test/e2e/annotations/auth.go +++ b/test/e2e/annotations/auth.go @@ -277,6 +277,14 @@ var _ = framework.DescribeAnnotation("auth-*", func() { "nginx.ingress.kubernetes.io/auth-snippet": ` 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) 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() { 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{ "nginx.ingress.kubernetes.io/auth-snippet": ` proxy_set_header My-Custom-Header 42;`, diff --git a/test/e2e/annotations/fastcgi.go b/test/e2e/annotations/fastcgi.go index 7ed35cb769..bcf1c3487b 100644 --- a/test/e2e/annotations/fastcgi.go +++ b/test/e2e/annotations/fastcgi.go @@ -82,7 +82,7 @@ var _ = framework.DescribeAnnotation("backend-protocol - FastCGI", func() { f.EnsureConfigMap(configuration) - host := "fastcgi-params-configmap" + host := "fastcgi-params-configmap" //#nosec G101 annotations := map[string]string{ "nginx.ingress.kubernetes.io/backend-protocol": "FCGI", diff --git a/test/e2e/annotations/fromtowwwredirect.go b/test/e2e/annotations/fromtowwwredirect.go index 4ee3d313cc..b69cce93e6 100644 --- a/test/e2e/annotations/fromtowwwredirect.go +++ b/test/e2e/annotations/fromtowwwredirect.go @@ -62,6 +62,15 @@ var _ = framework.DescribeAnnotation("from-to-www-redirect", 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") fromHost := fmt.Sprintf("%s.nip.io", f.GetNginxIP()) diff --git a/test/e2e/annotations/grpc.go b/test/e2e/annotations/grpc.go index 4c121df49b..b256b8ae4d 100644 --- a/test/e2e/annotations/grpc.go +++ b/test/e2e/annotations/grpc.go @@ -189,6 +189,15 @@ var _ = framework.DescribeAnnotation("backend-protocol - GRPC", func() { ginkgo.It("should return OK for service with backend protocol GRPCS", func() { f.NewGRPCBinDeployment() + f.SetNginxConfigMapData(map[string]string{ + "allow-snippet-annotations": "true", + }) + defer func() { + f.SetNginxConfigMapData(map[string]string{ + "allow-snippet-annotations": "false", + }) + }() + host := echoHost svc := &corev1.Service{ diff --git a/test/e2e/annotations/modsecurity/modsecurity.go b/test/e2e/annotations/modsecurity/modsecurity.go index 71e8963e3e..a3e7d80ba6 100644 --- a/test/e2e/annotations/modsecurity/modsecurity.go +++ b/test/e2e/annotations/modsecurity/modsecurity.go @@ -100,6 +100,15 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", 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 nameSpace := f.Namespace @@ -164,6 +173,15 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", 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 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() { + f.SetNginxConfigMapData(map[string]string{ + "allow-snippet-annotations": "true", + }) + defer func() { + f.SetNginxConfigMapData(map[string]string{ + "allow-snippet-annotations": "false", + }) + }() + host := modSecurityFooHost 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() { + 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 nameSpace := f.Namespace @@ -238,11 +276,6 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() { ing := framework.NewSingleIngress(host, "/", host, nameSpace, framework.EchoService, 80, annotations) f.EnsureIngress(ing) - f.SetNginxConfigMapData(map[string]string{ - "enable-modsecurity": "true", - "enable-owasp-modsecurity-crs": "true", - }) - f.WaitForNginxServer(host, func(server string) bool { return strings.Contains(server, "SecRuleEngine On") @@ -277,12 +310,17 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() { f.EnsureIngress(ing) expectedComment := "SecRuleEngine On" - f.SetNginxConfigMapData(map[string]string{ + "allow-snippet-annotations": "true", "enable-modsecurity": "true", "enable-owasp-modsecurity-crs": "true", "modsecurity-snippet": expectedComment, }) + defer func() { + f.SetNginxConfigMapData(map[string]string{ + "allow-snippet-annotations": "false", + }) + }() f.WaitForNginxServer(host, 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() { + f.SetNginxConfigMapData(map[string]string{ + "allow-snippet-annotations": "true", + }) + defer func() { + f.SetNginxConfigMapData(map[string]string{ + "allow-snippet-annotations": "false", + }) + }() host := modSecurityFooHost nameSpace := f.Namespace diff --git a/test/e2e/annotations/serversnippet.go b/test/e2e/annotations/serversnippet.go index e74fa37f5e..1195b728ab 100644 --- a/test/e2e/annotations/serversnippet.go +++ b/test/e2e/annotations/serversnippet.go @@ -33,6 +33,15 @@ var _ = framework.DescribeAnnotation("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" annotations := map[string]string{ "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() { + f.SetNginxConfigMapData(map[string]string{ + "allow-snippet-annotations": "true", + }) + defer func() { + f.SetNginxConfigMapData(map[string]string{ + "allow-snippet-annotations": "false", + }) + }() + host := "noserversnippet.foo.com" annotations := map[string]string{ "nginx.ingress.kubernetes.io/server-snippet": ` diff --git a/test/e2e/annotations/snippet.go b/test/e2e/annotations/snippet.go index 2bbd3e33a2..0c6148a4ff 100644 --- a/test/e2e/annotations/snippet.go +++ b/test/e2e/annotations/snippet.go @@ -33,6 +33,16 @@ var _ = framework.DescribeAnnotation("configuration-snippet", func() { ginkgo.It("set snippet more_set_headers in all locations", func() { 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{ "nginx.ingress.kubernetes.io/configuration-snippet": `more_set_headers "Foo1: Bar1";`, } @@ -76,10 +86,6 @@ var _ = framework.DescribeAnnotation("configuration-snippet", func() { annotations) 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 framework.Sleep() diff --git a/test/e2e/annotations/streamsnippet.go b/test/e2e/annotations/streamsnippet.go index b5df50975e..432537b4a8 100644 --- a/test/e2e/annotations/streamsnippet.go +++ b/test/e2e/annotations/streamsnippet.go @@ -39,6 +39,15 @@ var _ = framework.DescribeSetting("stream-snippet", 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" snippet := `server {listen 8000; proxy_pass 127.0.0.1:80;}` diff --git a/test/e2e/framework/deployment.go b/test/e2e/framework/deployment.go index 7ac150dcfa..08a5353b24 100644 --- a/test/e2e/framework/deployment.go +++ b/test/e2e/framework/deployment.go @@ -47,7 +47,7 @@ const NIPService = "external-nip" var HTTPBunImage = os.Getenv("HTTPBUN_IMAGE") // 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 // in order to reduce complexity and have a unified API across the diff --git a/test/e2e/ingress/multiple_rules.go b/test/e2e/ingress/multiple_rules.go index c08f36374b..f44b2f8dd7 100644 --- a/test/e2e/ingress/multiple_rules.go +++ b/test/e2e/ingress/multiple_rules.go @@ -36,6 +36,15 @@ var _ = framework.IngressNginxDescribe("single ingress - multiple hosts", 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{ "nginx.ingress.kubernetes.io/configuration-snippet": `more_set_input_headers "service-name: $service_name";`, } diff --git a/test/e2e/ingress/pathtype_exact.go b/test/e2e/ingress/pathtype_exact.go index ccc76b5bc6..d0564cbf6e 100644 --- a/test/e2e/ingress/pathtype_exact.go +++ b/test/e2e/ingress/pathtype_exact.go @@ -35,6 +35,15 @@ var _ = framework.IngressNginxDescribe("[Ingress] [PathType] 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" annotations := map[string]string{ diff --git a/test/e2e/ingress/pathtype_mixed.go b/test/e2e/ingress/pathtype_mixed.go index c55a2c32a2..e7bf2532e1 100644 --- a/test/e2e/ingress/pathtype_mixed.go +++ b/test/e2e/ingress/pathtype_mixed.go @@ -37,6 +37,15 @@ var _ = framework.IngressNginxDescribe("[Ingress] [PathType] mix Exact and Prefi exactPathType := networking.PathTypeExact 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" annotations := map[string]string{ diff --git a/test/e2e/settings/badannotationvalues.go b/test/e2e/settings/badannotationvalues.go index 68a122e769..f61b5bada0 100644 --- a/test/e2e/settings/badannotationvalues.go +++ b/test/e2e/settings/badannotationvalues.go @@ -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() { + f.SetNginxConfigMapData(map[string]string{ + "allow-snippet-annotations": "true", + }) + defer func() { + f.SetNginxConfigMapData(map[string]string{ + "allow-snippet-annotations": "false", + }) + }() host := "invalid-value-test" 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() { + f.SetNginxConfigMapData(map[string]string{ + "allow-snippet-annotations": "true", + }) + defer func() { + f.SetNginxConfigMapData(map[string]string{ + "allow-snippet-annotations": "false", + }) + }() + host := "forbidden-value-test" 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() { + 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" annotationsValid := map[string]string{ "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() { + 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" annotations := map[string]string{ diff --git a/test/e2e/settings/geoip2.go b/test/e2e/settings/geoip2.go index 6dd48b2ad7..e37286d5c3 100644 --- a/test/e2e/settings/geoip2.go +++ b/test/e2e/settings/geoip2.go @@ -69,7 +69,15 @@ var _ = framework.DescribeSetting("Geoip2", func() { ginkgo.It("should only allow requests from specific countries", func() { 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 { default 1; diff --git a/test/e2e/settings/proxy_host.go b/test/e2e/settings/proxy_host.go index efc254e458..35aafc53d3 100644 --- a/test/e2e/settings/proxy_host.go +++ b/test/e2e/settings/proxy_host.go @@ -34,6 +34,14 @@ var _ = framework.IngressNginxDescribe("Dynamic $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) annotations := map[string]string{ "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() { + 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) upstreamVHost := "different.host" annotations := map[string]string{ diff --git a/test/e2e/settings/server_snippet.go b/test/e2e/settings/server_snippet.go index 1577c927c9..8ddf10fd9f 100644 --- a/test/e2e/settings/server_snippet.go +++ b/test/e2e/settings/server_snippet.go @@ -37,10 +37,16 @@ var _ = framework.DescribeSetting("configmap server-snippet", func() { hostAnnots := "serverannotssnippet1.foo.com" f.SetNginxConfigMapData(map[string]string{ + "allow-snippet-annotations": "true", "server-snippet": ` more_set_headers "Globalfoo: Foooo";`, }) + defer func() { + f.SetNginxConfigMapData(map[string]string{ + "allow-snippet-annotations": "false", + }) + }() annotations := map[string]string{ "nginx.ingress.kubernetes.io/server-snippet": ` more_set_headers "Foo: Bar"; @@ -99,6 +105,11 @@ var _ = framework.DescribeSetting("configmap server-snippet", func() { more_set_headers "Globalfoo: Foooo";`, }) + defer func() { + f.SetNginxConfigMapData(map[string]string{ + "allow-snippet-annotations": "false", + }) + }() annotations := map[string]string{ "nginx.ingress.kubernetes.io/server-snippet": ` more_set_headers "Foo: Bar"; diff --git a/test/e2e/settings/validations/validations.go b/test/e2e/settings/validations/validations.go index 19488d2471..ac95a453a2 100644 --- a/test/e2e/settings/validations/validations.go +++ b/test/e2e/settings/validations/validations.go @@ -31,6 +31,15 @@ var _ = framework.IngressNginxDescribeSerial("annotation validations", func() { f := framework.NewDefaultFramework("validations") //nolint:dupl // Ignore dupl errors for similar test case 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" // 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 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" // Low and Medium Risk annotations should be allowed, the rest should be denied