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  }