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 }