Skip to content

Commit 267c72f

Browse files
Merge pull request #33 from kubescape/dev-branch
get SBOM through watch
2 parents e0ee4e7 + 97af479 commit 267c72f

File tree

1 file changed

+90
-10
lines changed

1 file changed

+90
-10
lines changed

pkg/storageclient/storage_client.go

Lines changed: 90 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,44 @@
11
package storageclient
22

33
import (
4-
"context"
4+
gcontext "context"
55
"fmt"
66
"os"
7+
"sync"
8+
"time"
79

810
apimachineryerrors "k8s.io/apimachinery/pkg/api/errors"
911
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
12+
"k8s.io/apimachinery/pkg/watch"
1013
"k8s.io/client-go/rest"
1114
"k8s.io/client-go/tools/clientcmd"
1215

16+
"sniffer/pkg/context"
17+
18+
"github.com/kubescape/go-logger"
19+
"github.com/kubescape/go-logger/helpers"
1320
spdxv1beta1 "github.com/kubescape/storage/pkg/apis/softwarecomposition/v1beta1"
1421
spdxclient "github.com/kubescape/storage/pkg/generated/clientset/versioned"
1522
)
1623

1724
const (
18-
KubeConfig = "KUBECONFIG"
19-
KubescapeNamespace = "kubescape"
25+
KubeConfig = "KUBECONFIG"
26+
KubescapeNamespace = "kubescape"
27+
SBOMServerStateExist SBOMServerState = "Exist"
28+
SBOMServerStateDeleted SBOMServerState = "Deleted"
29+
retryWatcherSleep = 30
2030
)
2131

32+
type SBOMServerState string
33+
34+
type SBOMMetadata struct {
35+
SBOMID string
36+
SBOMServerState
37+
}
38+
2239
type StorageK8SAggregatedAPIClient struct {
23-
clientset *spdxclient.Clientset
40+
clientset *spdxclient.Clientset
41+
readySBOMs sync.Map
2442
}
2543

2644
var storageclientErrors map[string]error
@@ -45,13 +63,75 @@ func CreateSBOMStorageK8SAggregatedAPIClient() (*StorageK8SAggregatedAPIClient,
4563
if err != nil {
4664
return nil, fmt.Errorf("failed to create K8S Aggregated API Client with err: %v", err)
4765
}
48-
return &StorageK8SAggregatedAPIClient{
49-
clientset: clientset,
50-
}, nil
66+
storageClient := &StorageK8SAggregatedAPIClient{
67+
clientset: clientset,
68+
readySBOMs: sync.Map{},
69+
}
70+
71+
go storageClient.watchForSBOMs()
72+
73+
return storageClient, nil
74+
}
75+
76+
func (sc *StorageK8SAggregatedAPIClient) watchForSBOMs() {
77+
for {
78+
watcher, err := sc.clientset.SpdxV1beta1().SBOMSPDXv2p3s(KubescapeNamespace).Watch(gcontext.TODO(), metav1.ListOptions{})
79+
if err != nil {
80+
logger.L().Ctx(context.GetBackgroundContext()).Error("Watch for SBOMs failed ", helpers.Error(err))
81+
logger.L().Ctx(context.GetBackgroundContext()).Error("Retry in ", helpers.String(fmt.Sprintf("%d", retryWatcherSleep), " seconds"))
82+
time.Sleep(retryWatcherSleep * time.Second)
83+
continue
84+
}
85+
for {
86+
event, chanActive := <-watcher.ResultChan()
87+
if !chanActive {
88+
watcher.Stop()
89+
break
90+
}
91+
if event.Type == watch.Error {
92+
watcher.Stop()
93+
break
94+
}
95+
96+
SBOM, ok := event.Object.(*spdxv1beta1.SBOMSPDXv2p3)
97+
if !ok {
98+
continue
99+
}
100+
101+
switch event.Type {
102+
case watch.Added:
103+
SBOMmetadataAdded := SBOMMetadata{
104+
SBOMID: SBOM.Name,
105+
SBOMServerState: SBOMServerStateExist,
106+
}
107+
sc.readySBOMs.Store(SBOM.Name, SBOMmetadataAdded)
108+
logger.L().Debug(fmt.Sprintf("new SBOM %s was detected in storage with labels: %v", SBOM.Name, SBOM.Labels))
109+
case watch.Deleted:
110+
SBOMmetadataDeleted := SBOMMetadata{
111+
SBOMID: SBOM.Name,
112+
SBOMServerState: SBOMServerStateDeleted,
113+
}
114+
sc.readySBOMs.Store(SBOM.Name, SBOMmetadataDeleted)
115+
logger.L().Debug(fmt.Sprintf("new SBOM %s was deleted from storage with labels: %v", SBOM.Name, SBOM.Labels))
116+
}
117+
}
118+
119+
}
51120
}
52121

53122
func (sc *StorageK8SAggregatedAPIClient) GetData(key string) (any, error) {
54-
SBOM, err := sc.clientset.SpdxV1beta1().SBOMSPDXv2p3s(KubescapeNamespace).Get(context.TODO(), key, metav1.GetOptions{})
123+
value, exist := sc.readySBOMs.Load(key)
124+
if !exist {
125+
return nil, fmt.Errorf("SBOM not exist in server")
126+
}
127+
metadata, ok := value.(SBOMMetadata)
128+
if !ok {
129+
return nil, fmt.Errorf("failed to convert to SBOM metadata")
130+
}
131+
if metadata.SBOMServerState == SBOMServerStateDeleted {
132+
return nil, fmt.Errorf("SBOM not exist in server, SBOM deleted")
133+
}
134+
SBOM, err := sc.clientset.SpdxV1beta1().SBOMSPDXv2p3s(KubescapeNamespace).Get(gcontext.TODO(), key, metav1.GetOptions{})
55135
if err != nil {
56136
return nil, err
57137
}
@@ -62,7 +142,7 @@ func (sc *StorageK8SAggregatedAPIClient) PutData(key string, data any) error {
62142
if !ok {
63143
return fmt.Errorf("failed to update SBOM: SBOM is not in the right form")
64144
}
65-
_, err := sc.clientset.SpdxV1beta1().SBOMSPDXv2p3s(KubescapeNamespace).Update(context.TODO(), SBOM, metav1.UpdateOptions{})
145+
_, err := sc.clientset.SpdxV1beta1().SBOMSPDXv2p3s(KubescapeNamespace).Update(gcontext.TODO(), SBOM, metav1.UpdateOptions{})
66146
if err != nil {
67147
return err
68148
}
@@ -73,7 +153,7 @@ func (sc *StorageK8SAggregatedAPIClient) PostData(key string, data any) error {
73153
if !ok {
74154
return fmt.Errorf("failed to update SBOM: SBOM is not in the right form")
75155
}
76-
retSBOM, err := sc.clientset.SpdxV1beta1().SBOMSPDXv2p3s(KubescapeNamespace).Create(context.TODO(), SBOM, metav1.CreateOptions{})
156+
retSBOM, err := sc.clientset.SpdxV1beta1().SBOMSPDXv2p3s(KubescapeNamespace).Create(gcontext.TODO(), SBOM, metav1.CreateOptions{})
77157
if err != nil {
78158
return err
79159
}

0 commit comments

Comments
 (0)