Skip to content

Commit

Permalink
add presave processor to deduplicate profile info
Browse files Browse the repository at this point in the history
Signed-off-by: Matthias Bertschy <[email protected]>
  • Loading branch information
matthyx committed Jan 31, 2024
1 parent b69c3ec commit b48cf34
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 2 deletions.
27 changes: 27 additions & 0 deletions pkg/apis/softwarecomposition/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package softwarecomposition

import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"strings"
)

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
Expand Down Expand Up @@ -314,11 +315,37 @@ type ExecCalls struct {
Envs []string
}

const sep = "␟"

func (e ExecCalls) String() string {
s := strings.Builder{}
s.WriteString(e.Path)
for _, arg := range e.Args {
s.WriteString(sep)
s.WriteString(arg)
}
for _, env := range e.Envs {
s.WriteString(sep)
s.WriteString(env)
}
return s.String()
}

type OpenCalls struct {
Path string
Flags []string
}

func (e OpenCalls) String() string {
s := strings.Builder{}
s.WriteString(e.Path)
for _, arg := range e.Flags {
s.WriteString(sep)
s.WriteString(arg)
}
return s.String()
}

type ApplicationProfileStatus struct {
}

Expand Down
3 changes: 2 additions & 1 deletion pkg/apiserver/apiserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ func (c completedConfig) New() (*WardleServer, error) {

storageImpl := file.NewStorageImpl(osFs, file.DefaultStorageRoot)

applicationProfileStorageImpl := file.NewStorageImplWithCollector(osFs, file.DefaultStorageRoot, &file.ApplicationProfileProcessor{})
configScanStorageImpl := file.NewConfigurationScanSummaryStorage(&storageImpl)
vulnerabilitySummaryStorage := file.NewVulnerabilitySummaryStorage(&storageImpl)
generatedNetworkPolicyStorage := file.NewGeneratedNetworkPolicyStorage(&storageImpl)
Expand All @@ -168,7 +169,7 @@ func (c completedConfig) New() (*WardleServer, error) {
v1beta1storage["configurationscansummaries"] = sbomregistry.RESTInPeace(configurationscansummary.NewREST(Scheme, configScanStorageImpl, c.GenericConfig.RESTOptionsGetter))
v1beta1storage["vulnerabilitysummaries"] = sbomregistry.RESTInPeace(vsumstorage.NewREST(Scheme, vulnerabilitySummaryStorage, c.GenericConfig.RESTOptionsGetter))

v1beta1storage["applicationprofiles"] = sbomregistry.RESTInPeace(applicationprofile.NewREST(Scheme, storageImpl, c.GenericConfig.RESTOptionsGetter))
v1beta1storage["applicationprofiles"] = sbomregistry.RESTInPeace(applicationprofile.NewREST(Scheme, applicationProfileStorageImpl, c.GenericConfig.RESTOptionsGetter))
v1beta1storage["applicationprofilesummaries"] = sbomregistry.RESTInPeace(applicationprofilesummary.NewREST(Scheme, storageImpl, c.GenericConfig.RESTOptionsGetter))
v1beta1storage["applicationactivities"] = sbomregistry.RESTInPeace(applicationactivity.NewREST(Scheme, storageImpl, c.GenericConfig.RESTOptionsGetter))

Expand Down
64 changes: 64 additions & 0 deletions pkg/registry/file/processor.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package file

import (
"fmt"
sets "github.com/deckarep/golang-set/v2"
"github.com/kubescape/storage/pkg/apis/softwarecomposition"
"k8s.io/apimachinery/pkg/runtime"
)

type Processor interface {
PreSave(object runtime.Object) error
}

type DefaultProcessor struct {
}

var _ Processor = (*DefaultProcessor)(nil)

func (d DefaultProcessor) PreSave(_ runtime.Object) error {
return nil
}

type ApplicationProfileProcessor struct {
}

var _ Processor = (*ApplicationProfileProcessor)(nil)

func (a ApplicationProfileProcessor) PreSave(object runtime.Object) error {
profile, ok := object.(*softwarecomposition.ApplicationProfile)
if !ok {
return fmt.Errorf("given object is not an ApplicationProfile")
}
for i, container := range profile.Spec.Containers {
profile.Spec.Containers[i] = deflate(container)
}
return nil
}

func deflate(container softwarecomposition.ApplicationProfileContainer) softwarecomposition.ApplicationProfileContainer {
return softwarecomposition.ApplicationProfileContainer{
Name: container.Name,
Capabilities: sets.NewThreadUnsafeSet(container.Capabilities...).ToSlice(),
Execs: deflateStringer(container.Execs),
Opens: deflateStringer(container.Opens),
Syscalls: sets.NewThreadUnsafeSet(container.Syscalls...).ToSlice(),
}
}

type Stringer interface {
String() string
}

func deflateStringer[T Stringer](in []T) []T {
var out []T
set := sets.NewSet[string]()
for _, item := range in {
if set.Contains(item.String()) {
continue
}
set.Add(item.String())
out = append(out, item)
}
return out
}
19 changes: 18 additions & 1 deletion pkg/registry/file/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,11 @@ type objState struct {
// hides all the storage-related operations behind it.
type StorageImpl struct {
appFs afero.Fs
watchDispatcher watchDispatcher
locks *Mutex[string]
processor Processor
root string
versioner storage.Versioner
watchDispatcher watchDispatcher
}

// StorageQuerier wraps the storage.Interface and adds some extra methods which are used by the storage implementation.
Expand All @@ -62,10 +63,22 @@ var _ StorageQuerier = &StorageImpl{}
func NewStorageImpl(appFs afero.Fs, root string) StorageQuerier {
return &StorageImpl{
appFs: appFs,
locks: NewMapMutex[string](),
processor: DefaultProcessor{},
root: root,
versioner: storage.APIObjectVersioner{},
watchDispatcher: newWatchDispatcher(),
}
}

func NewStorageImplWithCollector(appFs afero.Fs, root string, processor Processor) StorageQuerier {
return &StorageImpl{
appFs: appFs,
locks: NewMapMutex[string](),
processor: processor,
root: root,
versioner: storage.APIObjectVersioner{},
watchDispatcher: newWatchDispatcher(),
}
}

Expand Down Expand Up @@ -106,6 +119,10 @@ func isPayloadFile(path string) bool {
}

func (s *StorageImpl) writeFiles(key string, obj runtime.Object, metaOut runtime.Object) error {
// call processor on object to be saved
if err := s.processor.PreSave(obj); err != nil {
return fmt.Errorf("processor.PreSave: %w", err)
}
// set resourceversion
if version, _ := s.versioner.ObjectResourceVersion(obj); version == 0 {
if err := s.versioner.UpdateObject(obj, 1); err != nil {
Expand Down

0 comments on commit b48cf34

Please sign in to comment.