github.com/IBM-Cloud/bluemix-go@v0.0.0-20240423071914-9e96525baef4/api/container/registryv1/images_test.go (about) 1 package registryv1 2 3 import ( 4 "fmt" 5 "log" 6 "net/http" 7 "time" 8 9 ibmcloud "github.com/IBM-Cloud/bluemix-go" 10 "github.com/IBM-Cloud/bluemix-go/client" 11 ibmcloudHttp "github.com/IBM-Cloud/bluemix-go/http" 12 "github.com/IBM-Cloud/bluemix-go/session" 13 14 "github.com/onsi/gomega/ghttp" 15 16 . "github.com/onsi/ginkgo" 17 . "github.com/onsi/gomega" 18 ) 19 20 const ( 21 imageName = "registry.ng.bluemix.net/gpfs/sklm:2.7" 22 imageList = `[ 23 { 24 "Id": "sha256:1002cd429f26a9122df60be5f541a12f09f960b1bd092998f70594e4d8450be8", 25 "ParentId": "sha256:48b0f237fb3623275a4e96fddd0aec60067a6abee1b94725b292529124db8f86", 26 "DigestTags": { 27 "sha256:93390ca2d98a4da78a4496a77e14f751f30e95a8a7c2c172e89c1ca069ad2ef3": [ 28 "registry.ng.bluemix.net/gpfs/sklm:2.7" 29 ] 30 }, 31 "RepoTags": [ 32 "registry.ng.bluemix.net/gpfs/sklm:2.7" 33 ], 34 "RepoDigests": [ 35 "registry.ng.bluemix.net/gpfs/sklm@sha256:93390ca2d98a4da78a4496a77e14f751f30e95a8a7c2c172e89c1ca069ad2ef3" 36 ], 37 "Created": 1531320068, 38 "Size": 2257318704, 39 "VirtualSize": 2257318704, 40 "Labels": { 41 "architecture": "x86_64", 42 "authoritative-source-url": "registry.access.redhat.com" 43 }, 44 "Vulnerable": "true", 45 "VulnerabilityCount": 24, 46 "ConfigurationIssueCount": 0, 47 "IssueCount": 24, 48 "ExemptIssueCount": 0 49 } 50 ]` 51 imageInspect = `{ 52 "Id": "sha256:1002cd429f26a9122df60be5f541a12f09f960b1bd092998f70594e4d8450be8", 53 "Parent": "sha256:48b0f237fb3623275a4e96fddd0aec60067a6abee1b94725b292529124db8f86", 54 "Comment": "", 55 "Created": "2018-07-11T14:41:08.6719209Z", 56 "Container": "56b721a4dcad2778022df5b1b91e33a885579c29c7d00f7ce76065cd7dd35727", 57 "ContainerConfig": { 58 "Hostname": "36ee326478e1", 59 "Domainname": "", 60 "User": "", 61 "AttachStdin": false, 62 "AttachStdout": false, 63 "AttachStderr": false, 64 "ExposedPorts": { 65 "443/tcp": {}, 66 "5696/tcp": {}, 67 "80/tcp": {}, 68 "9083/tcp": {} 69 }, 70 "Tty": true, 71 "OpenStdin": false, 72 "StdinOnce": false, 73 "Env": [ 74 "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", 75 "container=oci" 76 ], 77 "Cmd": [ 78 "/bin/sh", 79 "-c", 80 "#(nop) ", 81 "CMD [\"/home/klmfcusr/run_sklm.sh\"]" 82 ], 83 "ArgsEscaped": true, 84 "Image": "sha256:48b0f237fb3623275a4e96fddd0aec60067a6abee1b94725b292529124db8f86", 85 "Volumes": { 86 "/home/sklmdb": {} 87 }, 88 "WorkingDir": "/home/klmfcusr", 89 "Entrypoint": null, 90 "OnBuild": null, 91 "Labels": { 92 "architecture": "x86_64", 93 "authoritative-source-url": "registry.access.redhat.com" 94 } 95 }, 96 "DockerVersion": "18.03.1-ce", 97 "Author": "", 98 "Config": { 99 "Hostname": "36ee326478e1", 100 "Domainname": "", 101 "User": "", 102 "AttachStdin": false, 103 "AttachStdout": false, 104 "AttachStderr": false, 105 "ExposedPorts": { 106 "443/tcp": {}, 107 "5696/tcp": {}, 108 "80/tcp": {}, 109 "9083/tcp": {} 110 }, 111 "Tty": true, 112 "OpenStdin": false, 113 "StdinOnce": false, 114 "Env": [ 115 "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", 116 "container=oci" 117 ], 118 "Cmd": [ 119 "/home/klmfcusr/run_sklm.sh" 120 ], 121 "ArgsEscaped": true, 122 "Image": "sha256:48b0f237fb3623275a4e96fddd0aec60067a6abee1b94725b292529124db8f86", 123 "Volumes": { 124 "/home/sklmdb": {} 125 }, 126 "WorkingDir": "/home/klmfcusr", 127 "Entrypoint": null, 128 "OnBuild": null, 129 "Labels": { 130 "architecture": "x86_64", 131 "authoritative-source-url": "registry.access.redhat.com" 132 } 133 }, 134 "Architecture": "amd64", 135 "Os": "linux", 136 "Size": 2257318704, 137 "VirtualSize": 2257318704, 138 "RootFS": { 139 "Type": "layers", 140 "Layers": [ 141 "sha256:f4fa6c253d2ff944ef6975be17cd0bb59896b386f9e2b737539400a37a68a80b", 142 "sha256:d6a4dd6ace1f76d1410e389c23e515a09eda880da05850b4343e2b39b6ced363", 143 "sha256:f98e45f3ca63148407d3800280a4faa7d6b6a7f98f39367e873d496d68293ffd", 144 "sha256:f98e45f3ca63148407d3800280a4faa7d6b6a7f98f39367e873d496d68293ffd", 145 "sha256:e1844b32012a6cb9c5974a10e903c1098e359b5b6b13bd3fc0dd331b1d455313", 146 "sha256:27a571001b44c6d3498e2e37b7310652c62e0ab5cc1f77d33807b83cac5449dc", 147 "sha256:55dc1ec7f17c842a4da60d7b1aaa976eb96eabd9f0e9a7376d0a473d1835472f" 148 ] 149 } 150 }` 151 imageVulnerability = `{ 152 "metadata": { 153 "namespace": "", 154 "complete": true, 155 "crawled_time": "2018-10-18T02:32:59Z", 156 "os_supported": true 157 }, 158 "summary": { 159 "malware": { 160 "compliant": true, 161 "reason": "" 162 }, 163 "compliance": { 164 "compliance_violations": 5, 165 "reason": "", 166 "compliant": false, 167 "total_compliance_rules": 0, 168 "execution_status": "" 169 }, 170 "secureconfig": { 171 "misconfigured": 0, 172 "correct_output": 0, 173 "total_output_docs": 0 174 }, 175 "vulnerability": { 176 "total_packages": 0, 177 "total_usns_for_distro": 0, 178 "vulnerable_usns": 0, 179 "vulnerable_packages": 10 180 } 181 }, 182 "detail": { 183 "compliance": [ 184 { 185 "reason": "File /etc/pam.d/common-password not found", 186 "compliant": false, 187 "description": "Minimum password length must be 8.", 188 "policy_mandated": false 189 } 190 ], 191 "vulnerability": [ 192 { 193 "package_name": "firefox 60.1.0-4.el7_5 has vulnerabilities", 194 "vulnerabilities": [ 195 { 196 "url": "https://access.redhat.com/errata/RHSA-2018:2692", 197 "cveid": [ 198 "CVE-2017-16541", 199 "CVE-2018-12376", 200 "CVE-2018-12377", 201 "CVE-2018-12378", 202 "CVE-2018-12379" 203 ], 204 "summary": "(RHSA-2018:2692) Critical: firefox security update" 205 } 206 ] 207 } 208 ] 209 } 210 }` 211 imageDelete = `{ "Untagged": "sha256:1002cd429f26a9122df60be5f541a12f09f960b1bd092998f70594e4d8450be8" }` 212 ) 213 214 var _ = Describe("Images", func() { 215 var server *ghttp.Server 216 AfterEach(func() { 217 server.Close() 218 }) 219 220 Describe("GetImages", func() { 221 Context("When get images is completed", func() { 222 BeforeEach(func() { 223 server = ghttp.NewServer() 224 server.AppendHandlers( 225 ghttp.CombineHandlers( 226 ghttp.VerifyRequest(http.MethodGet, "/api/v1/images"), 227 ghttp.RespondWith(http.StatusOK, imageList), 228 ), 229 ) 230 }) 231 232 It("should return get images results", func() { 233 params := GetImageRequest{ 234 IncludeIBM: false, 235 IncludePrivate: true, 236 Namespace: "", 237 Repository: "", 238 Vulnerabilities: true, 239 } 240 target := ImageTargetHeader{ 241 AccountID: "abc", 242 } 243 respptr, err := newImages(server.URL()).GetImages(params, target) 244 Expect(err).NotTo(HaveOccurred()) 245 Expect(respptr).NotTo(BeNil()) 246 resp := *respptr 247 Expect(resp).To(HaveLen(1)) 248 Expect(resp[0].ID).Should(Equal("sha256:1002cd429f26a9122df60be5f541a12f09f960b1bd092998f70594e4d8450be8")) 249 Expect(resp[0].ParentID).Should(Equal("sha256:48b0f237fb3623275a4e96fddd0aec60067a6abee1b94725b292529124db8f86")) 250 Expect(resp[0].DigestTags).Should(HaveKey("sha256:93390ca2d98a4da78a4496a77e14f751f30e95a8a7c2c172e89c1ca069ad2ef3")) 251 Expect(resp[0].DigestTags["sha256:93390ca2d98a4da78a4496a77e14f751f30e95a8a7c2c172e89c1ca069ad2ef3"]).To(HaveLen(1)) 252 Expect(resp[0].DigestTags["sha256:93390ca2d98a4da78a4496a77e14f751f30e95a8a7c2c172e89c1ca069ad2ef3"][0]).Should(Equal("registry.ng.bluemix.net/gpfs/sklm:2.7")) 253 Expect(resp[0].RepoTags).To(HaveLen(1)) 254 Expect(resp[0].RepoTags[0]).Should(Equal("registry.ng.bluemix.net/gpfs/sklm:2.7")) 255 Expect(resp[0].RepoDigests).To(HaveLen(1)) 256 Expect(resp[0].RepoDigests[0]).Should(Equal("registry.ng.bluemix.net/gpfs/sklm@sha256:93390ca2d98a4da78a4496a77e14f751f30e95a8a7c2c172e89c1ca069ad2ef3")) 257 Expect(resp[0].Created).Should(Equal(1531320068)) 258 Expect(resp[0].Size).Should(Equal(int64(2257318704))) 259 Expect(resp[0].VirtualSize).Should(Equal(int64(2257318704))) 260 Expect(resp[0].Labels).Should(HaveKey("architecture")) 261 Expect(resp[0].Labels["architecture"]).Should(Equal("x86_64")) 262 Expect(resp[0].Labels).Should(HaveKey("authoritative-source-url")) 263 Expect(resp[0].Labels["authoritative-source-url"]).Should(Equal("registry.access.redhat.com")) 264 Expect(resp[0].Vulnerable).Should(Equal("true")) 265 Expect(resp[0].VulnerabilityCount).Should(Equal(24)) 266 Expect(resp[0].ConfigurationIssueCount).Should(Equal(0)) 267 Expect(resp[0].IssueCount).Should(Equal(24)) 268 Expect(resp[0].ExemptIssueCount).Should(Equal(0)) 269 }) 270 }) 271 Context("When get image fails", func() { 272 BeforeEach(func() { 273 server = ghttp.NewServer() 274 server.SetAllowUnhandledRequests(true) 275 server.AppendHandlers( 276 ghttp.CombineHandlers( 277 ghttp.VerifyRequest(http.MethodGet, "/api/v1/images"), 278 ghttp.RespondWith(http.StatusInternalServerError, `Internal Error`), 279 ), 280 ) 281 }) 282 283 It("should return error when images are retrieved", func() { 284 params := GetImageRequest{ 285 IncludeIBM: false, 286 IncludePrivate: true, 287 Namespace: "", 288 Repository: "", 289 Vulnerabilities: true, 290 } 291 target := ImageTargetHeader{ 292 AccountID: "abc", 293 } 294 resp, err := newImages(server.URL()).GetImages(params, target) 295 Expect(err).To(HaveOccurred()) 296 Expect(resp).Should(BeNil()) 297 }) 298 }) 299 }) 300 301 Describe("InspectImage", func() { 302 Context("When Inspect Image is completed", func() { 303 304 BeforeEach(func() { 305 server = ghttp.NewServer() 306 server.AppendHandlers( 307 ghttp.CombineHandlers( 308 ghttp.VerifyRequest(http.MethodGet, fmt.Sprintf("/api/v1/images/%s/json", imageName)), 309 ghttp.RespondWith(http.StatusOK, imageInspect), 310 ), 311 ) 312 }) 313 314 It("should return image inspect results", func() { 315 target := ImageTargetHeader{ 316 AccountID: "abc", 317 } 318 respptr, err := newImages(server.URL()).InspectImage(imageName, target) 319 Expect(err).NotTo(HaveOccurred()) 320 Expect(respptr).NotTo(BeNil()) 321 resp := *respptr 322 Expect(resp.ID).Should(Equal("sha256:1002cd429f26a9122df60be5f541a12f09f960b1bd092998f70594e4d8450be8")) 323 Expect(resp.Parent).Should(Equal("sha256:48b0f237fb3623275a4e96fddd0aec60067a6abee1b94725b292529124db8f86")) 324 Expect(resp.Comment).Should(Equal("")) 325 time1, _ := time.Parse(time.RFC3339, "2018-07-11T14:41:08.6719209Z") 326 Expect(resp.Created).Should(Equal(time1)) 327 Expect(resp.Container).Should(Equal("56b721a4dcad2778022df5b1b91e33a885579c29c7d00f7ce76065cd7dd35727")) 328 Expect(resp.ContainerConfig.Hostname).Should(Equal("36ee326478e1")) 329 Expect(resp.ContainerConfig.Domainname).Should(Equal("")) 330 Expect(resp.ContainerConfig.User).Should(Equal("")) 331 Expect(resp.ContainerConfig.AttachStdin).Should(Equal(false)) 332 Expect(resp.ContainerConfig.AttachStdout).Should(Equal(false)) 333 Expect(resp.ContainerConfig.AttachStderr).Should(Equal(false)) 334 Expect(resp.ContainerConfig.ExposedPorts).Should(HaveKey("443/tcp")) 335 Expect(resp.ContainerConfig.ExposedPorts["443/tcp"]).To(HaveLen(0)) 336 Expect(resp.ContainerConfig.ExposedPorts).Should(HaveKey("5696/tcp")) 337 Expect(resp.ContainerConfig.ExposedPorts["5696/tcp"]).To(HaveLen(0)) 338 Expect(resp.ContainerConfig.ExposedPorts).Should(HaveKey("80/tcp")) 339 Expect(resp.ContainerConfig.ExposedPorts["80/tcp"]).To(HaveLen(0)) 340 Expect(resp.ContainerConfig.ExposedPorts).Should(HaveKey("9083/tcp")) 341 Expect(resp.ContainerConfig.ExposedPorts["9083/tcp"]).To(HaveLen(0)) 342 Expect(resp.ContainerConfig.Tty).Should(Equal(true)) 343 Expect(resp.ContainerConfig.OpenStdin).Should(Equal(false)) 344 Expect(resp.ContainerConfig.StdinOnce).Should(Equal(false)) 345 Expect(resp.ContainerConfig.Env).To(HaveLen(2)) 346 Expect(resp.ContainerConfig.Env[0]).Should(Equal("PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin")) 347 Expect(resp.ContainerConfig.Env[1]).Should(Equal("container=oci")) 348 Expect(resp.ContainerConfig.Cmd).To(HaveLen(4)) 349 Expect(resp.ContainerConfig.Cmd[0]).Should(Equal("/bin/sh")) 350 Expect(resp.ContainerConfig.Cmd[1]).Should(Equal("-c")) 351 Expect(resp.ContainerConfig.Cmd[2]).Should(Equal("#(nop) ")) 352 Expect(resp.ContainerConfig.Cmd[3]).Should(Equal("CMD [\"/home/klmfcusr/run_sklm.sh\"]")) 353 Expect(resp.ContainerConfig.ArgsEscaped).Should(Equal(true)) 354 Expect(resp.ContainerConfig.Image).Should(Equal("sha256:48b0f237fb3623275a4e96fddd0aec60067a6abee1b94725b292529124db8f86")) 355 Expect(resp.ContainerConfig.Volumes).Should(HaveKey("/home/sklmdb")) 356 Expect(resp.ContainerConfig.Volumes["/home/sklmdb"]).To(HaveLen(0)) 357 Expect(resp.ContainerConfig.WorkingDir).Should(Equal("/home/klmfcusr")) 358 Expect(resp.ContainerConfig.Entrypoint).To(HaveLen(0)) 359 Expect(resp.ContainerConfig.OnBuild).To(HaveLen(0)) 360 Expect(resp.ContainerConfig.Labels).Should(HaveKey("architecture")) 361 Expect(resp.ContainerConfig.Labels["architecture"]).Should(Equal("x86_64")) 362 Expect(resp.ContainerConfig.Labels).Should(HaveKey("authoritative-source-url")) 363 Expect(resp.ContainerConfig.Labels["authoritative-source-url"]).Should(Equal("registry.access.redhat.com")) 364 Expect(resp.DockerVersion).Should(Equal("18.03.1-ce")) 365 Expect(resp.Author).Should(Equal("")) 366 Expect(resp.Config.Hostname).Should(Equal("36ee326478e1")) 367 Expect(resp.Config.Domainname).Should(Equal("")) 368 Expect(resp.Config.User).Should(Equal("")) 369 Expect(resp.Config.AttachStdin).Should(Equal(false)) 370 Expect(resp.Config.AttachStdout).Should(Equal(false)) 371 Expect(resp.Config.AttachStderr).Should(Equal(false)) 372 Expect(resp.Config.ExposedPorts).Should(HaveKey("443/tcp")) 373 Expect(resp.Config.ExposedPorts["443/tcp"]).To(HaveLen(0)) 374 Expect(resp.Config.ExposedPorts).Should(HaveKey("5696/tcp")) 375 Expect(resp.Config.ExposedPorts["5696/tcp"]).To(HaveLen(0)) 376 Expect(resp.Config.ExposedPorts).Should(HaveKey("80/tcp")) 377 Expect(resp.Config.ExposedPorts["80/tcp"]).To(HaveLen(0)) 378 Expect(resp.Config.ExposedPorts).Should(HaveKey("9083/tcp")) 379 Expect(resp.Config.ExposedPorts["9083/tcp"]).To(HaveLen(0)) 380 Expect(resp.Config.Tty).Should(Equal(true)) 381 Expect(resp.Config.OpenStdin).Should(Equal(false)) 382 Expect(resp.Config.StdinOnce).Should(Equal(false)) 383 Expect(resp.Config.Env).To(HaveLen(2)) 384 Expect(resp.Config.Env[0]).Should(Equal("PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin")) 385 Expect(resp.Config.Env[1]).Should(Equal("container=oci")) 386 Expect(resp.Config.Cmd).To(HaveLen(1)) 387 Expect(resp.Config.Cmd[0]).Should(Equal("/home/klmfcusr/run_sklm.sh")) 388 Expect(resp.Config.ArgsEscaped).Should(Equal(true)) 389 Expect(resp.Config.Image).Should(Equal("sha256:48b0f237fb3623275a4e96fddd0aec60067a6abee1b94725b292529124db8f86")) 390 Expect(resp.Config.Volumes).Should(HaveKey("/home/sklmdb")) 391 Expect(resp.Config.Volumes["/home/sklmdb"]).To(HaveLen(0)) 392 Expect(resp.Config.WorkingDir).Should(Equal("/home/klmfcusr")) 393 Expect(resp.Config.Entrypoint).To(HaveLen(0)) 394 Expect(resp.Config.OnBuild).To(HaveLen(0)) 395 Expect(resp.Config.Labels).Should(HaveKey("architecture")) 396 Expect(resp.Config.Labels["architecture"]).Should(Equal("x86_64")) 397 Expect(resp.Config.Labels).Should(HaveKey("authoritative-source-url")) 398 Expect(resp.Config.Labels["authoritative-source-url"]).Should(Equal("registry.access.redhat.com")) 399 Expect(resp.Architecture).Should(Equal("amd64")) 400 Expect(resp.Os).Should(Equal("linux")) 401 Expect(resp.Size).Should(Equal(int64(2257318704))) 402 Expect(resp.VirtualSize).Should(Equal(int64(2257318704))) 403 Expect(resp.RootFS.Type).Should(Equal("layers")) 404 Expect(resp.RootFS.Layers).To(HaveLen(7)) 405 Expect(resp.RootFS.Layers[0]).Should(Equal("sha256:f4fa6c253d2ff944ef6975be17cd0bb59896b386f9e2b737539400a37a68a80b")) 406 Expect(resp.RootFS.Layers[1]).Should(Equal("sha256:d6a4dd6ace1f76d1410e389c23e515a09eda880da05850b4343e2b39b6ced363")) 407 Expect(resp.RootFS.Layers[2]).Should(Equal("sha256:f98e45f3ca63148407d3800280a4faa7d6b6a7f98f39367e873d496d68293ffd")) 408 Expect(resp.RootFS.Layers[3]).Should(Equal("sha256:f98e45f3ca63148407d3800280a4faa7d6b6a7f98f39367e873d496d68293ffd")) 409 Expect(resp.RootFS.Layers[4]).Should(Equal("sha256:e1844b32012a6cb9c5974a10e903c1098e359b5b6b13bd3fc0dd331b1d455313")) 410 Expect(resp.RootFS.Layers[5]).Should(Equal("sha256:27a571001b44c6d3498e2e37b7310652c62e0ab5cc1f77d33807b83cac5449dc")) 411 Expect(resp.RootFS.Layers[6]).Should(Equal("sha256:55dc1ec7f17c842a4da60d7b1aaa976eb96eabd9f0e9a7376d0a473d1835472f")) 412 }) 413 }) 414 Context("When inspect image fails", func() { 415 BeforeEach(func() { 416 server = ghttp.NewServer() 417 server.SetAllowUnhandledRequests(true) 418 server.AppendHandlers( 419 ghttp.CombineHandlers( 420 ghttp.VerifyRequest(http.MethodGet, fmt.Sprintf("/api/v1/images/%s/json", imageName)), 421 ghttp.RespondWith(http.StatusInternalServerError, `Internal Error`), 422 ), 423 ) 424 }) 425 426 It("should return error when image is inspected", func() { 427 target := ImageTargetHeader{ 428 AccountID: "abc", 429 } 430 resp, err := newImages(server.URL()).InspectImage(imageName, target) 431 Expect(err).To(HaveOccurred()) 432 Expect(resp).Should(BeNil()) 433 }) 434 }) 435 }) 436 437 Describe("ImageVulnerabilities", func() { 438 Context("When Scan Image is completed", func() { 439 440 BeforeEach(func() { 441 server = ghttp.NewServer() 442 server.AppendHandlers( 443 ghttp.CombineHandlers( 444 ghttp.VerifyRequest(http.MethodGet, fmt.Sprintf("/api/v1/images/%s/vulnerabilities", imageName)), 445 ghttp.RespondWith(http.StatusOK, imageVulnerability), 446 ), 447 ) 448 }) 449 450 It("should return scan images results", func() { 451 param := ImageVulnerabilitiesRequest{ 452 Advisory: true, 453 All: true, 454 } 455 target := ImageTargetHeader{ 456 AccountID: "abc", 457 } 458 respptr, err := newImages(server.URL()).ImageVulnerabilities(imageName, param, target) 459 460 Expect(err).NotTo(HaveOccurred()) 461 Expect(respptr).NotTo(BeNil()) 462 resp := *respptr 463 Expect(resp.Metadata.Namespace).Should(Equal("")) 464 Expect(resp.Metadata.Complete).Should(Equal(true)) 465 time1, _ := time.Parse(time.RFC3339, "2018-10-18T02:32:59Z") 466 Expect(resp.Metadata.CrawledTime).Should(Equal(time1)) 467 Expect(resp.Metadata.OsSupported).Should(Equal(true)) 468 Expect(resp.Summary.Malware.Compliant).Should(Equal(true)) 469 Expect(resp.Summary.Malware.Reason).Should(Equal("")) 470 Expect(resp.Summary.Compliance.ComplianceViolations).Should(Equal(5)) 471 Expect(resp.Summary.Compliance.Reason).Should(Equal("")) 472 Expect(resp.Summary.Compliance.Compliant).Should(Equal(false)) 473 Expect(resp.Summary.Compliance.TotalComplianceRules).Should(Equal(0)) 474 Expect(resp.Summary.Compliance.ExecutionStatus).Should(Equal("")) 475 Expect(resp.Summary.Secureconfig.Misconfigured).Should(Equal(0)) 476 Expect(resp.Summary.Secureconfig.CorrectOutput).Should(Equal(0)) 477 Expect(resp.Summary.Secureconfig.TotalOutputDocs).Should(Equal(0)) 478 Expect(resp.Summary.Vulnerability.TotalPackages).Should(Equal(0)) 479 Expect(resp.Summary.Vulnerability.TotalUsnsForDistro).Should(Equal(0)) 480 Expect(resp.Summary.Vulnerability.VulnerableUsns).Should(Equal(0)) 481 Expect(resp.Summary.Vulnerability.VulnerablePackages).Should(Equal(10)) 482 Expect(resp.Detail.Compliance).To(HaveLen(1)) 483 Expect(resp.Detail.Compliance[0].Reason).Should(Equal("File /etc/pam.d/common-password not found")) 484 Expect(resp.Detail.Compliance[0].Compliant).Should(Equal(false)) 485 Expect(resp.Detail.Compliance[0].Description).Should(Equal("Minimum password length must be 8.")) 486 Expect(resp.Detail.Compliance[0].PolicyMandated).Should(Equal(false)) 487 Expect(resp.Detail.Compliance).To(HaveLen(1)) 488 Expect(resp.Detail.Vulnerability[0].PackageName).Should(Equal("firefox 60.1.0-4.el7_5 has vulnerabilities")) 489 Expect(resp.Detail.Vulnerability[0].Vulnerabilities).To(HaveLen(1)) 490 Expect(resp.Detail.Vulnerability[0].Vulnerabilities[0].URL).Should(Equal("https://access.redhat.com/errata/RHSA-2018:2692")) 491 Expect(resp.Detail.Vulnerability[0].Vulnerabilities[0].Cveid).To(HaveLen(5)) 492 Expect(resp.Detail.Vulnerability[0].Vulnerabilities[0].Cveid[0]).Should(Equal("CVE-2017-16541")) 493 Expect(resp.Detail.Vulnerability[0].Vulnerabilities[0].Cveid[1]).Should(Equal("CVE-2018-12376")) 494 Expect(resp.Detail.Vulnerability[0].Vulnerabilities[0].Cveid[2]).Should(Equal("CVE-2018-12377")) 495 Expect(resp.Detail.Vulnerability[0].Vulnerabilities[0].Cveid[3]).Should(Equal("CVE-2018-12378")) 496 Expect(resp.Detail.Vulnerability[0].Vulnerabilities[0].Cveid[4]).Should(Equal("CVE-2018-12379")) 497 Expect(resp.Detail.Vulnerability[0].Vulnerabilities[0].Summary).Should(Equal("(RHSA-2018:2692) Critical: firefox security update")) 498 }) 499 }) 500 Context("When scan image fails", func() { 501 BeforeEach(func() { 502 server = ghttp.NewServer() 503 server.SetAllowUnhandledRequests(true) 504 server.AppendHandlers( 505 ghttp.CombineHandlers( 506 ghttp.VerifyRequest(http.MethodGet, fmt.Sprintf("/api/v1/images/%s/vulnerabilities", imageName)), 507 ghttp.RespondWith(http.StatusInternalServerError, `Internal Error`), 508 ), 509 ) 510 }) 511 512 It("should return error when image is scanned", func() { 513 param := ImageVulnerabilitiesRequest{ 514 Advisory: true, 515 All: true, 516 } 517 target := ImageTargetHeader{ 518 AccountID: "abc", 519 } 520 resp, err := newImages(server.URL()).ImageVulnerabilities(imageName, param, target) 521 Expect(err).To(HaveOccurred()) 522 Expect(resp).Should(BeNil()) 523 }) 524 }) 525 }) 526 527 Describe("DeleteImage", func() { 528 Context("When Delete image is completed", func() { 529 530 BeforeEach(func() { 531 server = ghttp.NewServer() 532 server.AppendHandlers( 533 ghttp.CombineHandlers( 534 ghttp.VerifyRequest(http.MethodDelete, fmt.Sprintf("/api/v1/images/%s", imageName)), 535 ghttp.RespondWith(http.StatusOK, imageDelete), 536 ), 537 ) 538 }) 539 540 It("should return delete images results", func() { 541 target := ImageTargetHeader{ 542 AccountID: "abc", 543 } 544 respptr, err := newImages(server.URL()).DeleteImage(imageName, target) 545 546 Expect(err).NotTo(HaveOccurred()) 547 resp := *respptr 548 Expect(resp.Untagged).Should(Equal("sha256:1002cd429f26a9122df60be5f541a12f09f960b1bd092998f70594e4d8450be8")) 549 }) 550 }) 551 Context("When delete image fails", func() { 552 BeforeEach(func() { 553 server = ghttp.NewServer() 554 server.SetAllowUnhandledRequests(true) 555 server.AppendHandlers( 556 ghttp.CombineHandlers( 557 ghttp.VerifyRequest(http.MethodDelete, fmt.Sprintf("/api/v1/images/%s", imageName)), 558 ghttp.RespondWith(http.StatusInternalServerError, `Internal Error`), 559 ), 560 ) 561 }) 562 563 It("should return error when image is deleted", func() { 564 target := ImageTargetHeader{ 565 AccountID: "abc", 566 } 567 resp, err := newImages(server.URL()).DeleteImage(imageName, target) 568 Expect(err).To(HaveOccurred()) 569 Expect(resp).Should(BeNil()) 570 }) 571 }) 572 }) 573 }) 574 575 func newImages(url string) Images { 576 577 sess, err := session.New() 578 if err != nil { 579 log.Fatal(err) 580 } 581 conf := sess.Config.Copy() 582 conf.HTTPClient = ibmcloudHttp.NewHTTPClient(conf) 583 conf.Endpoint = &url 584 585 client := client.Client{ 586 Config: conf, 587 ServiceName: ibmcloud.ContainerRegistryService, 588 } 589 return newImageAPI(&client) 590 }