diff --git a/static/css/directives/repo-view/repo-panel-tags.css b/static/css/directives/repo-view/repo-panel-tags.css
index 267daf9e9..fe9a60385 100644
--- a/static/css/directives/repo-view/repo-panel-tags.css
+++ b/static/css/directives/repo-view/repo-panel-tags.css
@@ -85,6 +85,42 @@
margin-right: 2px;
}
+.repo-panel-tags-element .fa-flag {
+ cursor: pointer;
+}
+
+.repo-panel-tags-element .vuln-name {
+
+}
+
+.repo-panel-tags-element .vuln-description {
+ color: #ccc;
+ font-size: 10px;
+}
+
+.repo-panel-tags-element .fa-flag.None {
+ color: #00CA00;
+}
+
+.repo-panel-tags-element .fa-flag.Medium {
+ color: orange;
+}
+
+.repo-panel-tags-element .fa-flag.High {
+ color: red;
+}
+
+@keyframes flickerAnimation { /* flame pulses */
+ 0% { opacity:1; }
+ 50% { opacity:0; }
+ 100% { opacity:1; }
+}
+
+.repo-panel-tags-element .fa-flag.Critical {
+ color: red;
+ opacity:1;
+ animation: flickerAnimation 1s infinite;
+}
@media (max-width: 767px) {
.repo-panel-tags-element .tag-span {
diff --git a/static/directives/repo-view/repo-panel-tags.html b/static/directives/repo-view/repo-panel-tags.html
index 420f95f60..f5690d29b 100644
--- a/static/directives/repo-view/repo-panel-tags.html
+++ b/static/directives/repo-view/repo-panel-tags.html
@@ -86,6 +86,12 @@
style="min-width: 62px;">
Size
+
+
+
+
+ |
Unknown
|
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+ |
|
diff --git a/static/js/directives/repo-view/repo-panel-tags.js b/static/js/directives/repo-view/repo-panel-tags.js
index 95e365a56..fcc5d950e 100644
--- a/static/js/directives/repo-view/repo-panel-tags.js
+++ b/static/js/directives/repo-view/repo-panel-tags.js
@@ -18,7 +18,7 @@ angular.module('quay').directive('repoPanelTags', function () {
'getImages': '&getImages'
},
- controller: function($scope, $element, $filter, $location, ApiService, UIService) {
+ controller: function($scope, $element, $filter, $location, ApiService, UIService, VulnerabilityService) {
var orderBy = $filter('orderBy');
$scope.checkedTags = UIService.createCheckStateController([], 'name');
@@ -35,6 +35,7 @@ angular.module('quay').directive('repoPanelTags', function () {
$scope.tagActionHandler = null;
$scope.showingHistory = false;
$scope.tagsPerPage = 50;
+ $scope.tagVulnerabilities = {};
var setTagState = function() {
if (!$scope.repository || !$scope.selectedTags) { return; }
@@ -149,6 +150,53 @@ angular.module('quay').directive('repoPanelTags', function () {
setTagState();
});
+ $scope.loadTagVulnerabilities = function(tag, tagData) {
+ var params = {
+ 'tag': tag.name,
+ 'repository': $scope.repository.namespace + '/' + $scope.repository.name,
+ };
+
+ ApiService.getRepoTagVulnerabilities(null, params).then(function(resp) {
+ tagData.indexed = resp.security_indexed;
+ tagData.loading = false;
+
+ if (resp.security_indexed) {
+ tagData.hasVulnerabilities = !!resp.data.Vulnerabilities.length;
+ tagData.vulnerabilities = resp.data.Vulnerabilities;
+
+ var highest = null;
+ resp.data.Vulnerabilities.forEach(function(v) {
+ if (highest == null ||
+ VulnerabilityService.LEVELS[v.Priority].index < VulnerabilityService.LEVELS[highest.Priority].index) {
+ highest = v;
+ }
+ });
+
+ tagData.highestVulnerability = highest;
+ }
+ }, function() {
+ tagData.loading = false;
+ tagData.hasError = true;
+ });
+ };
+
+ $scope.getTagVulnerabilities = function(tag) {
+ if (!$scope.repository) {
+ return
+ }
+
+ var tagName = tag.name;
+ if (!$scope.tagVulnerabilities[tagName]) {
+ $scope.tagVulnerabilities[tagName] = {
+ 'loading': true
+ };
+
+ $scope.loadTagVulnerabilities(tag, $scope.tagVulnerabilities[tagName]);
+ }
+
+ return $scope.tagVulnerabilities[tagName];
+ };
+
$scope.clearSelectedTags = function() {
$scope.checkedTags.setChecked([]);
};
diff --git a/static/js/pages/image-view.js b/static/js/pages/image-view.js
index d8d3adc22..d848440f2 100644
--- a/static/js/pages/image-view.js
+++ b/static/js/pages/image-view.js
@@ -40,6 +40,19 @@
loadImage();
loadRepository();
+ $scope.downloadPackages = function() {
+ if ($scope.packagesResource) { return; }
+
+ var params = {
+ 'repository': namespace + '/' + name,
+ 'imageid': imageid
+ };
+
+ $scope.packagesResource = ApiService.getRepoImagePackagesAsResource(params).get(function(packages) {
+ $scope.packages = packages;
+ });
+ };
+
$scope.downloadChanges = function() {
if ($scope.changesResource) { return; }
diff --git a/static/partials/image-view.html b/static/partials/image-view.html
index 181938afc..3213ee7ac 100644
--- a/static/partials/image-view.html
+++ b/static/partials/image-view.html
@@ -25,6 +25,10 @@
tab-init="downloadChanges()">
+
+
+
@@ -53,6 +57,39 @@
+
+
+
+
+
Image Packages
+
+
This image has not been indexed yet
+
+ Please try again in a few minutes.
+
+
+
+
This image contains no recognized packages
+
+ Quay currently indexes Debian, Red Hat and Ubuntu packages.
+
+
+
+
+
+ Package Name |
+ Package Version |
+ OS |
+
+
+
+ {{ package.Name }} |
+ {{ package.Version }} |
+ {{ package.OS }} |
+
+
+
+