Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ DMT includes **9 specialized linters** to validate different aspects of your Dec
| [**NoCyrillic**](pkg/linters/no-cyrillic/README.md) | Character encoding | Cyrillic characters in code/config files |
| [**OpenAPI**](pkg/linters/openapi/README.md) | OpenAPI schemas | Schema validation, CRD definitions, naming conventions |
| [**RBAC**](pkg/linters/rbac/README.md) | Security policies | Role bindings, service accounts, wildcards |
| [**Templates**](pkg/linters/templates/README.md) | Kubernetes templates | VPA/PDB settings, Prometheus rules, Grafana dashboards, service ports, mount-points |
| [**Templates**](pkg/linters/templates/README.md) | Kubernetes templates | VPA/PDB settings, Prometheus rules, Grafana dashboards, service ports, mount-points, Ingress/Gateway API enablement, deprecated annotations |

### 🚀 Module Bootstrapping

Expand Down
66 changes: 66 additions & 0 deletions internal/modules/https_certificate_reuse_exclude_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
Copyright 2026 Flant JSC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package modules

import (
"testing"

"github.com/stretchr/testify/require"

"github.com/deckhouse/dmt/pkg"
"github.com/deckhouse/dmt/pkg/config"
"github.com/deckhouse/dmt/pkg/config/global"
)

// TestRemapHTTPSCertificateReuseExcludeRules proves that a module's
// .dmtlint.yaml exclude-rules for https-certificate-reuse (parsed into
// config.TemplatesExcludeRules by viper/mapstructure) actually reach the
// pkg.TemplatesExcludeRules the rule itself reads from — the same path
// IngressEnablement/GatewayEnablement already use.
func TestRemapHTTPSCertificateReuseExcludeRules(t *testing.T) {
configSettings := &config.LintersSettings{
Templates: config.TemplatesSettings{
ExcludeRules: config.TemplatesExcludeRules{
HTTPSCertificateReuse: config.PathRuleExclude{
Files: config.StringRuleExcludeList{"templates/legacy-certificate.yaml"},
Directories: config.DirectoryRuleExcludeList{"templates/vendor/"},
},
},
},
}

settings := remapLinterSettings(configSettings, &global.Linters{})

excludes := settings.Templates.ExcludeRules.HTTPSCertificateReuse
require.Equal(t, pkg.StringRuleExcludeList{"templates/legacy-certificate.yaml"}, excludes.Files)
require.Equal(t, pkg.DirectoryRuleExcludeList{"templates/vendor/"}, excludes.Directories)
}

// TestRemapHTTPSCertificateReuseRuleLevel proves the rule-level impact
// override (global org-wide config, mirroring how every other Templates
// rule's level is wired) reaches pkg.TemplatesLinterRules too.
func TestRemapHTTPSCertificateReuseRuleLevel(t *testing.T) {
settings := remapLinterSettings(&config.LintersSettings{}, &global.Linters{
Templates: global.TemplatesLinterConfig{
Rules: global.TemplatesLinterRules{
HTTPSCertificateReuseRule: global.RuleConfig{Impact: pkg.Warn.String()},
},
},
})

require.Equal(t, pkg.Warn, *settings.Templates.Rules.HTTPSCertificateReuseRule.GetLevel())
}
12 changes: 12 additions & 0 deletions internal/modules/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,10 @@ func mapTemplatesRules(linterSettings *pkg.LintersSettings, configSettings *conf
rules.HelmRenderRule.SetLevel(globalRules.HelmRenderRule.Impact, fallbackImpact)
rules.OpenAPIValuesQuoteRule.SetLevel(globalRules.OpenAPIValuesQuoteRule.Impact, fallbackImpact)
rules.SchemaValidationRule.SetLevel(globalRules.SchemaValidationRule.Impact, fallbackImpact)
rules.DeprecatedHTTPRouteAnnotationsRule.SetLevel(globalRules.DeprecatedHTTPRouteAnnotationsRule.Impact, fallbackImpact)
rules.IngressEnablementRule.SetLevel(globalRules.IngressEnablementRule.Impact, fallbackImpact)
rules.GatewayEnablementRule.SetLevel(globalRules.GatewayEnablementRule.Impact, fallbackImpact)
rules.HTTPSCertificateReuseRule.SetLevel(globalRules.HTTPSCertificateReuseRule.Impact, fallbackImpact)
}

// mapOpenAPIRules configures OpenAPI linter rules
Expand Down Expand Up @@ -552,6 +556,14 @@ func mapTemplatesExclusionsAndSettings(linterSettings *pkg.LintersSettings, conf
excludes.MountPoints = pkg.StringRuleExcludeList(configExcludes.MountPoints)
excludes.OpenAPIValuesQuote = pkg.StringRuleExcludeList(configExcludes.OpenAPIValuesQuote)
excludes.SchemaValidation = configExcludes.SchemaValidation.Get()
excludes.DeprecatedHTTPRouteAnnotations.Files = pkg.StringRuleExcludeList(configExcludes.DeprecatedHTTPRouteAnnotations.Files)
excludes.DeprecatedHTTPRouteAnnotations.Directories = pkg.DirectoryRuleExcludeList(configExcludes.DeprecatedHTTPRouteAnnotations.Directories)
excludes.IngressEnablement.Files = pkg.StringRuleExcludeList(configExcludes.IngressEnablement.Files)
excludes.IngressEnablement.Directories = pkg.DirectoryRuleExcludeList(configExcludes.IngressEnablement.Directories)
excludes.GatewayEnablement.Files = pkg.StringRuleExcludeList(configExcludes.GatewayEnablement.Files)
excludes.GatewayEnablement.Directories = pkg.DirectoryRuleExcludeList(configExcludes.GatewayEnablement.Directories)
excludes.HTTPSCertificateReuse.Files = pkg.StringRuleExcludeList(configExcludes.HTTPSCertificateReuse.Files)
excludes.HTTPSCertificateReuse.Directories = pkg.DirectoryRuleExcludeList(configExcludes.HTTPSCertificateReuse.Directories)

// Additional settings
linterSettings.Templates.PrometheusRuleSettings.Disable = configSettings.Templates.PrometheusRules.Disable
Expand Down
71 changes: 43 additions & 28 deletions pkg/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,23 +137,27 @@ type TemplatesLinterConfig struct {
GrafanaDashboardsSettings GrafanaDashboardsSettings
}
type TemplatesLinterRules struct {
VPARule RuleConfig
PDBRule RuleConfig
IngressRule RuleConfig
PrometheusRule RuleConfig
GrafanaRule RuleConfig
KubeRBACProxyRule RuleConfig
ServicePortRule RuleConfig
ClusterDomainRule RuleConfig
RegistryRule RuleConfig
HTTPRouteRule RuleConfig
EnabledModulesRule RuleConfig
CRDEnabledModulesRule RuleConfig
WebhookConfigurationRule RuleConfig
MountPointsRule RuleConfig
HelmRenderRule RuleConfig
OpenAPIValuesQuoteRule RuleConfig
SchemaValidationRule RuleConfig
VPARule RuleConfig
PDBRule RuleConfig
IngressRule RuleConfig
PrometheusRule RuleConfig
GrafanaRule RuleConfig
KubeRBACProxyRule RuleConfig
ServicePortRule RuleConfig
ClusterDomainRule RuleConfig
RegistryRule RuleConfig
HTTPRouteRule RuleConfig
EnabledModulesRule RuleConfig
CRDEnabledModulesRule RuleConfig
WebhookConfigurationRule RuleConfig
MountPointsRule RuleConfig
HelmRenderRule RuleConfig
OpenAPIValuesQuoteRule RuleConfig
SchemaValidationRule RuleConfig
DeprecatedHTTPRouteAnnotationsRule RuleConfig
IngressEnablementRule RuleConfig
GatewayEnablementRule RuleConfig
HTTPSCertificateReuseRule RuleConfig
}

type PrometheusRuleSettings struct {
Expand All @@ -164,17 +168,28 @@ type GrafanaDashboardsSettings struct {
Disable bool
}
type TemplatesExcludeRules struct {
VPAAbsent KindRuleExcludeList
PDBAbsent KindRuleExcludeList
ServicePort ServicePortExcludeList
KubeRBACProxy StringRuleExcludeList
Ingress KindRuleExcludeList
HTTPRoute KindRuleExcludeList
EnabledModules EnabledModulesExcludeRule
WebhookConfiguration KindRuleExcludeList
MountPoints StringRuleExcludeList
OpenAPIValuesQuote StringRuleExcludeList
SchemaValidation KindRuleExcludeList
VPAAbsent KindRuleExcludeList
PDBAbsent KindRuleExcludeList
ServicePort ServicePortExcludeList
KubeRBACProxy StringRuleExcludeList
Ingress KindRuleExcludeList
HTTPRoute KindRuleExcludeList
EnabledModules EnabledModulesExcludeRule
WebhookConfiguration KindRuleExcludeList
MountPoints StringRuleExcludeList
OpenAPIValuesQuote StringRuleExcludeList
SchemaValidation KindRuleExcludeList
DeprecatedHTTPRouteAnnotations PathRuleExclude
IngressEnablement PathRuleExclude
GatewayEnablement PathRuleExclude
HTTPSCertificateReuse PathRuleExclude
}

// PathRuleExclude excludes specific files and whole directories (both relative
// to the module root) from a rule that scans template source files.
type PathRuleExclude struct {
Files StringRuleExcludeList
Directories DirectoryRuleExcludeList
}

type EnabledModulesExcludeRule struct {
Expand Down
38 changes: 21 additions & 17 deletions pkg/config/global/global.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,23 +140,27 @@ type TemplatesLinterConfig struct {
}

type TemplatesLinterRules struct {
VPARule RuleConfig `mapstructure:"vpa"`
PDBRule RuleConfig `mapstructure:"pdb"`
IngressRule RuleConfig `mapstructure:"ingress"`
HTTPRouteRule RuleConfig `mapstructure:"httproute"`
PrometheusRule RuleConfig `mapstructure:"prometheus-rules"`
GrafanaRule RuleConfig `mapstructure:"grafana-dashboards"`
KubeRBACProxyRule RuleConfig `mapstructure:"kube-rbac-proxy"`
ServicePortRule RuleConfig `mapstructure:"service-port"`
ClusterDomainRule RuleConfig `mapstructure:"cluster-domain"`
RegistryRule RuleConfig `mapstructure:"registry"`
EnabledModulesRule RuleConfig `mapstructure:"enabled-modules"`
CRDEnabledModulesRule RuleConfig `mapstructure:"crd-enabled-modules"`
WebhookConfigurationRule RuleConfig `mapstructure:"webhook-configuration-annotations"`
MountPointsRule RuleConfig `mapstructure:"mount-points"`
HelmRenderRule RuleConfig `mapstructure:"helm-render"`
OpenAPIValuesQuoteRule RuleConfig `mapstructure:"openapi-values-quote"`
SchemaValidationRule RuleConfig `mapstructure:"schema-validation"`
VPARule RuleConfig `mapstructure:"vpa"`
PDBRule RuleConfig `mapstructure:"pdb"`
IngressRule RuleConfig `mapstructure:"ingress"`
HTTPRouteRule RuleConfig `mapstructure:"httproute"`
PrometheusRule RuleConfig `mapstructure:"prometheus-rules"`
GrafanaRule RuleConfig `mapstructure:"grafana-dashboards"`
KubeRBACProxyRule RuleConfig `mapstructure:"kube-rbac-proxy"`
ServicePortRule RuleConfig `mapstructure:"service-port"`
ClusterDomainRule RuleConfig `mapstructure:"cluster-domain"`
RegistryRule RuleConfig `mapstructure:"registry"`
EnabledModulesRule RuleConfig `mapstructure:"enabled-modules"`
CRDEnabledModulesRule RuleConfig `mapstructure:"crd-enabled-modules"`
WebhookConfigurationRule RuleConfig `mapstructure:"webhook-configuration-annotations"`
MountPointsRule RuleConfig `mapstructure:"mount-points"`
HelmRenderRule RuleConfig `mapstructure:"helm-render"`
OpenAPIValuesQuoteRule RuleConfig `mapstructure:"openapi-values-quote"`
SchemaValidationRule RuleConfig `mapstructure:"schema-validation"`
DeprecatedHTTPRouteAnnotationsRule RuleConfig `mapstructure:"deprecated-httproute-annotations"`
IngressEnablementRule RuleConfig `mapstructure:"ingress-enablement"`
GatewayEnablementRule RuleConfig `mapstructure:"gateway-enablement"`
HTTPSCertificateReuseRule RuleConfig `mapstructure:"https-certificate-reuse"`
}

func (c LinterConfig) IsWarn() bool {
Expand Down
71 changes: 43 additions & 28 deletions pkg/config/linters_settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,44 +234,59 @@ type TemplatesSettings struct {
}

type TemplatesLinterRules struct {
VPARule RuleConfig `mapstructure:"vpa"`
PDBRule RuleConfig `mapstructure:"pdb"`
IngressRule RuleConfig `mapstructure:"ingress"`
HTTPRouteRule RuleConfig `mapstructure:"httproute"`
PrometheusRule RuleConfig `mapstructure:"prometheus-rules"`
GrafanaRule RuleConfig `mapstructure:"grafana-dashboards"`
KubeRBACProxyRule RuleConfig `mapstructure:"kube-rbac-proxy"`
ServicePortRule RuleConfig `mapstructure:"service-port"`
ClusterDomainRule RuleConfig `mapstructure:"cluster-domain"`
RegistryRule RuleConfig `mapstructure:"registry"`
EnabledModulesRule RuleConfig `mapstructure:"enabled-modules"`
CRDEnabledModulesRule RuleConfig `mapstructure:"crd-enabled-modules"`
WebhookConfigurationRule RuleConfig `mapstructure:"webhook-configuration-annotations"`
MountPointsRule RuleConfig `mapstructure:"mount-points"`
HelmRenderRule RuleConfig `mapstructure:"helm-render"`
OpenAPIValuesQuoteRule RuleConfig `mapstructure:"openapi-values-quote"`
SchemaValidationRule RuleConfig `mapstructure:"schema-validation"`
VPARule RuleConfig `mapstructure:"vpa"`
PDBRule RuleConfig `mapstructure:"pdb"`
IngressRule RuleConfig `mapstructure:"ingress"`
HTTPRouteRule RuleConfig `mapstructure:"httproute"`
PrometheusRule RuleConfig `mapstructure:"prometheus-rules"`
GrafanaRule RuleConfig `mapstructure:"grafana-dashboards"`
KubeRBACProxyRule RuleConfig `mapstructure:"kube-rbac-proxy"`
ServicePortRule RuleConfig `mapstructure:"service-port"`
ClusterDomainRule RuleConfig `mapstructure:"cluster-domain"`
RegistryRule RuleConfig `mapstructure:"registry"`
EnabledModulesRule RuleConfig `mapstructure:"enabled-modules"`
CRDEnabledModulesRule RuleConfig `mapstructure:"crd-enabled-modules"`
WebhookConfigurationRule RuleConfig `mapstructure:"webhook-configuration-annotations"`
MountPointsRule RuleConfig `mapstructure:"mount-points"`
HelmRenderRule RuleConfig `mapstructure:"helm-render"`
OpenAPIValuesQuoteRule RuleConfig `mapstructure:"openapi-values-quote"`
SchemaValidationRule RuleConfig `mapstructure:"schema-validation"`
DeprecatedHTTPRouteAnnotationsRule RuleConfig `mapstructure:"deprecated-httproute-annotations"`
IngressEnablementRule RuleConfig `mapstructure:"ingress-enablement"`
GatewayEnablementRule RuleConfig `mapstructure:"gateway-enablement"`
HTTPSCertificateReuseRule RuleConfig `mapstructure:"https-certificate-reuse"`
}

type TemplatesExcludeRules struct {
VPAAbsent KindRuleExcludeList `mapstructure:"vpa"`
PDBAbsent KindRuleExcludeList `mapstructure:"pdb"`
ServicePort ServicePortExcludeList `mapstructure:"service-port"`
KubeRBACProxy StringRuleExcludeList `mapstructure:"kube-rbac-proxy"`
Ingress KindRuleExcludeList `mapstructure:"ingress"`
HTTPRoute KindRuleExcludeList `mapstructure:"httproute"`
EnabledModules EnabledModulesExcludeRule `mapstructure:"enabled-modules"`
WebhookConfiguration KindRuleExcludeList `mapstructure:"webhook-configuration-annotations"`
MountPoints StringRuleExcludeList `mapstructure:"mount-points"`
OpenAPIValuesQuote StringRuleExcludeList `mapstructure:"openapi-values-quote"`
SchemaValidation KindRuleExcludeList `mapstructure:"schema-validation"`
VPAAbsent KindRuleExcludeList `mapstructure:"vpa"`
PDBAbsent KindRuleExcludeList `mapstructure:"pdb"`
ServicePort ServicePortExcludeList `mapstructure:"service-port"`
KubeRBACProxy StringRuleExcludeList `mapstructure:"kube-rbac-proxy"`
Ingress KindRuleExcludeList `mapstructure:"ingress"`
HTTPRoute KindRuleExcludeList `mapstructure:"httproute"`
EnabledModules EnabledModulesExcludeRule `mapstructure:"enabled-modules"`
WebhookConfiguration KindRuleExcludeList `mapstructure:"webhook-configuration-annotations"`
MountPoints StringRuleExcludeList `mapstructure:"mount-points"`
OpenAPIValuesQuote StringRuleExcludeList `mapstructure:"openapi-values-quote"`
SchemaValidation KindRuleExcludeList `mapstructure:"schema-validation"`
DeprecatedHTTPRouteAnnotations PathRuleExclude `mapstructure:"deprecated-httproute-annotations"`
IngressEnablement PathRuleExclude `mapstructure:"ingress-enablement"`
GatewayEnablement PathRuleExclude `mapstructure:"gateway-enablement"`
HTTPSCertificateReuse PathRuleExclude `mapstructure:"https-certificate-reuse"`
}

type EnabledModulesExcludeRule struct {
Files StringRuleExcludeList `mapstructure:"files"`
Directories DirectoryRuleExcludeList `mapstructure:"directories"`
}

// PathRuleExclude excludes specific files and whole directories (both relative
// to the module root) from a rule that scans template source files.
type PathRuleExclude struct {
Files StringRuleExcludeList `mapstructure:"files"`
Directories DirectoryRuleExcludeList `mapstructure:"directories"`
}

type GrafanaDashboardsExcludeList struct {
Disable bool `mapstructure:"disable"`
}
Expand Down
Loading
Loading