github.com/devseccon/trivy@v0.47.1-0.20231123133102-bd902a0bd996/pkg/sbom/cyclonedx/core/cyclonedx_test.go (about)

     1  package core_test
     2  
     3  import (
     4  	"testing"
     5  	"time"
     6  
     7  	cdx "github.com/CycloneDX/cyclonedx-go"
     8  	"github.com/package-url/packageurl-go"
     9  	"github.com/stretchr/testify/assert"
    10  
    11  	"github.com/devseccon/trivy/pkg/clock"
    12  	"github.com/devseccon/trivy/pkg/digest"
    13  	"github.com/devseccon/trivy/pkg/purl"
    14  	"github.com/devseccon/trivy/pkg/sbom/cyclonedx/core"
    15  	"github.com/devseccon/trivy/pkg/uuid"
    16  )
    17  
    18  func TestMarshaler_CoreComponent(t *testing.T) {
    19  	noDepRefs := []string{}
    20  	tests := []struct {
    21  		name          string
    22  		rootComponent *core.Component
    23  		want          *cdx.BOM
    24  	}{
    25  		{
    26  			name: "marshal CoreComponent",
    27  			rootComponent: &core.Component{
    28  				Type: cdx.ComponentTypeContainer,
    29  				Name: "test-cluster",
    30  				Components: []*core.Component{
    31  					{
    32  						Type: cdx.ComponentTypeApplication,
    33  						Name: "kube-apiserver-kind-control-plane",
    34  						Properties: []core.Property{
    35  							{
    36  								Name:  "control_plane_components",
    37  								Value: "kube-apiserver",
    38  							},
    39  						},
    40  						Components: []*core.Component{
    41  							{
    42  								Type:    cdx.ComponentTypeContainer,
    43  								Name:    "k8s.gcr.io/kube-apiserver",
    44  								Version: "sha256:18e61c783b41758dd391ab901366ec3546b26fae00eef7e223d1f94da808e02f",
    45  								PackageURL: &purl.PackageURL{
    46  									PackageURL: packageurl.PackageURL{
    47  										Type:    "oci",
    48  										Name:    "kube-apiserver",
    49  										Version: "sha256:18e61c783b41758dd391ab901366ec3546b26fae00eef7e223d1f94da808e02f",
    50  										Qualifiers: packageurl.Qualifiers{
    51  											{
    52  												Key:   "repository_url",
    53  												Value: "k8s.gcr.io/kube-apiserver",
    54  											},
    55  											{
    56  												Key: "arch",
    57  											},
    58  										},
    59  									},
    60  								},
    61  								Hashes: []digest.Digest{"sha256:18e61c783b41758dd391ab901366ec3546b26fae00eef7e223d1f94da808e02f"},
    62  								Properties: []core.Property{
    63  									{
    64  										Name:  "PkgID",
    65  										Value: "k8s.gcr.io/kube-apiserver:1.21.1",
    66  									},
    67  									{
    68  										Name:  "PkgType",
    69  										Value: "oci",
    70  									},
    71  								},
    72  							},
    73  						},
    74  					},
    75  					{
    76  						Type: cdx.ComponentTypeContainer,
    77  						Name: "kind-control-plane",
    78  						Properties: []core.Property{
    79  							{
    80  								Name:  "architecture",
    81  								Value: "arm64",
    82  							},
    83  							{
    84  								Name:  "host_name",
    85  								Value: "kind-control-plane",
    86  							},
    87  							{
    88  								Name:  "kernel_version",
    89  								Value: "6.2.13-300.fc38.aarch64",
    90  							},
    91  							{
    92  								Name:  "node_role",
    93  								Value: "master",
    94  							},
    95  							{
    96  								Name:  "operating_system",
    97  								Value: "linux",
    98  							},
    99  						},
   100  						Components: []*core.Component{
   101  							{
   102  								Type:    cdx.ComponentTypeOS,
   103  								Name:    "ubuntu",
   104  								Version: "21.04",
   105  								Properties: []core.Property{
   106  									{
   107  										Name:  "Class",
   108  										Value: "os-pkgs",
   109  									},
   110  									{
   111  										Name:  "Type",
   112  										Value: "ubuntu",
   113  									},
   114  								},
   115  							},
   116  							{
   117  								Type: cdx.ComponentTypeApplication,
   118  								Name: "node-core-components",
   119  								Properties: []core.Property{
   120  									{
   121  										Name:  "Class",
   122  										Value: "lang-pkgs",
   123  									},
   124  									{
   125  										Name:  "Type",
   126  										Value: "golang",
   127  									},
   128  								},
   129  								Components: []*core.Component{
   130  									{
   131  										Type:    cdx.ComponentTypeLibrary,
   132  										Name:    "kubelet",
   133  										Version: "1.21.1",
   134  										Properties: []core.Property{
   135  											{
   136  												Name:  "PkgType",
   137  												Value: "golang",
   138  											},
   139  										},
   140  										PackageURL: &purl.PackageURL{
   141  											PackageURL: packageurl.PackageURL{
   142  												Type:       "golang",
   143  												Name:       "kubelet",
   144  												Version:    "1.21.1",
   145  												Qualifiers: packageurl.Qualifiers{},
   146  											},
   147  										},
   148  									},
   149  									{
   150  										Type:    cdx.ComponentTypeLibrary,
   151  										Name:    "containerd",
   152  										Version: "1.5.2",
   153  										Properties: []core.Property{
   154  											{
   155  												Name:  "PkgType",
   156  												Value: "golang",
   157  											},
   158  										},
   159  										PackageURL: &purl.PackageURL{
   160  											PackageURL: packageurl.PackageURL{
   161  												Type:       "golang",
   162  												Name:       "containerd",
   163  												Version:    "1.5.2",
   164  												Qualifiers: packageurl.Qualifiers{},
   165  											},
   166  										},
   167  									},
   168  								},
   169  							},
   170  						},
   171  					},
   172  				},
   173  			},
   174  
   175  			want: &cdx.BOM{
   176  				XMLNS:        "http://cyclonedx.org/schema/bom/1.5",
   177  				BOMFormat:    "CycloneDX",
   178  				SerialNumber: "urn:uuid:3ff14136-e09f-4df9-80ea-000000000001",
   179  				JSONSchema:   "http://cyclonedx.org/schema/bom-1.5.schema.json",
   180  				SpecVersion:  cdx.SpecVersion1_5,
   181  				Version:      1,
   182  				Metadata: &cdx.Metadata{
   183  					Timestamp: "2021-08-25T12:20:30+00:00",
   184  					Tools: &[]cdx.Tool{
   185  						{
   186  							Name:    "trivy",
   187  							Vendor:  "aquasecurity",
   188  							Version: "dev",
   189  						},
   190  					},
   191  					Component: &cdx.Component{
   192  						BOMRef:     "3ff14136-e09f-4df9-80ea-000000000002",
   193  						Name:       "test-cluster",
   194  						Properties: &[]cdx.Property{},
   195  						Type:       cdx.ComponentTypeContainer,
   196  					},
   197  				},
   198  				Vulnerabilities: &[]cdx.Vulnerability{},
   199  				Components: &[]cdx.Component{
   200  					{
   201  						BOMRef: "3ff14136-e09f-4df9-80ea-000000000003",
   202  						Type:   "application",
   203  						Name:   "kube-apiserver-kind-control-plane",
   204  						Properties: &[]cdx.Property{
   205  							{
   206  								Name:  "aquasecurity:trivy:control_plane_components",
   207  								Value: "kube-apiserver",
   208  							},
   209  						},
   210  					},
   211  					{
   212  						BOMRef: "3ff14136-e09f-4df9-80ea-000000000004",
   213  						Type:   "container",
   214  						Name:   "kind-control-plane",
   215  						Properties: &[]cdx.Property{
   216  							{
   217  								Name:  "aquasecurity:trivy:architecture",
   218  								Value: "arm64",
   219  							},
   220  							{
   221  								Name:  "aquasecurity:trivy:host_name",
   222  								Value: "kind-control-plane",
   223  							},
   224  							{
   225  								Name:  "aquasecurity:trivy:kernel_version",
   226  								Value: "6.2.13-300.fc38.aarch64",
   227  							},
   228  							{
   229  								Name:  "aquasecurity:trivy:node_role",
   230  								Value: "master",
   231  							},
   232  							{
   233  								Name:  "aquasecurity:trivy:operating_system",
   234  								Value: "linux",
   235  							},
   236  						},
   237  					},
   238  					{
   239  						BOMRef:  "3ff14136-e09f-4df9-80ea-000000000005",
   240  						Type:    "operating-system",
   241  						Name:    "ubuntu",
   242  						Version: "21.04",
   243  						Properties: &[]cdx.Property{
   244  							{
   245  								Name:  "aquasecurity:trivy:Class",
   246  								Value: "os-pkgs",
   247  							},
   248  							{
   249  								Name:  "aquasecurity:trivy:Type",
   250  								Value: "ubuntu",
   251  							},
   252  						},
   253  					},
   254  					{
   255  						BOMRef: "3ff14136-e09f-4df9-80ea-000000000006",
   256  						Type:   "application",
   257  						Name:   "node-core-components",
   258  						Properties: &[]cdx.Property{
   259  							{
   260  								Name:  "aquasecurity:trivy:Class",
   261  								Value: "lang-pkgs",
   262  							},
   263  							{
   264  								Name:  "aquasecurity:trivy:Type",
   265  								Value: "golang",
   266  							},
   267  						},
   268  					},
   269  					{
   270  						BOMRef:     "pkg:golang/containerd@1.5.2",
   271  						Type:       "library",
   272  						Name:       "containerd",
   273  						Version:    "1.5.2",
   274  						PackageURL: "pkg:golang/containerd@1.5.2",
   275  						Properties: &[]cdx.Property{
   276  							{
   277  								Name:  "aquasecurity:trivy:PkgType",
   278  								Value: "golang",
   279  							},
   280  						},
   281  					},
   282  					{
   283  						BOMRef:     "pkg:golang/kubelet@1.21.1",
   284  						Type:       "library",
   285  						Name:       "kubelet",
   286  						Version:    "1.21.1",
   287  						PackageURL: "pkg:golang/kubelet@1.21.1",
   288  						Properties: &[]cdx.Property{
   289  							{
   290  								Name:  "aquasecurity:trivy:PkgType",
   291  								Value: "golang",
   292  							},
   293  						},
   294  					},
   295  					{
   296  						BOMRef: "pkg:oci/kube-apiserver@sha256%3A18e61c783b41758dd391ab901366ec3546b26fae00eef7e223d1f94da808e02f?arch=&repository_url=k8s.gcr.io%2Fkube-apiserver",
   297  						Hashes: &[]cdx.Hash{
   298  							{
   299  								Algorithm: "SHA-256",
   300  								Value:     "18e61c783b41758dd391ab901366ec3546b26fae00eef7e223d1f94da808e02f",
   301  							},
   302  						},
   303  						Type:       "container",
   304  						Name:       "k8s.gcr.io/kube-apiserver",
   305  						Version:    "sha256:18e61c783b41758dd391ab901366ec3546b26fae00eef7e223d1f94da808e02f",
   306  						PackageURL: "pkg:oci/kube-apiserver@sha256%3A18e61c783b41758dd391ab901366ec3546b26fae00eef7e223d1f94da808e02f?arch=&repository_url=k8s.gcr.io%2Fkube-apiserver",
   307  						Properties: &[]cdx.Property{
   308  							{
   309  								Name:  "aquasecurity:trivy:PkgID",
   310  								Value: "k8s.gcr.io/kube-apiserver:1.21.1",
   311  							},
   312  							{
   313  								Name:  "aquasecurity:trivy:PkgType",
   314  								Value: "oci",
   315  							},
   316  						},
   317  					},
   318  				},
   319  				Dependencies: &[]cdx.Dependency{
   320  					{
   321  						Ref: "3ff14136-e09f-4df9-80ea-000000000002",
   322  						Dependencies: &[]string{
   323  							"3ff14136-e09f-4df9-80ea-000000000003",
   324  							"3ff14136-e09f-4df9-80ea-000000000004",
   325  						},
   326  					},
   327  					{
   328  						Ref:          "3ff14136-e09f-4df9-80ea-000000000003",
   329  						Dependencies: &[]string{"pkg:oci/kube-apiserver@sha256%3A18e61c783b41758dd391ab901366ec3546b26fae00eef7e223d1f94da808e02f?arch=&repository_url=k8s.gcr.io%2Fkube-apiserver"},
   330  					},
   331  					{
   332  						Ref: "3ff14136-e09f-4df9-80ea-000000000004",
   333  						Dependencies: &[]string{
   334  							"3ff14136-e09f-4df9-80ea-000000000005",
   335  							"3ff14136-e09f-4df9-80ea-000000000006",
   336  						},
   337  					},
   338  					{
   339  						Ref:          "3ff14136-e09f-4df9-80ea-000000000005",
   340  						Dependencies: &noDepRefs,
   341  					},
   342  					{
   343  						Ref: "3ff14136-e09f-4df9-80ea-000000000006",
   344  						Dependencies: &[]string{
   345  							"pkg:golang/containerd@1.5.2",
   346  							"pkg:golang/kubelet@1.21.1",
   347  						},
   348  					},
   349  					{
   350  						Ref:          "pkg:golang/containerd@1.5.2",
   351  						Dependencies: &noDepRefs,
   352  					},
   353  					{
   354  						Ref:          "pkg:golang/kubelet@1.21.1",
   355  						Dependencies: &noDepRefs,
   356  					},
   357  					{
   358  						Ref:          "pkg:oci/kube-apiserver@sha256%3A18e61c783b41758dd391ab901366ec3546b26fae00eef7e223d1f94da808e02f?arch=&repository_url=k8s.gcr.io%2Fkube-apiserver",
   359  						Dependencies: &noDepRefs,
   360  					},
   361  				},
   362  			},
   363  		},
   364  	}
   365  
   366  	for _, tt := range tests {
   367  		t.Run(tt.name, func(t *testing.T) {
   368  			clock.SetFakeTime(t, time.Date(2021, 8, 25, 12, 20, 30, 5, time.UTC))
   369  			uuid.SetFakeUUID(t, "3ff14136-e09f-4df9-80ea-%012d")
   370  
   371  			marshaler := core.NewCycloneDX("dev")
   372  			got := marshaler.Marshal(tt.rootComponent)
   373  			assert.Equal(t, tt.want, got)
   374  		})
   375  	}
   376  }