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
1 change: 1 addition & 0 deletions internal/module/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,7 @@ func mapContainerExclusions(linterSettings *pkg.LintersSettings, configSettings
configExcludes := &configSettings.Container.ExcludeRules

excludes.ControllerSecurityContext = configExcludes.ControllerSecurityContext.Get()
excludes.NamespaceLabelsRule = configExcludes.NamespaceLabelsRule.Get()
excludes.DNSPolicy = configExcludes.DNSPolicy.Get()
excludes.PriorityClass = configExcludes.PriorityClass.Get()
excludes.HostNetworkPorts = configExcludes.HostNetworkPorts.Get()
Expand Down
1 change: 1 addition & 0 deletions pkg/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,7 @@ type ContainerLinterRules struct {

type ContainerExcludeRules struct {
ControllerSecurityContext KindRuleExcludeList
NamespaceLabelsRule KindRuleExcludeList
DNSPolicy KindRuleExcludeList
PriorityClass KindRuleExcludeList

Expand Down
2 changes: 1 addition & 1 deletion pkg/config/global/global.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ type ContainerLinterConfig struct {

type ContainerRules struct {
RecommendedLabelsRule RuleConfig `mapstructure:"recommended-labels"`
NamespaceLabelsRule RuleConfig `mapstructure:"namespace-labels"`
NamespaceLabelsRule RuleConfig `mapstructure:"object-namespace-labels"`
APIVersionRule RuleConfig `mapstructure:"api-version"`
PriorityClassRule RuleConfig `mapstructure:"priority-class"`
DNSPolicyRule RuleConfig `mapstructure:"dns-policy"`
Expand Down
1 change: 1 addition & 0 deletions pkg/config/linters_settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ type ContainerSettings struct {

type ContainerExcludeRules struct {
ControllerSecurityContext KindRuleExcludeList `mapstructure:"controller-security-context"`
NamespaceLabelsRule KindRuleExcludeList `mapstructure:"object-namespace-labels"`
DNSPolicy KindRuleExcludeList `mapstructure:"dns-policy"`
PriorityClass KindRuleExcludeList `mapstructure:"priority-class"`

Expand Down
54 changes: 36 additions & 18 deletions pkg/linters/container/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Proper container configuration is critical for cluster stability, security, and
| Rule | Description | Configurable | Default |
|------|-------------|--------------|---------|
| [object-recommended-labels](#object-recommended-labels) | Validates required labels (module, heritage) | ❌ | enabled |
| [object-namespace-labels](#object-namespace-labels) | Validates Prometheus watcher label on d8-* namespaces | | enabled |
| [object-namespace-labels](#object-namespace-labels) | Validates Prometheus watcher label on d8-* namespaces | | enabled |
| [object-api-version](#object-api-version) | Validates API versions are not deprecated | ❌ | enabled |
| [object-priority-class](#object-priority-class) | Validates PriorityClass is set and allowed | ❌ | enabled |
| [dns-policy](#dns-policy) | Validates DNS policy for hostNetwork pods | ✅ | enabled |
Expand All @@ -44,6 +44,8 @@ Proper container configuration is critical for cluster stability, security, and
| [no-new-privileges](#no-new-privileges) | Validates containers don't allow privilege escalation | ✅ | enabled |
| [seccomp-profile](#seccomp-profile) | Validates seccomp profile configuration | ✅ | enabled |

"Configurable" means that this rule can be configured using the `.dmt.yaml` file, including customizing the rule's parameters and/or disabling the rule.

## Rule Details

### object-recommended-labels
Expand Down Expand Up @@ -174,6 +176,22 @@ metadata:
heritage: deckhouse
```

**Configuration:**

Exclude specific `d8-*` namespaces from this check when the Prometheus watcher label is intentionally omitted:

```yaml
# .dmt.yaml
linters-settings:
container:
exclude-rules:
object-namespace-labels:
- kind: Namespace
name: d8-my-module
```

Each entry matches by Kubernetes object `kind` and `name`. When a namespace is excluded, the rule is not applied even if `PrometheusRule` resources exist in that namespace.

---

### object-api-version
Expand Down Expand Up @@ -344,7 +362,7 @@ spec:
**Error:**
```
dnsPolicy must be `ClusterFirstWithHostNet` when hostNetwork is `true`
```
``.dmtlint.yaml

✅ **Correct** - Proper DNS policy:

Expand Down Expand Up @@ -443,7 +461,7 @@ spec:
image: my-image
```

**Correct** - Non-root with deckhouse user:
.dmtlint.yaml** - Non-root with deckhouse user:

```yaml
spec:
Expand Down Expand Up @@ -654,7 +672,7 @@ Container's SecurityContext has `ReadOnlyRootFilesystem: false`, but it must be
```

✅ **Correct** - Read-only filesystem:

.dmtlint.yaml
```yaml
containers:
- name: app
Expand Down Expand Up @@ -724,7 +742,7 @@ spec:
```
Pod running in hostNetwork and it's container port doesn't fit the range [4200,4299]
```

.dmtlint.yaml
✅ **Correct** - Port in allowed range:

```yaml
Expand Down Expand Up @@ -831,7 +849,7 @@ Using external registries bypasses Deckhouse's image verification, mirroring, an
containers:
- name: app
image: docker.io/library/nginx:latest
```
``.dmtlint.yaml

**Error:**
```
Expand Down Expand Up @@ -954,7 +972,7 @@ Ephemeral storage for container is not defined in Resources.Requests

✅ **Correct** - Ephemeral storage defined:

```yaml
``.dmtlint.yaml
containers:
- name: app
image: my-image
Expand Down Expand Up @@ -1015,7 +1033,7 @@ containers:
```
Container ContainerSecurityContext is not defined
```

.dmtlint.yaml
✅ **Correct** - Security context defined:

```yaml
Expand Down Expand Up @@ -1076,7 +1094,7 @@ containers:
```

**Error:**
```
``.dmtlint.yaml
Container uses port <= 1024
```

Expand Down Expand Up @@ -1182,7 +1200,7 @@ containers:
periodSeconds: 20
```

**Correct** - Exec liveness probe:
.dmtlint.yaml** - Exec liveness probe:

```yaml
containers:
Expand Down Expand Up @@ -1285,7 +1303,7 @@ containers:
tcpSocket:
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
.dmtlint.yamldSeconds: 10
```

✅ **Correct** - GRPC readiness probe:
Expand Down Expand Up @@ -1342,7 +1360,7 @@ containers:
allowPrivilegeEscalation: true # ❌ Allows privilege escalation
```

**Error:**
**.dmtlint.yaml
```
Container allows privilege escalation (allowPrivilegeEscalation is true)
```
Expand Down Expand Up @@ -1417,7 +1435,7 @@ containers:
```

**Error:**
```
``.dmtlint.yaml
Container has seccompProfile.type set to 'Unconfined' which disables seccomp filtering and poses security risks - use 'RuntimeDefault' instead
```

Expand All @@ -1436,7 +1454,7 @@ containers:

```yaml
# .dmt.yaml
linters-settings:
li.dmtlint.yamltings:
container:
exclude-rules:
Comment on lines 1455 to 1459
seccomp-profile:
Expand All @@ -1453,7 +1471,7 @@ The Container linter can be configured at both the module level and for individu

Configure the overall impact level for the container linter:

```yaml
``.dmtlint.yaml
# .dmt.yaml
linters-settings:
Comment on lines +1474 to 1476
container:
Expand Down Expand Up @@ -1511,7 +1529,7 @@ linters-settings:
container: reserve-resources

image-digest:
- kind: Deployment
.dmtlint.yamlind: Deployment
name: okmeter
container: okagent

Expand Down Expand Up @@ -1568,10 +1586,10 @@ linters-settings:

liveness-probe:
- kind: Deployment
name: standby-holder-name
name: standb.dmtlint.yamlname
container: reserve-resources

readiness-probe:
readiness-prob.dmtlint.yaml
- kind: Deployment
name: standby-holder-name
container: reserve-resources
Expand Down
3 changes: 2 additions & 1 deletion pkg/linters/container/rules.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ func (l *Container) applyContainerRules(object storage.StoreObject, storageMap m
errorList = errorList.WithFilePath(object.GetPath())

rules.NewRecommendedLabelsRule().ObjectRecommendedLabels(object, errorList.WithMaxLevel(l.cfg.Rules.RecommendedLabelsRule.GetLevel()))
rules.NewNamespaceLabelsRule().ObjectNamespaceLabels(object, storageMap, errorList.WithMaxLevel(l.cfg.Rules.NamespaceLabelsRule.GetLevel()))
rules.NewNamespaceLabelsRule(l.cfg.ExcludeRules.NamespaceLabelsRule.Get()).
ObjectNamespaceLabels(object, storageMap, errorList.WithMaxLevel(l.cfg.Rules.NamespaceLabelsRule.GetLevel()))
rules.NewAPIVersionRule().ObjectAPIVersion(object, errorList.WithMaxLevel(l.cfg.Rules.APIVersionRule.GetLevel()))
rules.NewPriorityClassRule(l.cfg.ExcludeRules.PriorityClass.Get()).ObjectPriorityClass(object, errorList.WithMaxLevel(l.cfg.Rules.PriorityClassRule.GetLevel()))
rules.NewDNSPolicyRule(l.cfg.ExcludeRules.DNSPolicy.Get()).
Expand Down
11 changes: 10 additions & 1 deletion pkg/linters/container/rules/namespace_labels.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,20 @@ const (
NamespaceLabelsRuleName = "object-namespace-labels"
)

func NewNamespaceLabelsRule() *NamespaceLabelsRule {
func NewNamespaceLabelsRule(excludeRules []pkg.KindRuleExclude) *NamespaceLabelsRule {
return &NamespaceLabelsRule{
RuleMeta: pkg.RuleMeta{
Name: NamespaceLabelsRuleName,
},
KindRule: pkg.KindRule{
ExcludeRules: excludeRules,
},
}
}

type NamespaceLabelsRule struct {
pkg.RuleMeta
pkg.KindRule
}

func (r *NamespaceLabelsRule) ObjectNamespaceLabels(object storage.StoreObject, storageMap map[storage.ResourceIndex]storage.StoreObject, errorList *errors.LintRuleErrorsList) {
Expand All @@ -49,6 +53,11 @@ func (r *NamespaceLabelsRule) ObjectNamespaceLabels(object storage.StoreObject,

namespaceName := object.Unstructured.GetName()

if !r.Enabled(object.Unstructured.GetKind(), namespaceName) {
// TODO: add metrics
return
}

hasPrometheusRules := false

for _, obj := range storageMap {
Expand Down
16 changes: 9 additions & 7 deletions pkg/linters/docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ Proper documentation is critical for Deckhouse modules as it helps users underst
| [cyrillic-in-english](#cyrillic-in-english) | Validates English documentation doesn't contain cyrillic characters | ✅ | enabled |
| [no-lang-key](#no-lang-key) | Validates documentation front matter doesn't contain `lang` key | ✅ | enabled |

"Configurable" means that this rule can be configured using the `.dmt.yaml` file, including customizing the rule's parameters and/or disabling the rule.

## Rule Details

### readme
Expand Down Expand Up @@ -91,7 +93,7 @@ This module provides...
**Configuration:**

To disable this rule for specific modules:

.dmtlint.yaml
```yaml
# .dmt.yaml
linters-settings:
Expand Down Expand Up @@ -172,7 +174,7 @@ my-module/
**Configuration:**

To disable bilingual checks for specific files:

.dmtlint.yaml
```yaml
# .dmt.yaml
linters-settings:
Expand Down Expand Up @@ -287,7 +289,7 @@ Line 42: Check the документация for more details.
**Configuration:**

To exclude specific files from this check:

.dmtlint.yaml
```yaml
# .dmt.yaml
linters-settings:
Expand Down Expand Up @@ -377,7 +379,7 @@ webIfaces:
**Configuration:**

To exclude specific files from this check:

.dmtlint.yaml
```yaml
# .dmt.yaml
linters-settings:
Expand All @@ -397,7 +399,7 @@ The Documentation linter can be configured at both the module level and for indi
### Module-Level Settings

Configure the overall impact level for the documentation linter:

.dmtlint.yaml
```yaml
# .dmt.yaml
linters-settings:
Expand All @@ -414,7 +416,7 @@ linters-settings:
### Path-Based Exclusions

Exclude specific modules or files from validation:

.dmtlint.yaml
```yaml
# .dmt.yaml
linters-settings:
Expand Down Expand Up @@ -499,7 +501,7 @@ File: docs/CONFIGURATION.md
```

3. **Exclude if translation is not needed (not recommended):**

.dmtlint.yaml
```yaml
# .dmt.yaml
linters-settings:
Expand Down
Loading
Loading