@@ -2,12 +2,14 @@ package certgraphanalysis
22
33import (
44 "context"
5+ "fmt"
56 "strings"
67
78 "github.com/openshift/api/annotations"
89 "github.com/openshift/library-go/pkg/certs/cert-inspection/certgraphapi"
910 corev1 "k8s.io/api/core/v1"
1011 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
12+ "k8s.io/apimachinery/pkg/labels"
1113 utilerrors "k8s.io/apimachinery/pkg/util/errors"
1214 "k8s.io/apimachinery/pkg/util/sets"
1315 "k8s.io/client-go/kubernetes"
@@ -251,11 +253,16 @@ func MergePKILists(ctx context.Context, first, second *certgraphapi.PKIList) *ce
251253 }
252254 onDiskResourceData = deduplicateOnDiskMetadata (onDiskResourceData )
253255
256+ inMemoryResourceData := certgraphapi.PerInMemoryResourceData {
257+ CertKeyPairs : append (first .InMemoryResourceData .CertKeyPairs , second .InMemoryResourceData .CertKeyPairs ... ),
258+ }
259+
254260 return & certgraphapi.PKIList {
255261 CertificateAuthorityBundles : * caBundlesList ,
256262 CertKeyPairs : * certList ,
257263 InClusterResourceData : inClusterData ,
258264 OnDiskResourceData : onDiskResourceData ,
265+ InMemoryResourceData : inMemoryResourceData ,
259266 }
260267}
261268
@@ -299,3 +306,85 @@ func GetBootstrapIPAndHostname(ctx context.Context, kubeClient kubernetes.Interf
299306
300307 return bootstrapIP , bootstrapHostname , nil
301308}
309+
310+ type InMemoryCertDetail struct {
311+ Namespace string
312+ LabelSelector labels.Selector
313+ Description string
314+ NamePrefix string
315+ Validity string
316+ CertInfo certgraphapi.PKIRegistryCertKeyPairInfo
317+ }
318+
319+ // CreateInMemoryPKIList creates a PKIList listing in-memory certificate for each apiserver
320+
321+ func CreateInMemoryPKIList (ctx context.Context , kubeClient kubernetes.Interface , details []InMemoryCertDetail ) (* certgraphapi.PKIList , error ) {
322+ errs := []error {}
323+ result := & certgraphapi.PKIList {}
324+
325+ for _ , detail := range details {
326+ err := addInMemoryCertificateStub (ctx , result , kubeClient , detail )
327+ if err != nil {
328+ errs = append (errs , fmt .Errorf ("failed to add in-memory certificate stub for %#v: %w" , detail , err ))
329+ }
330+ }
331+ return result , utilerrors .NewAggregate (errs )
332+
333+ }
334+
335+ func addInMemoryCertificateStub (ctx context.Context , list * certgraphapi.PKIList , kubeClient kubernetes.Interface , detail InMemoryCertDetail ) error {
336+ if list == nil {
337+ list = & certgraphapi.PKIList {}
338+ }
339+
340+ if list .InMemoryResourceData .CertKeyPairs == nil {
341+ list .InMemoryResourceData .CertKeyPairs = []certgraphapi.PKIRegistryInMemoryCertKeyPair {}
342+ }
343+ if list .CertKeyPairs .Items == nil {
344+ list .CertKeyPairs .Items = []certgraphapi.CertKeyPair {}
345+ }
346+
347+ // For each matched pod in namespace, create a cert key pair
348+ podList , err := kubeClient .CoreV1 ().Pods (detail .Namespace ).List (ctx , metav1.ListOptions {
349+ LabelSelector : detail .LabelSelector .String (),
350+ })
351+
352+ if err != nil {
353+ return err
354+ }
355+
356+ for i , pod := range podList .Items {
357+ certKeyPair := certgraphapi.CertKeyPair {
358+ Name : fmt .Sprintf ("%s-%d::1" , detail .NamePrefix , i ),
359+ Description : detail .Description ,
360+ Spec : certgraphapi.CertKeyPairSpec {
361+ InMemoryLocations : []certgraphapi.InClusterPodLocation {
362+ {
363+ Namespace : pod .Namespace ,
364+ // Using fake pod name to avoid removing IPs or hashes
365+ Name : fmt .Sprintf ("%s-%d" , detail .NamePrefix , i ),
366+ },
367+ },
368+ CertMetadata : certgraphapi.CertKeyMetadata {
369+ ValidityDuration : detail .Validity ,
370+ CertIdentifier : certgraphapi.CertIdentifier {
371+ // PubkeyModulus needs to be unique so that the secret would not be removed during deduplication
372+ PubkeyModulus : fmt .Sprintf ("in-memory-%s-%d" , detail .NamePrefix , i ),
373+ },
374+ },
375+ },
376+ }
377+
378+ list .CertKeyPairs .Items = append (list .CertKeyPairs .Items , certKeyPair )
379+
380+ list .InMemoryResourceData .CertKeyPairs = append (list .InMemoryResourceData .CertKeyPairs , certgraphapi.PKIRegistryInMemoryCertKeyPair {
381+ PodLocation : certgraphapi.InClusterPodLocation {
382+ Namespace : pod .Namespace ,
383+ Name : fmt .Sprintf ("%s-%d" , detail .NamePrefix , i ),
384+ },
385+ CertKeyInfo : detail .CertInfo ,
386+ })
387+ }
388+ return nil
389+
390+ }
0 commit comments