Skip to content
This repository was archived by the owner on Jul 7, 2021. It is now read-only.

Commit 489be1a

Browse files
author
Tom McKay
committed
adds image signatures
1 parent 4951f20 commit 489be1a

File tree

10 files changed

+391
-43
lines changed

10 files changed

+391
-43
lines changed

dist/image-widgets.js

Lines changed: 233 additions & 32 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/image-widgets.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

images.js

Lines changed: 105 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,8 @@ angular.module('registryUI.images', [
167167
.directive('registryImageBody', [
168168
'imageLayers',
169169
'imageDockerConfig',
170-
function(imageLayers, imageDockerConfig) {
170+
'imageSignatures',
171+
function(imageLayers, imageDockerConfig, imageSignatures) {
171172
return {
172173
restrict: 'E',
173174
scope: {
@@ -180,6 +181,7 @@ angular.module('registryUI.images', [
180181
scope.layers = imageLayers(image);
181182
scope.config = imageDockerConfig(image);
182183
scope.labels = scope.config.Labels;
184+
scope.signatures = imageSignatures(image);
183185
if (angular.equals({ }, scope.labels))
184186
scope.labels = null;
185187
});
@@ -234,6 +236,37 @@ angular.module('registryUI.images', [
234236
}
235237
])
236238

239+
.directive('registryImageSignatures', [
240+
'imageSignatures',
241+
function(imageSignatures) {
242+
return {
243+
restrict: 'E',
244+
scope: {
245+
image: '=',
246+
},
247+
templateUrl: 'registry-image-widgets/views/image-signatures.html',
248+
link: function(scope, element, attrs) {
249+
scope.signatureDetails = function signatureDetails(signature) {
250+
var result = "";
251+
if (signature.conditions) {
252+
var condition = signature.conditions.find(function (condition) {
253+
return condition.type === "Trusted";
254+
});
255+
if (condition !== undefined) {
256+
result = condition.reason + " / " + condition.message;
257+
}
258+
}
259+
return result;
260+
};
261+
262+
scope.$watch("image", function(image) {
263+
scope.signatures = imageSignatures(image);
264+
});
265+
}
266+
};
267+
}
268+
])
269+
237270
.directive('registryImageMeta', [
238271
'imageDockerConfig',
239272
function(imageDockerConfig) {
@@ -312,18 +345,85 @@ angular.module('registryUI.images', [
312345
}
313346
])
314347

348+
.factory('imageSignatures', [
349+
'WeakMap',
350+
function(WeakMap) {
351+
var weak = new WeakMap();
352+
353+
return function(image) {
354+
if (!image)
355+
return [];
356+
var signatures = weak.get(image);
357+
358+
359+
var signatureStatus = function(signature) {
360+
var trusted = "Unverified";
361+
if (signature.conditions) {
362+
var condition = signature.conditions.find(function (condition) {
363+
return condition.type === "Trusted";
364+
});
365+
if (condition !== undefined) {
366+
trusted = "Verified";
367+
} else {
368+
// Failed info not available
369+
// https://github.com/openshift/origin/issues/16301
370+
trusted = "Failed verification";
371+
}
372+
}
373+
return trusted;
374+
};
375+
376+
if (!signatures && image.signatures) {
377+
signatures = [];
378+
image.signatures.forEach(function(signature) {
379+
signature.verified = signatureStatus(signature);
380+
signatures.push(signature);
381+
});
382+
weak.set(image, signatures);
383+
}
384+
385+
return signatures || [];
386+
};
387+
}
388+
])
389+
315390
.factory('registryImageListingFunc', [
316391
'imagestreamTags',
317392
'imagestreamTagFromName',
393+
'imageSignatures',
318394
'$location',
319-
function(imagestreamTags, imagestreamTagFromName, $location) {
395+
function(imagestreamTags, imagestreamTagFromName, imageSignatures, $location) {
320396
return function(scope, element, attrs) {
321397
scope.imagestreamTags = imagestreamTags;
322398
scope.imagestreamPath = scope.imagestreamFunc();
323399
scope.imageByTag = scope.imageByTagFunc();
324400
scope.imageTagNames = scope.imageTagNamesFunc();
325401
scope.sharedImages = scope.sharedImagesFunc();
326402
scope.imagestreamTagFromName = imagestreamTagFromName;
403+
scope.imageSignatures = imageSignatures;
404+
405+
scope.overallVerification = function overallVerification(tag) {
406+
var image, signature, signatures;
407+
var overall = "Unverified";
408+
409+
image = scope.imageByTag(tag.status);
410+
signatures = scope.imageSignatures(image);
411+
412+
if (signatures.length === 0) {
413+
return "Unsigned";
414+
} else {
415+
signatures.forEach(function(signature) {
416+
var status = signature.verified;
417+
if (status === "Failed verification" || overall === "Failed verification" || overall === undefined) {
418+
overall = status;
419+
} else if (status !== "Failed verification") {
420+
overall = status;
421+
}
422+
});
423+
}
424+
425+
return overall;
426+
};
327427

328428
/* Called when someone clicks on a row */
329429
scope.imagestreamActivate = function imagestreamActivate(imagestream, tag, ev) {
@@ -410,7 +510,8 @@ angular.module('registryUI.images', [
410510
.directive('registryImagePanel', [
411511
'imageDockerConfig',
412512
'imageLayers',
413-
function(imageDockerConfig, imageLayers) {
513+
'imageSignatures',
514+
function(imageDockerConfig, imageLayers, imageSignatures) {
414515
return {
415516
restrict: 'E',
416517
transclude: true,
@@ -435,6 +536,7 @@ angular.module('registryUI.images', [
435536
scope.layers = imageLayers(scope.image);
436537
scope.config = imageDockerConfig(scope.image);
437538
scope.labels = scope.config.Labels;
539+
scope.signatures = imageSignatures(scope.image);
438540
if (scope.imageTagNames)
439541
scope.names = scope.imageTagNames(scope.image);
440542
}

images.less

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,10 @@ registry-image-listing table.listing-ct {
113113
}
114114
}
115115

116+
td.image-signature {
117+
margin-right: 5px;
118+
}
119+
116120
tbody.open .listing-ct-panel .listing-ct-body {
117121
border-right: 1px solid #ccc;
118122
}

views/image-body.html

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
<dt ng-if-start="config.Image" translate>Identifier</dt>
2525
<dd class="indentifier" ng-if-end><tt>{{ config.Image }}</tt></dd>
2626
</dl>
27-
2827
<dl class="registry-image-tags" ng-if="names">
2928
<dt translate>Tags</dt>
3029
<dd><span class="registry-image-tag" ng-repeat="name in names">{{name}}</span>&nbsp;</dd>

views/image-listing.html

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
<th translate="yes" width="20%">Tag</th>
66
<th translate="yes">From</th>
77
<th translate="yes">Identifier</th>
8+
<th translate="yes">Signatures</th>
89
<th translate="yes">Last Updated</th>
910
</tr>
1011
</thead>
@@ -54,6 +55,17 @@
5455
</div>
5556
</div>
5657
</td>
58+
<td class="image-signature">
59+
<div>
60+
<span class="pficon pficon-ok"
61+
ng-if="overallVerification(tag) == 'Verified'"></span>
62+
<span class="pficon pficon-error-circle-o"
63+
ng-if="overallVerification(tag) == 'Failed verification'"></span>
64+
<span class="pficon pficon-warning-triangle-o"
65+
ng-if="overallVerification(tag) === 'Unverified'"></span>
66+
<span translate="yes">{{ overallVerification(tag) }}</span>
67+
</div>
68+
</td>
5769
<td>
5870
<div title="{{ tag.items[0].created }}">
5971
<span ng-if="tag.status.items.length &amp;&amp; tag.status.items[0].image" title="{{ tag.items[0].created }}">
@@ -63,15 +75,15 @@
6375
</td>
6476
</tr>
6577
<tr class="listing-ct-panel" ng-if="imagestreamExpanded(imagestream, tag)" ng-repeat-end="">
66-
<td colspan="5">
78+
<td colspan="6">
6779
<registry-image-panel ng-init="tag = tag.status"></registry-image-panel>
6880
</td>
6981
</tr>
7082
</tbody>
7183
<thead class="listing-ct-empty" ng-if="!quiet">
7284
<tr>
73-
<td colspan="5" ng-if="!failure && !imagestreamTags(imagestream).length" translate="yes">No tags are present.</td>
74-
<td colspan="5" ng-if="failure">{{failure}}</td>
85+
<td colspan="6" ng-if="!failure && !imagestreamTags(imagestream).length" translate="yes">No tags are present.</td>
86+
<td colspan="6" ng-if="failure">{{failure}}</td>
7587
</tr>
7688
</thead>
7789
</table>

views/image-panel.html

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
<li ng-class="{active: tab('meta')}">
1515
<a ng-click="tab('meta', $event)" translate>Metadata</a>
1616
</li>
17+
<li ng-class="{active: tab('signatures')}">
18+
<a ng-click="tab('signatures', $event)" translate>Signatures</a>
19+
</li>
1720
</ul>
1821
</div>
1922

@@ -35,4 +38,9 @@
3538
<registry-image-layers image="image" layers="layers">
3639
</registry-image-layers>
3740
</div>
41+
42+
<div class="listing-ct-body" ng-show="tab('signatures')">
43+
<registry-image-signatures image="image">
44+
</registry-image-signatures>
45+
</div>
3846
</div>

views/image-signatures.html

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<div class="row" ng-repeat="signature in signatures">
2+
<dt translate><b>Signature</b></dt>
3+
<dd>{{ signature.metadata.name }}</dd>
4+
<dt translate>Verified</dt>
5+
<dd>
6+
<span class="pficon pficon-ok" style="margin-right: 5px;"
7+
ng-if="signature.verified == 'Verified'"></span>
8+
<span class="pficon pficon-error-circle-o" style="margin-right: 5px;"
9+
ng-if="signature.verified == 'Failed verification'"></span>
10+
<span class="pficon pficon-warning-triangle-o" style="margin-right: 5px;"
11+
ng-if="signature.verified === 'Unverified'"></span>
12+
<span translate="yes">{{ signature.verified }}</span>
13+
</dd>
14+
<span ng-if="signature.verified == 'Verified'">
15+
<dt translate>Details</dt>
16+
<dd>{{signatureDetails(signature)}}</dd>
17+
</span>
18+
</div>
19+
<div class="row" ng-if="signatures.length == 0">
20+
<span translate>No signatures</span>
21+
</div>

views/imagestream-listing.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,15 @@
3333
</td>
3434
</tr>
3535
<tr class="listing-ct-panel" ng-if="imagestreamExpanded(imagestream)">
36-
<td colspan="4">
36+
<td colspan="5">
3737
<registry-imagestream-panel></registry-imagestream-panel>
3838
</td>
3939
</tr>
4040
</tbody>
4141
<thead class="listing-ct-empty" ng-if="!quiet">
4242
<tr>
43-
<td colspan="4" ng-if="!failure && (!imagestreams || !imagestreams.length)" translate="yes">No image streams are present.</td>
44-
<td colspan="4" ng-if="failure">{{failure}}</td>
43+
<td colspan="5" ng-if="!failure && (!imagestreams || !imagestreams.length)" translate="yes">No image streams are present.</td>
44+
<td colspan="5" ng-if="failure">{{failure}}</td>
4545
</tr>
4646
</thead>
4747
</table>

webpack.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ module.exports = {
2424
srcdir + "views/image-config.html",
2525
srcdir + "views/image-meta.html",
2626
srcdir + "views/image-layers.html",
27+
srcdir + "views/image-signatures.html",
2728
srcdir + "views/image-panel.html",
2829
srcdir + "views/image-pull.html",
2930
srcdir + "views/image-listing.html",

0 commit comments

Comments
 (0)