@@ -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,84 @@ 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+ func CreateInMemoryPKIList (ctx context.Context , kubeClient kubernetes.Interface , details []InMemoryCertDetail ) (* certgraphapi.PKIList , error ) {
321+ errs := []error {}
322+ result := & certgraphapi.PKIList {}
323+
324+ for _ , detail := range details {
325+ err := addInMemoryCertificateStub (ctx , result , kubeClient , detail )
326+ if err != nil {
327+ errs = append (errs , fmt .Errorf ("failed to add in-memory certificate stub for %#v: %w" , detail , err ))
328+ }
329+ }
330+ return result , utilerrors .NewAggregate (errs )
331+
332+ }
333+
334+ func addInMemoryCertificateStub (ctx context.Context , list * certgraphapi.PKIList , kubeClient kubernetes.Interface , detail InMemoryCertDetail ) error {
335+ if list == nil {
336+ list = & certgraphapi.PKIList {}
337+ }
338+
339+ if list .InMemoryResourceData .CertKeyPairs == nil {
340+ list .InMemoryResourceData .CertKeyPairs = []certgraphapi.PKIRegistryInMemoryCertKeyPair {}
341+ }
342+ if list .CertKeyPairs .Items == nil {
343+ list .CertKeyPairs .Items = []certgraphapi.CertKeyPair {}
344+ }
345+
346+ // For each matched pod in namespace, create a cert key pair
347+ podList , err := kubeClient .CoreV1 ().Pods (detail .Namespace ).List (ctx , metav1.ListOptions {
348+ LabelSelector : detail .LabelSelector .String (),
349+ })
350+
351+ if err != nil {
352+ return err
353+ }
354+
355+ for i , pod := range podList .Items {
356+ certKeyPair := certgraphapi.CertKeyPair {
357+ Name : fmt .Sprintf ("%s-%d::1" , detail .NamePrefix , i ),
358+ Description : detail .Description ,
359+ Spec : certgraphapi.CertKeyPairSpec {
360+ InMemoryLocations : []certgraphapi.InClusterPodLocation {
361+ {
362+ Namespace : pod .Namespace ,
363+ // Using fake pod name to avoid removing IPs or hashes
364+ Name : fmt .Sprintf ("%s-%d" , detail .NamePrefix , i ),
365+ },
366+ },
367+ CertMetadata : certgraphapi.CertKeyMetadata {
368+ ValidityDuration : detail .Validity ,
369+ CertIdentifier : certgraphapi.CertIdentifier {
370+ // PubkeyModulus needs to be unique so that the secret would not be removed during deduplication
371+ PubkeyModulus : fmt .Sprintf ("in-memory-%s-%d" , detail .NamePrefix , i ),
372+ },
373+ },
374+ },
375+ }
376+
377+ list .CertKeyPairs .Items = append (list .CertKeyPairs .Items , certKeyPair )
378+
379+ list .InMemoryResourceData .CertKeyPairs = append (list .InMemoryResourceData .CertKeyPairs , certgraphapi.PKIRegistryInMemoryCertKeyPair {
380+ PodLocation : certgraphapi.InClusterPodLocation {
381+ Namespace : pod .Namespace ,
382+ Name : fmt .Sprintf ("%s-%d" , detail .NamePrefix , i ),
383+ },
384+ CertKeyInfo : detail .CertInfo ,
385+ })
386+ }
387+ return nil
388+
389+ }
0 commit comments