Skip to content

Commit 1780a51

Browse files
committed
Remove all punctuation from anchors in policies.md
1 parent 3f954e3 commit 1780a51

File tree

5 files changed

+132
-18
lines changed

5 files changed

+132
-18
lines changed

examples/policies-no-rego.md

+27-7
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* [P1005: Pods must not run with access to the host IPC](#p1005-pods-must-not-run-with-access-to-the-host-ipc)
1111
* [P1006: Pods must not run with access to the host networking](#p1006-pods-must-not-run-with-access-to-the-host-networking)
1212
* [P1007: Pods must not run with access to the host PID namespace](#p1007-pods-must-not-run-with-access-to-the-host-pid-namespace)
13-
* [P1008: Pods must run as non-root](#p1008-pods-must-run-as-non-root)
13+
* [P1008: Pods must run as non\-root](#p1008-pods-must-run-as-non-root)
1414
* [P1009: PodSecurityPolicies must require all capabilities are dropped](#p1009-podsecuritypolicies-must-require-all-capabilities-are-dropped)
1515
* [P1010: PodSecurityPolicies must not allow privileged escalation](#p1010-podsecuritypolicies-must-not-allow-privileged-escalation)
1616
* [P1011: PodSecurityPolicies must not allow access to the host aliases](#p1011-podsecuritypolicies-must-not-allow-access-to-the-host-aliases)
@@ -21,13 +21,14 @@
2121
* [P2001: Images must not use the latest tag](#p2001-images-must-not-use-the-latest-tag)
2222
* [P2002: Containers must define resource constraints](#p2002-containers-must-define-resource-constraints)
2323
* [P2005: Roles must not allow use of privileged PodSecurityPolicies](#p2005-roles-must-not-allow-use-of-privileged-podsecuritypolicies)
24-
* [P2006: Tenants' containers must not run as privileged](#p2006-tenants'-containers-must-not-run-as-privileged)
24+
* [P2006: Tenants' containers must not run as privileged](#p2006-tenants-containers-must-not-run-as-privileged)
2525

2626
## Warnings
2727

2828
* [P0001: Deprecated Deployment and DaemonSet API](#p0001-deprecated-deployment-and-daemonset-api)
29+
* [P0003: Title with\-punctuation\_ \!"\#$%&'\(\)\*\+,\./:;\<=\>?@\[\\\]^\`\{\|\}~marks](#p0003-title-with-punctuation_marks)
2930
* [P2003: Containers should not have a writable root filesystem](#p2003-containers-should-not-have-a-writable-root-filesystem)
30-
* [P2004: PodSecurityPolicies should require that a read-only root filesystem is set](#p2004-podsecuritypolicies-should-require-that-a-read-only-root-filesystem-is-set)
31+
* [P2004: PodSecurityPolicies should require that a read\-only root filesystem is set](#p2004-podsecuritypolicies-should-require-that-a-read-only-root-filesystem-is-set)
3132

3233
## P0002: Required Labels
3334

@@ -168,7 +169,7 @@ boundary.
168169

169170
_source: [pod-deny-host-pid](pod-deny-host-pid)_
170171

171-
## P1008: Pods must run as non-root
172+
## P1008: Pods must run as non\-root
172173

173174
**Severity:** Violation
174175

@@ -341,7 +342,7 @@ _source: [container-deny-without-resource-constraints](container-deny-without-re
341342

342343
**Resources:**
343344

344-
- rbac.authorization.k8s.io/Role
345+
- rbac\.authorization\.k8s\.io/Role
345346

346347
Workloads not running in the exempted namespaces must not use PodSecurityPolicies with privileged permissions.
347348

@@ -359,7 +360,7 @@ _source: [role-deny-use-privileged-psp](role-deny-use-privileged-psp)_
359360
- apps/Deployment
360361
- apps/StatefulSet
361362

362-
**MatchLabels:** is-tenant=true
363+
**MatchLabels:** is\-tenant=true
363364

364365
Privileged containers can easily escalate to root privileges on the node. As
365366
such containers running as privileged or with sufficient capabilities granted
@@ -386,6 +387,25 @@ the version for both of these resources must be `apps/v1`.
386387

387388
_source: [any-warn-deprecated-api-versions](any-warn-deprecated-api-versions)_
388389

390+
## P0003: Title with\-punctuation\_ \!"\#$%&'\(\)\*\+,\./:;\<=\>?@\[\\\]^\`\{\|\}~marks
391+
392+
**Severity:** Warning
393+
394+
**Resources:**
395+
396+
- \*/Pod
397+
398+
**MatchLabels:** \_test\_=true
399+
400+
**Parameters:**
401+
402+
* \_param\_name\_: array of string
403+
404+
This is only here to test _punctuation_ handling
405+
406+
407+
_source: [policy-markdown-punctuation](policy-markdown-punctuation)_
408+
389409
## P2003: Containers should not have a writable root filesystem
390410

391411
**Severity:** Warning
@@ -403,7 +423,7 @@ important to make the root filesystem read-only.
403423

404424
_source: [container-warn-no-ro-fs](container-warn-no-ro-fs)_
405425

406-
## P2004: PodSecurityPolicies should require that a read-only root filesystem is set
426+
## P2004: PodSecurityPolicies should require that a read\-only root filesystem is set
407427

408428
**Severity:** Warning
409429

examples/policies.md

+41-7
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* [P1005: Pods must not run with access to the host IPC](#p1005-pods-must-not-run-with-access-to-the-host-ipc)
1111
* [P1006: Pods must not run with access to the host networking](#p1006-pods-must-not-run-with-access-to-the-host-networking)
1212
* [P1007: Pods must not run with access to the host PID namespace](#p1007-pods-must-not-run-with-access-to-the-host-pid-namespace)
13-
* [P1008: Pods must run as non-root](#p1008-pods-must-run-as-non-root)
13+
* [P1008: Pods must run as non\-root](#p1008-pods-must-run-as-non-root)
1414
* [P1009: PodSecurityPolicies must require all capabilities are dropped](#p1009-podsecuritypolicies-must-require-all-capabilities-are-dropped)
1515
* [P1010: PodSecurityPolicies must not allow privileged escalation](#p1010-podsecuritypolicies-must-not-allow-privileged-escalation)
1616
* [P1011: PodSecurityPolicies must not allow access to the host aliases](#p1011-podsecuritypolicies-must-not-allow-access-to-the-host-aliases)
@@ -21,13 +21,14 @@
2121
* [P2001: Images must not use the latest tag](#p2001-images-must-not-use-the-latest-tag)
2222
* [P2002: Containers must define resource constraints](#p2002-containers-must-define-resource-constraints)
2323
* [P2005: Roles must not allow use of privileged PodSecurityPolicies](#p2005-roles-must-not-allow-use-of-privileged-podsecuritypolicies)
24-
* [P2006: Tenants' containers must not run as privileged](#p2006-tenants'-containers-must-not-run-as-privileged)
24+
* [P2006: Tenants' containers must not run as privileged](#p2006-tenants-containers-must-not-run-as-privileged)
2525

2626
## Warnings
2727

2828
* [P0001: Deprecated Deployment and DaemonSet API](#p0001-deprecated-deployment-and-daemonset-api)
29+
* [P0003: Title with\-punctuation\_ \!"\#$%&'\(\)\*\+,\./:;\<=\>?@\[\\\]^\`\{\|\}~marks](#p0003-title-with-punctuation_marks)
2930
* [P2003: Containers should not have a writable root filesystem](#p2003-containers-should-not-have-a-writable-root-filesystem)
30-
* [P2004: PodSecurityPolicies should require that a read-only root filesystem is set](#p2004-podsecuritypolicies-should-require-that-a-read-only-root-filesystem-is-set)
31+
* [P2004: PodSecurityPolicies should require that a read\-only root filesystem is set](#p2004-podsecuritypolicies-should-require-that-a-read-only-root-filesystem-is-set)
3132

3233
## P0002: Required Labels
3334

@@ -364,7 +365,7 @@ pod_has_hostpid {
364365

365366
_source: [pod-deny-host-pid](pod-deny-host-pid)_
366367

367-
## P1008: Pods must run as non-root
368+
## P1008: Pods must run as non\-root
368369

369370
**Severity:** Violation
370371

@@ -773,7 +774,7 @@ _source: [container-deny-without-resource-constraints](container-deny-without-re
773774

774775
**Resources:**
775776

776-
- rbac.authorization.k8s.io/Role
777+
- rbac\.authorization\.k8s\.io/Role
777778

778779
Workloads not running in the exempted namespaces must not use PodSecurityPolicies with privileged permissions.
779780

@@ -831,7 +832,7 @@ _source: [role-deny-use-privileged-psp](role-deny-use-privileged-psp)_
831832
- apps/Deployment
832833
- apps/StatefulSet
833834

834-
**MatchLabels:** is-tenant=true
835+
**MatchLabels:** is\-tenant=true
835836

836837
Privileged containers can easily escalate to root privileges on the node. As
837838
such containers running as privileged or with sufficient capabilities granted
@@ -908,6 +909,39 @@ warn[msg] {
908909

909910
_source: [any-warn-deprecated-api-versions](any-warn-deprecated-api-versions)_
910911

912+
## P0003: Title with\-punctuation\_ \!"\#$%&'\(\)\*\+,\./:;\<=\>?@\[\\\]^\`\{\|\}~marks
913+
914+
**Severity:** Warning
915+
916+
**Resources:**
917+
918+
- \*/Pod
919+
920+
**MatchLabels:** \_test\_=true
921+
922+
**Parameters:**
923+
924+
* \_param\_name\_: array of string
925+
926+
This is only here to test _punctuation_ handling
927+
928+
### Rego
929+
930+
```rego
931+
package policy_markdown_punctuation
932+
933+
import data.lib.core
934+
935+
policyID := "P0003"
936+
937+
warn[msg] {
938+
core.apiVersion == "foo/bar"
939+
msg := core.format_with_id("Title tester", policyID)
940+
}
941+
```
942+
943+
_source: [policy-markdown-punctuation](policy-markdown-punctuation)_
944+
911945
## P2003: Containers should not have a writable root filesystem
912946

913947
**Severity:** Warning
@@ -955,7 +989,7 @@ no_read_only_filesystem(container) {
955989

956990
_source: [container-warn-no-ro-fs](container-warn-no-ro-fs)_
957991

958-
## P2004: PodSecurityPolicies should require that a read-only root filesystem is set
992+
## P2004: PodSecurityPolicies should require that a read\-only root filesystem is set
959993

960994
**Severity:** Warning
961995

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# METADATA
2+
# title: " Title with-punctuation_ !\"#$%&'()*+,./:;<=>?@[\\]^`{|}~marks "
3+
# description: This is only here to test _punctuation_ handling
4+
# custom:
5+
# matchers:
6+
# kinds:
7+
# - apiGroups:
8+
# - "*"
9+
# kinds:
10+
# - Pod
11+
# labelSelector:
12+
# matchLabels:
13+
# _test_: "true"
14+
# parameters:
15+
# _param_name_:
16+
# type: array
17+
# items:
18+
# type: string
19+
package policy_markdown_punctuation
20+
21+
import data.lib.core
22+
23+
policyID := "P0003"
24+
25+
warn[msg] {
26+
core.apiVersion == "foo/bar"
27+
msg := core.format_with_id("Title tester", policyID)
28+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package policy_markdown_punctuation
2+
3+
test_ignoreme {
4+
count(warn) == 1 with input as {"apiVersion": "foo/bar"}
5+
}

internal/commands/document.go

+31-4
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,24 @@ type Document struct {
3838
//go:embed document_template.tpl
3939
var docTemplate string
4040

41+
var (
42+
// Escape the characters on this list: https://www.markdownguide.org/basic-syntax/#characters-you-can-escape
43+
// (Admittedly, a few of these seem... odd.)
44+
markdownReplacer = strings.NewReplacer(
45+
"\\", "\\\\", "`", "\\`", "*", "\\*", "_", "\\_", "{", "\\{", "}", "\\}", "[", "\\[", "]", "\\]", "<", "\\<",
46+
">", "\\>", "(", "\\(", ")", "\\)", "#", "\\#", "+", "\\+", "-", "\\-", ".", "\\.", "!", "\\!", "|", "\\|",
47+
)
48+
49+
// Space -> -, remove tab and all ASCII punctuation except - and _
50+
anchorReplacer = strings.NewReplacer(
51+
" ", "-",
52+
"\t", "", "!", "", "\"", "", "#", "", "$", "", "%", "", "&", "", "'", "", "(", "", ")", "",
53+
"*", "", "+", "", ",", "", ".", "", "/", "", ":", "", ";", "", "<", "", "=", "", ">", "",
54+
"?", "", "@", "", "[", "", "\\", "", "]", "", "^", "", "`", "", "{", "", "|", "", "}", "",
55+
"~", "",
56+
)
57+
)
58+
4159
func newDocCommand() *cobra.Command {
4260
cmd := cobra.Command{
4361
Use: "doc <dir>",
@@ -180,13 +198,15 @@ func getDocumentation(path string, outputDirectory string) (map[rego.Severity][]
180198
url = strings.ReplaceAll(relDir, string(os.PathSeparator), "/")
181199
}
182200

183-
documentTitle := policy.Title()
201+
// Trailing whitespace breaks at least some Markdown parsers, it seems. When generating the anchor, the space
202+
// becomes - but then the anchor doesn't work, even though the trailing space is present in the heading line.
203+
rawDocumentTitle := strings.TrimSpace(policy.Title())
184204
if policy.PolicyID() != "" {
185-
documentTitle = fmt.Sprintf("%s: %s", policy.PolicyID(), documentTitle)
205+
rawDocumentTitle = fmt.Sprintf("%s: %s", policy.PolicyID(), rawDocumentTitle)
186206
}
207+
documentTitle := markdownReplacer.Replace(rawDocumentTitle)
187208

188-
anchor := strings.ToLower(strings.ReplaceAll(documentTitle, " ", "-"))
189-
anchor = strings.ReplaceAll(anchor, ":", "")
209+
anchor := anchorReplacer.Replace(strings.ToLower(rawDocumentTitle))
190210

191211
legacyMatchers, err := policy.Matchers()
192212
if err != nil {
@@ -208,13 +228,17 @@ func getDocumentation(path string, outputDirectory string) (map[rego.Severity][]
208228
logger.Warn("No kind matchers set, this can lead to poor policy performance.")
209229
matchResources = append(matchResources, "Any Resource")
210230
}
231+
for i := range matchResources {
232+
matchResources[i] = markdownReplacer.Replace(matchResources[i])
233+
}
211234

212235
var matchLabels string
213236
if policy.AnnotationLabelSelectorMatcher() != nil {
214237
matchLabels = labelSelectorDocString(policy.AnnotationLabelSelectorMatcher())
215238
} else {
216239
matchLabels = legacyMatchers.MatchLabelsMatcher.String()
217240
}
241+
matchLabels = markdownReplacer.Replace(matchLabels)
218242

219243
parameters := policy.Parameters()
220244
if len(policy.AnnotationParameters()) > 0 {
@@ -223,6 +247,9 @@ func getDocumentation(path string, outputDirectory string) (map[rego.Severity][]
223247
sort.Slice(parameters, func(i, j int) bool {
224248
return parameters[i].Name < parameters[j].Name
225249
})
250+
for i := range parameters {
251+
parameters[i].Name = markdownReplacer.Replace(parameters[i].Name)
252+
}
226253

227254
header := Header{
228255
Title: documentTitle,

0 commit comments

Comments
 (0)