@@ -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-
1211type 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+
64184func generateViolationJSONForAnnotationRequirement (annotationName string , pkiInfo * certgraphapi.PKIRegistryInfo ) * certgraphapi.PKIRegistryInfo {
65185 ret := & certgraphapi.PKIRegistryInfo {}
66186
0 commit comments