Skip to content

Commit

Permalink
feature: tracee loads CRDs policies if avaliable
Browse files Browse the repository at this point in the history
  • Loading branch information
josedonizetti committed Oct 29, 2023
1 parent c212fe0 commit 4595399
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 70 deletions.
38 changes: 31 additions & 7 deletions pkg/cmd/cobra/cobra.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import (
"github.com/aquasecurity/tracee/pkg/config"
"github.com/aquasecurity/tracee/pkg/errfmt"
"github.com/aquasecurity/tracee/pkg/events"
"github.com/aquasecurity/tracee/pkg/k8s"
"github.com/aquasecurity/tracee/pkg/k8s/apis/tracee.aquasec.com/v1beta1"
"github.com/aquasecurity/tracee/pkg/logger"
"github.com/aquasecurity/tracee/pkg/policy"
"github.com/aquasecurity/tracee/pkg/signatures/engine"
Expand Down Expand Up @@ -156,18 +158,40 @@ func GetTraceeRunner(c *cobra.Command, version string) (cmd.Runner, error) {
return runner, errors.New("policy and event flags cannot be used together")
}

var policies *policy.Policies
var k8sPolicies []v1beta1.PolicyInterface

if len(policyFlags) > 0 {
policies, err = createPoliciesFromPolicyFiles(policyFlags)
k8sClient, err := k8s.New()
if err != nil {
logger.Debugw("kubernetes cluster", "error", err)
}

// if k8sClient is not nil, then we are running inside a k8s cluster
if k8sClient != nil {
k8sPolicies, err = k8sClient.GetPolicy(c.Context())
if err != nil {
return runner, err
logger.Debugw("kubernetes cluster", "error", err)
}
}

var policies *policy.Policies

if k8sPolicies != nil && len(k8sPolicies) > 0 {
logger.Debugw("using policies from kubernetes crd")

if len(k8sPolicies) > 0 {
policies, err = createPoliciesFromK8SPolicy(k8sPolicies)
}
} else if len(policyFlags) > 0 {
logger.Debugw("using policies from --policy flag")
policies, err = createPoliciesFromPolicyFiles(policyFlags)
} else {
logger.Debugw("using policies from --scope and --events flag")
policies, err = createPoliciesFromCLIFlags(scopeFlags, eventFlags)
if err != nil {
return runner, err
}
}

// if any error returned while creating policies, return it
if err != nil {
return runner, err
}

cfg.Policies = policies
Expand Down
10 changes: 10 additions & 0 deletions pkg/cmd/cobra/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,20 @@ package cobra

import (
"github.com/aquasecurity/tracee/pkg/cmd/flags"
k8s "github.com/aquasecurity/tracee/pkg/k8s/apis/tracee.aquasec.com/v1beta1"
"github.com/aquasecurity/tracee/pkg/policy"
"github.com/aquasecurity/tracee/pkg/policy/v1beta1"
)

func createPoliciesFromK8SPolicy(policies []k8s.PolicyInterface) (*policy.Policies, error) {
policyScopeMap, policyEventsMap, err := flags.PrepareFilterMapsFromPolicies(policies)
if err != nil {
return nil, err
}

return flags.CreatePolicies(policyScopeMap, policyEventsMap, true)
}

func createPoliciesFromPolicyFiles(policyFlags []string) (*policy.Policies, error) {
policyFiles, err := v1beta1.PoliciesFromPaths(policyFlags)
if err != nil {
Expand Down
22 changes: 11 additions & 11 deletions pkg/cmd/flags/policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ import (
"github.com/aquasecurity/tracee/pkg/errfmt"
"github.com/aquasecurity/tracee/pkg/events"
"github.com/aquasecurity/tracee/pkg/filters"
k8s "github.com/aquasecurity/tracee/pkg/k8s/apis/tracee.aquasec.com/v1beta1"
"github.com/aquasecurity/tracee/pkg/logger"
"github.com/aquasecurity/tracee/pkg/policy"
"github.com/aquasecurity/tracee/pkg/policy/v1beta1"
)

// PrepareFilterMapsForPolicies prepares the scope and events PolicyFilterMap for the policies
func PrepareFilterMapsFromPolicies(policies []v1beta1.PolicyFile) (PolicyScopeMap, PolicyEventMap, error) {
func PrepareFilterMapsFromPolicies(policies []k8s.PolicyInterface) (PolicyScopeMap, PolicyEventMap, error) {
policyScopeMap := make(PolicyScopeMap)
policyEventsMap := make(PolicyEventMap)

Expand All @@ -28,19 +28,19 @@ func PrepareFilterMapsFromPolicies(policies []v1beta1.PolicyFile) (PolicyScopeMa
policyNames := make(map[string]bool)

for pIdx, p := range policies {
if _, ok := policyNames[p.Name()]; ok {
return nil, nil, errfmt.Errorf("policy %s already exist", p.Name())
if _, ok := policyNames[p.GetName()]; ok {
return nil, nil, errfmt.Errorf("policy %s already exist", p.GetName())
}
policyNames[p.Name()] = true
policyNames[p.GetName()] = true

scopeFlags := make([]scopeFlag, 0)

// scope
for _, s := range p.Scope() {
for _, s := range p.GetScope() {
s = strings.ReplaceAll(s, " ", "")

if s == "global" && len(p.Scope()) > 1 {
return nil, nil, errfmt.Errorf("policy %s, global scope must be unique", p.Name())
if s == "global" && len(p.GetScope()) > 1 {
return nil, nil, errfmt.Errorf("policy %s, global scope must be unique", p.GetName())
}

if s == "global" {
Expand All @@ -56,13 +56,13 @@ func PrepareFilterMapsFromPolicies(policies []v1beta1.PolicyFile) (PolicyScopeMa
}

policyScopeMap[pIdx] = policyScopes{
policyName: p.Name(),
policyName: p.GetName(),
scopeFlags: scopeFlags,
}

eventFlags := make([]eventFlag, 0)

for _, r := range p.Rules() {
for _, r := range p.GetRules() {
evtFlags, err := parseEventFlag(r.Event)
if err != nil {
return nil, nil, errfmt.WrapError(err)
Expand Down Expand Up @@ -92,7 +92,7 @@ func PrepareFilterMapsFromPolicies(policies []v1beta1.PolicyFile) (PolicyScopeMa
}

policyEventsMap[pIdx] = policyEvents{
policyName: p.Name(),
policyName: p.GetName(),
eventFlags: eventFlags,
}
}
Expand Down
57 changes: 57 additions & 0 deletions pkg/k8s/policy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package k8s

import (
"context"

"github.com/aquasecurity/tracee/pkg/k8s/apis/tracee.aquasec.com/v1beta1"
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/client-go/rest"
"k8s.io/kubectl/pkg/scheme"
)

type Client struct {
restClient *rest.RESTClient
}

func New() (*Client, error) {
config, err := rest.InClusterConfig()
if err != nil {
return nil, err
}

v1beta1.AddToScheme(scheme.Scheme)

crdConfig := *config
crdConfig.ContentConfig.GroupVersion = &v1beta1.GroupVersion
crdConfig.APIPath = "/apis"
crdConfig.NegotiatedSerializer = serializer.NewCodecFactory(scheme.Scheme)
crdConfig.UserAgent = rest.DefaultKubernetesUserAgent()

client, err := rest.UnversionedRESTClientFor(&crdConfig)
if err != nil {
return nil, err
}

return &Client{client}, nil
}

func (c Client) GetPolicy(ctx context.Context) ([]v1beta1.PolicyInterface, error) {
result := v1beta1.PolicyList{}

err := c.restClient.
Get().
Resource("policies").
Do(ctx).
Into(&result)

if err != nil {
return nil, err
}

policies := make([]v1beta1.PolicyInterface, len(result.Items))
for i, item := range result.Items {
policies[i] = item
}

return policies, nil
}
Loading

0 comments on commit 4595399

Please sign in to comment.