Skip to content

Commit e240400

Browse files
committed
cert-inspection: create stubs for in-memory certificates
We have no method to detect those, we have to create stub entries for every instance of apiserver
1 parent cf85180 commit e240400

File tree

4 files changed

+133
-4
lines changed

4 files changed

+133
-4
lines changed

pkg/certs/cert-inspection/certgraphanalysis/collector.go

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@ package certgraphanalysis
22

33
import (
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+
}

pkg/certs/cert-inspection/certgraphanalysis/deduplication.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ func deduplicateCertKeyPairs(in []*certgraphapi.CertKeyPair) []*certgraphapi.Cer
2525
found = true
2626
ret[j] = CombineSecretLocations(ret[j], currIn.Spec.SecretLocations)
2727
ret[j] = CombineCertOnDiskLocations(ret[j], currIn.Spec.OnDiskLocations)
28+
ret[j] = CombineCertInMemoryLocations(ret[j], currIn.Spec.InMemoryLocations)
2829
break
2930
}
3031
}
@@ -199,3 +200,20 @@ func deduplicateOnDiskMetadata(in certgraphapi.PerOnDiskResourceData) certgrapha
199200
}
200201
return out
201202
}
203+
204+
// CombineCertInMemoryLocations returns a CertKeyPair with all in-memory locations from in and rhs de-duplicated into a single list
205+
func CombineCertInMemoryLocations(in *certgraphapi.CertKeyPair, rhs []certgraphapi.InClusterPodLocation) *certgraphapi.CertKeyPair {
206+
out := in.DeepCopy()
207+
for _, curr := range rhs {
208+
found := false
209+
for _, existing := range in.Spec.InMemoryLocations {
210+
if curr == existing {
211+
found = true
212+
}
213+
}
214+
if !found {
215+
out.Spec.InMemoryLocations = append(out.Spec.InMemoryLocations, curr)
216+
}
217+
}
218+
return out
219+
}

pkg/certs/cert-inspection/certgraphapi/type_registry.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
package certgraphapi
22

33
type PKIRegistryCertKeyPair struct {
4-
InClusterLocation *PKIRegistryInClusterCertKeyPair
5-
OnDiskLocation *PKIRegistryOnDiskCertKeyPair
4+
InClusterLocation *PKIRegistryInClusterCertKeyPair
5+
OnDiskLocation *PKIRegistryOnDiskCertKeyPair
6+
InMemoryPodLocation *PKIRegistryInMemoryCertKeyPair
67
}
78

89
// PKIRegistryOnDiskCertKeyPair identifies certificate key pair on disk and stores its metadata
@@ -13,6 +14,14 @@ type PKIRegistryOnDiskCertKeyPair struct {
1314
CertKeyInfo PKIRegistryCertKeyPairInfo `json:"certKeyInfo"`
1415
}
1516

17+
// PKIRegistryInMemoryCertKeyPair identifies certificate key pair and stores its metadata
18+
type PKIRegistryInMemoryCertKeyPair struct {
19+
// PodLocation points to the pod location
20+
PodLocation InClusterPodLocation `json:"podLocation"`
21+
// CertKeyInfo stores metadata for certificate key pair
22+
CertKeyInfo PKIRegistryCertKeyPairInfo `json:"certKeyInfo"`
23+
}
24+
1625
// PKIRegistryInClusterCertKeyPair identifies certificate key pair and stores its metadata
1726
type PKIRegistryInClusterCertKeyPair struct {
1827
// SecretLocation points to the secret location

pkg/certs/cert-inspection/certgraphapi/types.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ type PKIList struct {
1414

1515
InClusterResourceData PerInClusterResourceData
1616
OnDiskResourceData PerOnDiskResourceData
17+
InMemoryResourceData PerInMemoryResourceData
1718

1819
CertificateAuthorityBundles CertificateAuthorityBundleList
1920
CertKeyPairs CertKeyPairList
@@ -29,6 +30,12 @@ type PerInClusterResourceData struct {
2930
CertKeyPairs []PKIRegistryInClusterCertKeyPair `json:"certKeyPairs"`
3031
}
3132

33+
// PerInMemoryResourceData tracks metadata that corresponds to specific certificates stored in pod memory.
34+
type PerInMemoryResourceData struct {
35+
// +mapType:=atomic
36+
CertKeyPairs []PKIRegistryInMemoryCertKeyPair `json:"certKeyPairs"`
37+
}
38+
3239
// PerOnDiskResourceData tracks metadata that corresponds to specific files on disk.
3340
// This data should not duplicate the analysis of the certkeypair lists, but is pulled from files on disk.
3441
// It will be stitched together by a generator after the fact.
@@ -89,8 +96,9 @@ type CertKeyPairStatus struct {
8996
}
9097

9198
type CertKeyPairSpec struct {
92-
SecretLocations []InClusterSecretLocation
93-
OnDiskLocations []OnDiskCertKeyPairLocation
99+
SecretLocations []InClusterSecretLocation
100+
OnDiskLocations []OnDiskCertKeyPairLocation
101+
InMemoryLocations []InClusterPodLocation
94102

95103
CertMetadata CertKeyMetadata
96104
Details CertKeyPairDetails
@@ -106,6 +114,11 @@ type InClusterConfigMapLocation struct {
106114
Name string
107115
}
108116

117+
type InClusterPodLocation struct {
118+
Namespace string
119+
Name string
120+
}
121+
109122
type OnDiskCertKeyPairLocation struct {
110123
Cert OnDiskLocation
111124
Key OnDiskLocation

0 commit comments

Comments
 (0)