Skip to content

Commit 7e15319

Browse files
committed
refactor to simplify annotation requirement callers
1 parent d5647d5 commit 7e15319

File tree

3 files changed

+145
-138
lines changed

3 files changed

+145
-138
lines changed
Lines changed: 10 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,14 @@
11
package autoregenerate_after_expiry
22

3-
import (
4-
"fmt"
5-
6-
"github.com/openshift/origin/pkg/cmd/update-tls-artifacts/generate-owners/tlsmetadatainterfaces"
7-
8-
"github.com/openshift/library-go/pkg/certs/cert-inspection/certgraphapi"
9-
"k8s.io/apimachinery/pkg/util/sets"
10-
)
3+
import "github.com/openshift/origin/pkg/cmd/update-tls-artifacts/generate-owners/tlsmetadatainterfaces"
114

125
const annotationName string = "certificates.openshift.io/auto-regenerate-after-offline-expiry"
136

147
type AutoRegenerateAfterOfflineExpiryRequirement struct{}
158

169
func NewAutoRegenerateAfterOfflineExpiryRequirement() tlsmetadatainterfaces.Requirement {
17-
return tlsmetadatainterfaces.NewAnnotationRequirement(
18-
// requirement name
19-
"autoregenerate-after-expiry",
20-
// cert or configmap annotation
21-
annotationName,
22-
// function which generates markdown report
23-
generateAutoRegenerateAfterOfflineExpiryMarkdownFn,
24-
)
25-
}
26-
27-
func generateAutoRegenerateAfterOfflineExpiryMarkdownFn(pkiInfo *certgraphapi.PKIRegistryInfo) ([]byte, error) {
28-
compliantCertsByOwner := map[string][]certgraphapi.PKIRegistryInClusterCertKeyPair{}
29-
violatingCertsByOwner := map[string][]certgraphapi.PKIRegistryInClusterCertKeyPair{}
30-
compliantCABundlesByOwner := map[string][]certgraphapi.PKIRegistryInClusterCABundle{}
31-
violatingCABundlesByOwner := map[string][]certgraphapi.PKIRegistryInClusterCABundle{}
32-
33-
for i := range pkiInfo.CertKeyPairs {
34-
curr := pkiInfo.CertKeyPairs[i]
35-
owner := curr.CertKeyInfo.OwningJiraComponent
36-
regenerates, _ := tlsmetadatainterfaces.AnnotationValue(curr.CertKeyInfo.SelectedCertMetadataAnnotations, annotationName)
37-
if len(regenerates) == 0 {
38-
violatingCertsByOwner[owner] = append(violatingCertsByOwner[owner], curr)
39-
continue
40-
}
4110

42-
compliantCertsByOwner[owner] = append(compliantCertsByOwner[owner], curr)
43-
}
44-
for i := range pkiInfo.CertificateAuthorityBundles {
45-
curr := pkiInfo.CertificateAuthorityBundles[i]
46-
owner := curr.CABundleInfo.OwningJiraComponent
47-
regenerates, _ := tlsmetadatainterfaces.AnnotationValue(curr.CABundleInfo.SelectedCertMetadataAnnotations, annotationName)
48-
if len(regenerates) == 0 {
49-
violatingCABundlesByOwner[owner] = append(violatingCABundlesByOwner[owner], curr)
50-
continue
51-
}
52-
compliantCABundlesByOwner[owner] = append(compliantCABundlesByOwner[owner], curr)
53-
}
54-
55-
md := tlsmetadatainterfaces.NewMarkdown("Auto Regenerate After Offline Expiry")
11+
md := tlsmetadatainterfaces.NewMarkdown("")
5612
md.Text("Acknowledging that a cert/key pair or CA bundle can auto-regenerate after it expires offline means")
5713
md.Text("that if the cluster is shut down until the certificate expires, when the machines are restarted")
5814
md.Text("the cluster will automatically create new cert/key pairs or update CA bundles as required without human")
@@ -70,89 +26,12 @@ func generateAutoRegenerateAfterOfflineExpiryMarkdownFn(pkiInfo *certgraphapi.PK
7026
md.OrderedListEnd()
7127
md.Text("Links should be provided in the PR adding the annotation.")
7228

73-
if len(violatingCertsByOwner) > 0 || len(violatingCABundlesByOwner) > 0 {
74-
numViolators := 0
75-
for _, v := range violatingCertsByOwner {
76-
numViolators += len(v)
77-
}
78-
for _, v := range violatingCABundlesByOwner {
79-
numViolators += len(v)
80-
}
81-
md.Title(2, fmt.Sprintf("Items That Cannot Auto Regenerate After Offline Expiry (%d)", numViolators))
82-
violatingOwners := sets.StringKeySet(violatingCertsByOwner)
83-
violatingOwners.Insert(sets.StringKeySet(violatingCABundlesByOwner).UnsortedList()...)
84-
for _, owner := range violatingOwners.List() {
85-
md.Title(3, fmt.Sprintf("%s (%d)", owner, len(violatingCertsByOwner[owner])+len(violatingCABundlesByOwner[owner])))
86-
certs := violatingCertsByOwner[owner]
87-
if len(certs) > 0 {
88-
md.Title(4, fmt.Sprintf("Certificates (%d)", len(certs)))
89-
md.OrderedListStart()
90-
for _, curr := range certs {
91-
md.NewOrderedListItem()
92-
md.Textf("ns/%v secret/%v\n", curr.SecretLocation.Namespace, curr.SecretLocation.Name)
93-
md.Textf("**Description:** %v", curr.CertKeyInfo.Description)
94-
md.Text("\n")
95-
}
96-
md.OrderedListEnd()
97-
md.Text("\n")
98-
}
99-
100-
caBundles := violatingCABundlesByOwner[owner]
101-
if len(caBundles) > 0 {
102-
md.Title(4, fmt.Sprintf("Certificate Authority Bundles (%d)", len(caBundles)))
103-
md.OrderedListStart()
104-
for _, curr := range caBundles {
105-
md.NewOrderedListItem()
106-
md.Textf("ns/%v configmap/%v\n", curr.ConfigMapLocation.Namespace, curr.ConfigMapLocation.Name)
107-
md.Textf("**Description:** %v", curr.CABundleInfo.Description)
108-
md.Text("\n")
109-
}
110-
md.OrderedListEnd()
111-
md.Text("\n")
112-
}
113-
}
114-
}
115-
116-
numCompliant := 0
117-
for _, v := range compliantCertsByOwner {
118-
numCompliant += len(v)
119-
}
120-
for _, v := range compliantCABundlesByOwner {
121-
numCompliant += len(v)
122-
}
123-
md.Title(2, fmt.Sprintf("Items That Can Auto Regenerate After Offline Expiry (%d)", numCompliant))
124-
allAutoRegenerateAfterOfflineExpirys := sets.StringKeySet(compliantCertsByOwner)
125-
allAutoRegenerateAfterOfflineExpirys.Insert(sets.StringKeySet(compliantCABundlesByOwner).UnsortedList()...)
126-
for _, owner := range allAutoRegenerateAfterOfflineExpirys.List() {
127-
md.Title(3, fmt.Sprintf("%s (%d)", owner, len(compliantCertsByOwner[owner])+len(compliantCABundlesByOwner[owner])))
128-
certs := compliantCertsByOwner[owner]
129-
if len(certs) > 0 {
130-
md.Title(4, fmt.Sprintf("Certificates (%d)", len(certs)))
131-
md.OrderedListStart()
132-
for _, curr := range certs {
133-
md.NewOrderedListItem()
134-
md.Textf("ns/%v secret/%v\n", curr.SecretLocation.Namespace, curr.SecretLocation.Name)
135-
md.Textf("**Description:** %v", curr.CertKeyInfo.Description)
136-
md.Text("\n")
137-
}
138-
md.OrderedListEnd()
139-
md.Text("\n")
140-
}
141-
142-
caBundles := compliantCABundlesByOwner[owner]
143-
if len(caBundles) > 0 {
144-
md.Title(4, fmt.Sprintf("Certificate Authority Bundles (%d)", len(caBundles)))
145-
md.OrderedListStart()
146-
for _, curr := range caBundles {
147-
md.NewOrderedListItem()
148-
md.Textf("ns/%v configmap/%v\n", curr.ConfigMapLocation.Namespace, curr.ConfigMapLocation.Name)
149-
md.Textf("**Description:** %v", curr.CABundleInfo.Description)
150-
md.Text("\n")
151-
}
152-
md.OrderedListEnd()
153-
md.Text("\n")
154-
}
155-
}
156-
157-
return md.Bytes(), nil
29+
return tlsmetadatainterfaces.NewAnnotationRequirement(
30+
// requirement name
31+
"autoregenerate-after-expiry",
32+
// cert or configmap annotation
33+
annotationName,
34+
"Auto Regenerate After Offline Expiry",
35+
string(md.ExactBytes()),
36+
)
15837
}

pkg/cmd/update-tls-artifacts/generate-owners/tlsmetadatainterfaces/annotation_requirement.go

Lines changed: 127 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,26 @@ import (
55
"fmt"
66

77
"github.com/openshift/library-go/pkg/certs/cert-inspection/certgraphapi"
8+
"k8s.io/apimachinery/pkg/util/sets"
89
)
910

10-
type generateMarkdownFn func(pkiInfo *certgraphapi.PKIRegistryInfo) ([]byte, error)
11-
1211
type annotationRequirement struct {
1312
// requirementName is a unique name for metadata requirement
1413
requirementName string
1514
// annotationName is the annotation looked up in cert metadata
1615
annotationName string
17-
// markdownFn is a function which build markdown report from pkiInfo
18-
markdownFn generateMarkdownFn
16+
// title for the markdown
17+
title string
18+
// explanationMD is exactly the markdown to include that explains the purposes of the check
19+
explanationMD string
1920
}
2021

21-
func NewAnnotationRequirement(requirementName, annotationName string, generateMarkdownFn generateMarkdownFn) AnnotationRequirement {
22+
func NewAnnotationRequirement(requirementName, annotationName, title, explanationMD string) AnnotationRequirement {
2223
return annotationRequirement{
2324
requirementName: requirementName,
2425
annotationName: annotationName,
25-
markdownFn: generateMarkdownFn,
26+
title: title,
27+
explanationMD: explanationMD,
2628
}
2729
}
2830

@@ -44,7 +46,7 @@ func (o annotationRequirement) InspectRequirement(rawData []*certgraphapi.PKILis
4446
if err != nil {
4547
return nil, fmt.Errorf("failure marshalling %v.json: %w", o.GetName(), err)
4648
}
47-
markdown, err := o.markdownFn(pkiInfo)
49+
markdown, err := o.generateInspectionMarkdown(pkiInfo)
4850
if err != nil {
4951
return nil, fmt.Errorf("failure marshalling %v.md: %w", o.GetName(), err)
5052
}
@@ -61,6 +63,124 @@ func (o annotationRequirement) InspectRequirement(rawData []*certgraphapi.PKILis
6163
violationJSONBytes)
6264
}
6365

66+
func (o annotationRequirement) generateInspectionMarkdown(pkiInfo *certgraphapi.PKIRegistryInfo) ([]byte, error) {
67+
compliantCertsByOwner := map[string][]certgraphapi.PKIRegistryInClusterCertKeyPair{}
68+
violatingCertsByOwner := map[string][]certgraphapi.PKIRegistryInClusterCertKeyPair{}
69+
compliantCABundlesByOwner := map[string][]certgraphapi.PKIRegistryInClusterCABundle{}
70+
violatingCABundlesByOwner := map[string][]certgraphapi.PKIRegistryInClusterCABundle{}
71+
72+
for i := range pkiInfo.CertKeyPairs {
73+
curr := pkiInfo.CertKeyPairs[i]
74+
owner := curr.CertKeyInfo.OwningJiraComponent
75+
regenerates, _ := AnnotationValue(curr.CertKeyInfo.SelectedCertMetadataAnnotations, o.GetAnnotationName())
76+
if len(regenerates) == 0 {
77+
violatingCertsByOwner[owner] = append(violatingCertsByOwner[owner], curr)
78+
continue
79+
}
80+
81+
compliantCertsByOwner[owner] = append(compliantCertsByOwner[owner], curr)
82+
}
83+
for i := range pkiInfo.CertificateAuthorityBundles {
84+
curr := pkiInfo.CertificateAuthorityBundles[i]
85+
owner := curr.CABundleInfo.OwningJiraComponent
86+
regenerates, _ := AnnotationValue(curr.CABundleInfo.SelectedCertMetadataAnnotations, o.GetAnnotationName())
87+
if len(regenerates) == 0 {
88+
violatingCABundlesByOwner[owner] = append(violatingCABundlesByOwner[owner], curr)
89+
continue
90+
}
91+
compliantCABundlesByOwner[owner] = append(compliantCABundlesByOwner[owner], curr)
92+
}
93+
94+
md := NewMarkdown(o.title)
95+
md.ExactText(o.explanationMD)
96+
97+
if len(violatingCertsByOwner) > 0 || len(violatingCABundlesByOwner) > 0 {
98+
numViolators := 0
99+
for _, v := range violatingCertsByOwner {
100+
numViolators += len(v)
101+
}
102+
for _, v := range violatingCABundlesByOwner {
103+
numViolators += len(v)
104+
}
105+
md.Title(2, fmt.Sprintf("Items Do NOT Meet the Requirement (%d)", numViolators))
106+
violatingOwners := sets.StringKeySet(violatingCertsByOwner)
107+
violatingOwners.Insert(sets.StringKeySet(violatingCABundlesByOwner).UnsortedList()...)
108+
for _, owner := range violatingOwners.List() {
109+
md.Title(3, fmt.Sprintf("%s (%d)", owner, len(violatingCertsByOwner[owner])+len(violatingCABundlesByOwner[owner])))
110+
certs := violatingCertsByOwner[owner]
111+
if len(certs) > 0 {
112+
md.Title(4, fmt.Sprintf("Certificates (%d)", len(certs)))
113+
md.OrderedListStart()
114+
for _, curr := range certs {
115+
md.NewOrderedListItem()
116+
md.Textf("ns/%v secret/%v\n", curr.SecretLocation.Namespace, curr.SecretLocation.Name)
117+
md.Textf("**Description:** %v", curr.CertKeyInfo.Description)
118+
md.Text("\n")
119+
}
120+
md.OrderedListEnd()
121+
md.Text("\n")
122+
}
123+
124+
caBundles := violatingCABundlesByOwner[owner]
125+
if len(caBundles) > 0 {
126+
md.Title(4, fmt.Sprintf("Certificate Authority Bundles (%d)", len(caBundles)))
127+
md.OrderedListStart()
128+
for _, curr := range caBundles {
129+
md.NewOrderedListItem()
130+
md.Textf("ns/%v configmap/%v\n", curr.ConfigMapLocation.Namespace, curr.ConfigMapLocation.Name)
131+
md.Textf("**Description:** %v", curr.CABundleInfo.Description)
132+
md.Text("\n")
133+
}
134+
md.OrderedListEnd()
135+
md.Text("\n")
136+
}
137+
}
138+
}
139+
140+
numCompliant := 0
141+
for _, v := range compliantCertsByOwner {
142+
numCompliant += len(v)
143+
}
144+
for _, v := range compliantCABundlesByOwner {
145+
numCompliant += len(v)
146+
}
147+
md.Title(2, fmt.Sprintf("Items That DO Meet the Requirement (%d)", numCompliant))
148+
allAutoRegenerateAfterOfflineExpirys := sets.StringKeySet(compliantCertsByOwner)
149+
allAutoRegenerateAfterOfflineExpirys.Insert(sets.StringKeySet(compliantCABundlesByOwner).UnsortedList()...)
150+
for _, owner := range allAutoRegenerateAfterOfflineExpirys.List() {
151+
md.Title(3, fmt.Sprintf("%s (%d)", owner, len(compliantCertsByOwner[owner])+len(compliantCABundlesByOwner[owner])))
152+
certs := compliantCertsByOwner[owner]
153+
if len(certs) > 0 {
154+
md.Title(4, fmt.Sprintf("Certificates (%d)", len(certs)))
155+
md.OrderedListStart()
156+
for _, curr := range certs {
157+
md.NewOrderedListItem()
158+
md.Textf("ns/%v secret/%v\n", curr.SecretLocation.Namespace, curr.SecretLocation.Name)
159+
md.Textf("**Description:** %v", curr.CertKeyInfo.Description)
160+
md.Text("\n")
161+
}
162+
md.OrderedListEnd()
163+
md.Text("\n")
164+
}
165+
166+
caBundles := compliantCABundlesByOwner[owner]
167+
if len(caBundles) > 0 {
168+
md.Title(4, fmt.Sprintf("Certificate Authority Bundles (%d)", len(caBundles)))
169+
md.OrderedListStart()
170+
for _, curr := range caBundles {
171+
md.NewOrderedListItem()
172+
md.Textf("ns/%v configmap/%v\n", curr.ConfigMapLocation.Namespace, curr.ConfigMapLocation.Name)
173+
md.Textf("**Description:** %v", curr.CABundleInfo.Description)
174+
md.Text("\n")
175+
}
176+
md.OrderedListEnd()
177+
md.Text("\n")
178+
}
179+
}
180+
181+
return md.Bytes(), nil
182+
}
183+
64184
func generateViolationJSONForAnnotationRequirement(annotationName string, pkiInfo *certgraphapi.PKIRegistryInfo) *certgraphapi.PKIRegistryInfo {
65185
ret := &certgraphapi.PKIRegistryInfo{}
66186

pkg/cmd/update-tls-artifacts/generate-owners/tlsmetadatainterfaces/markdown.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@ func (m *Markdown) Bytes() []byte {
3636
return ret.Bytes()
3737
}
3838

39+
// ExactBytes returns markdown with table of contents or title. Useful for embedding.
40+
func (m *Markdown) ExactBytes() []byte {
41+
ret := &bytes.Buffer{}
42+
fmt.Fprintf(ret, m.body.String())
43+
return ret.Bytes()
44+
}
45+
3946
func (m *Markdown) UnlistedTitle(level int, text string) {
4047
titlePrefix := strings.Repeat("#", level)
4148
fmt.Fprintf(m.body, "%s %s\n", titlePrefix, text)
@@ -54,6 +61,7 @@ func (m *Markdown) Title(level int, text string) {
5461
func (m *Markdown) ExactText(text string) {
5562
if m.orderedListDepth == 0 {
5663
fmt.Fprintf(m.body, "%s\n", text)
64+
return
5765
}
5866

5967
prefix := ""

0 commit comments

Comments
 (0)