Skip to content

Commit

Permalink
Merge pull request #26 from josedonizetti/add-get-artifact
Browse files Browse the repository at this point in the history
feat: add get artifact
  • Loading branch information
chen-keinan authored May 15, 2022
2 parents 233c92f + b6e8afa commit be8c01f
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 15 deletions.
26 changes: 19 additions & 7 deletions examples/trivy.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,29 @@ func main() {
log.Fatal(err)
}
printArtifacts(artifacts)

fmt.Println("Scanning namespace 'default', resource 'deployment/orion'")

//trivy k8s --namespace default deployment/orion
artifact, err := trivyk8s.Namespace("default").GetArtifact(ctx, "deploy", "orion")
if err != nil {
log.Fatal(err)
}
printArtifact(artifact)
}

func printArtifacts(artifacts []*artifacts.Artifact) {
for _, artifact := range artifacts {
fmt.Printf(
"Name: %s, Kind: %s, Namespace: %s, Images: %v\n",
artifact.Name,
artifact.Kind,
artifact.Namespace,
artifact.Images,
)
printArtifact(artifact)
}
}

func printArtifact(artifact *artifacts.Artifact) {
fmt.Printf(
"Name: %s, Kind: %s, Namespace: %s, Images: %v\n",
artifact.Name,
artifact.Kind,
artifact.Namespace,
artifact.Images,
)
}
7 changes: 7 additions & 0 deletions pkg/k8s/k8s.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ type Cluster interface {
// GetGVRs returns cluster GroupVersionResource to query kubernetes, receives
// a boolean to determine if returns namespaced GVRs only or all GVRs
GetGVRs(bool) ([]schema.GroupVersionResource, error)
// GetGVR returns resource GroupVersionResource to query kubernetes, receives
// a string with the resource kind
GetGVR(string) (schema.GroupVersionResource, error)
}

type cluster struct {
Expand Down Expand Up @@ -118,6 +121,10 @@ func (c *cluster) GetGVRs(namespaced bool) ([]schema.GroupVersionResource, error
return grvs, nil
}

func (c *cluster) GetGVR(kind string) (schema.GroupVersionResource, error) {
return c.restMapper.ResourceFor(schema.GroupVersionResource{Resource: kind})
}

func getClusterResources() []string {
return []string{
ClusterRoles,
Expand Down
42 changes: 34 additions & 8 deletions pkg/trivyk8s/trivyk8s.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/aquasecurity/trivy-kubernetes/pkg/k8s"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/dynamic"

// import auth plugins
Expand All @@ -24,6 +25,8 @@ type TrivyK8S interface {
type ArtifactsK8S interface {
// ListArtifacts returns kubernetes scanable artifacts
ListArtifacts(context.Context) ([]*artifacts.Artifact, error)
// GetArtifact return kubernete scanable artifact
GetArtifact(context.Context, string, string) (*artifacts.Artifact, error)
}

type client struct {
Expand All @@ -47,20 +50,13 @@ func (c *client) ListArtifacts(ctx context.Context) ([]*artifacts.Artifact, erro
artifactList := make([]*artifacts.Artifact, 0)

namespaced := len(c.namespace) != 0

grvs, err := c.cluster.GetGVRs(namespaced)
if err != nil {
return nil, err
}

k8s := c.cluster.GetDynamicClient()
for _, gvr := range grvs {
var dclient dynamic.ResourceInterface
if namespaced {
dclient = k8s.Resource(gvr).Namespace(c.namespace)
} else {
dclient = k8s.Resource(gvr)
}
dclient := c.getDynamicClient(gvr)

resources, err := dclient.List(ctx, v1.ListOptions{})
if err != nil {
Expand All @@ -83,6 +79,36 @@ func (c *client) ListArtifacts(ctx context.Context) ([]*artifacts.Artifact, erro
return artifactList, nil
}

// GetArtifact return kubernetes scannable artifac.
func (c *client) GetArtifact(ctx context.Context, kind, name string) (*artifacts.Artifact, error) {
gvr, err := c.cluster.GetGVR(kind)
if err != nil {
return nil, err
}

dclient := c.getDynamicClient(gvr)
resource, err := dclient.Get(ctx, name, v1.GetOptions{})
if err != nil {
return nil, fmt.Errorf("failed getting resource for gvr: %v - %w", gvr, err)
}

artifact, err := artifacts.FromResource(*resource)
if err != nil {
return nil, err
}

return artifact, nil
}

func (c *client) getDynamicClient(gvr schema.GroupVersionResource) dynamic.ResourceInterface {
k8s := c.cluster.GetDynamicClient()
if len(c.namespace) == 0 {
return k8s.Resource(gvr)
} else {
return k8s.Resource(gvr).Namespace(c.namespace)
}
}

// ignore resources to avoid duplication,
// when a resource has an owner, the image/iac will be scanned on the owner itself
func ignoreResource(resource unstructured.Unstructured) bool {
Expand Down

0 comments on commit be8c01f

Please sign in to comment.