This repository has been archived on 2020-03-24. You can view files and clone it, but cannot push or open issues or pull requests.
quay/static/directives/service-keys-manager.html
2016-04-29 14:05:16 -04:00

260 lines
No EOL
12 KiB
HTML

<div class="service-keys-manager-element">
<div class="resource-view" resource="keysResource" error-message="'Could not load service keys'">
<div class="manager-header" header-title="Service Keys">
<button class="btn btn-primary" ng-click="showCreateKey()">
Create Preshareable Key
</button>
</div>
<div class="section-description-header twenty">
Service keys provide a recognized means of authentication between Quay Enterprise and external services, as well as between external services. <br>Example services include Quay Security Scanner speaking to a <a href="https://github.com/coreos/clair" target="_blank">Clair</a> cluster, or Quay Enterprise speaking to its
<a href="https://tectonic.com/quay-enterprise/docs/latest/build-support.html" target="_blank">build workers</a>.
</div>
<span class="co-filter-box" ng-if="keys.length">
<span class="filter-message" ng-if="options.filter">
Showing {{ orderedKeys.entries.length }} of {{ keys.length }} keys
</span>
<input class="form-control" type="text" ng-model="options.filter" placeholder="Filter Keys...">
</span>
<!-- Table -->
<div class="empty" ng-if="!keys.length" style="margin-top: 20px;">
<div class="empty-primary-msg">No service keys defined</div>
<div class="empty-secondary-msg">There are no keys defined for working with external services</div>
</div>
<table class="co-table" ng-show="keys.length">
<thead>
<td class="caret-col"></td>
<td ng-class="TableService.tablePredicateClass('name', options.predicate, options.reverse)">
<a href="javascript:void(0)" ng-click="TableService.orderBy('name', options)">Name</a>
</td>
<td ng-class="TableService.tablePredicateClass('service', options.predicate, options.reverse)">
<a href="javascript:void(0)" ng-click="TableService.orderBy('service', options)">Service Name</a>
</td>
<td ng-class="TableService.tablePredicateClass('creation_datetime', options.predicate, options.reverse)">
<a href="javascript:void(0)" ng-click="TableService.orderBy('creation_datetime', options)">Created</a>
</td>
<td ng-class="TableService.tablePredicateClass('expiration_datetime', options.predicate, options.reverse)">
<a href="javascript:void(0)" ng-click="TableService.orderBy('expiration_datetime', options)">Expires</a>
</td>
<td>
Approval Status
</td>
<td class="hidden-xs options-col"></td>
</thead>
<tbody ng-repeat="key in orderedKeys.visibleEntries" bindonce>
<tr>
<td class="caret-col">
<span ng-click="toggleDetails(key)">
<i class="fa"
ng-class="key.expanded ? 'fa-caret-down' : 'fa-caret-right'"
data-title="View Details" bs-tooltip></i>
</span>
</td>
<td>
<a ng-click="toggleDetails(key)" bo-if="key.name"><span bo-text="key.name"></span></a>
<a ng-click="toggleDetails(key)" bo-if="!key.name" class="unnamed">(Unnamed)</a>
</td>
<td><span bo-text="key.service"></span></td>
<td>
<span am-time-ago="key.created_date"></span>
</td>
<td>
<span class="rotation" bo-if="key.expiration_date && getExpirationInfo(key).rotateDate">
<i class="fa" ng-class="getExpirationInfo(key).icon"></i>
Automatically rotated <span am-time-ago="getExpirationInfo(key).rotateDate"></span>
</span>
<span bo-if="key.expiration_date && !getExpirationInfo(key).rotateDate">
<span ng-class="getExpirationInfo(key).className">
<a ng-click="showChangeExpiration(key)">
<i class="fa" ng-class="getExpirationInfo(key).icon"></i>
Expires <span am-time-ago="key.expiration_date"></span>
</a>
</span>
</span>
<span class="no-expiration" bo-if="!key.expiration_date">
<i class="fa fa-info-circle"></i> Does not expire
</span>
</td>
<td>
<span class="approval-user" bo-if="key.approval && key.approval.approval_type == 'ServiceKeyApprovalType.SUPERUSER'">
<span class="pretext">Approved by</span><span class="entity-reference" entity="key.approval.approver"></span>
</span>
<span class="approval-rotation" bo-if="key.approval && key.approval.approval_type == 'ServiceKeyApprovalType.KEY_ROTATION'">
<i class="fa fa-refresh"></i>Approved via key rotation
</span>
<span class="approval-required" bo-if="!key.approval">
<i class="fa fa-warning"></i>
Awaiting Approval <a ng-click="showApproveKey(key)">Approve Now</a>
</span>
</td>
<td class="options-col">
<span class="cor-options-menu">
<span class="cor-option" option-click="showChangeName(key)">
<i class="fa fa-tag"></i> Set Friendly Name
</span>
<span class="cor-option" option-click="showChangeExpiration(key)">
<i class="fa fa-clock-o"></i> Change Expiration Time
</span>
<span class="cor-option" option-click="showApproveKey(key)" ng-show="!key.approval">
<i class="fa fa-check-circle"></i> Approve Key
</span>
<span class="cor-option" option-click="showDeleteKey(key)">
<i class="fa fa-times"></i> Delete Key
</span>
</span>
</td>
</tr>
<tr ng-if="key.expanded">
<td colspan="7">
<div class="subtitle">Full Key ID</div>
<span bo-text="key.kid"></span>
<div bo-if="key.approval.notes">
<div class="subtitle">Approval notes</div>
<div class="markdown-view" content="key.approval.notes"></div>
</div>
</td>
</tr>
</tbody>
</table>
<div class="empty" ng-if="keys.length && !orderedKeys.entries.length"
style="margin-top: 20px;">
<div class="empty-primary-msg">No matching keys found.</div>
<div class="empty-secondary-msg">Try expanding your filtering terms.</div>
</div>
</div>
<!-- Change Key Expiration Confirm -->
<div class="cor-confirm-dialog"
dialog-context="context.expirationChangeInfo"
dialog-action="changeKeyExpiration(context.expirationChangeInfo, callback)"
dialog-title="Change Service Key Expiration"
dialog-action-title="Change Expiration">
<form>
<span class="datetime-picker" datetime="context.expirationChangeInfo.expiration_date"></span>
<span class="co-help-text">
If specified, the date and time that the key expires. It is highly recommended to have an expiration date.
</span>
</form>
</div>
<!-- Delete Key Confirm -->
<div class="cor-confirm-dialog"
dialog-context="deleteKeyInfo"
dialog-action="deleteKey(deleteKeyInfo, callback)"
dialog-title="Delete Service Key"
dialog-action-title="Delete Key">
Are you <strong>sure</strong> you want to delete service key <strong>{{ getKeyTitle(deleteKeyInfo.key) }}</strong>?<br><br>
All external services that use this key for authentication will fail.
</div>
<!-- Approve Key Confirm -->
<div class="cor-confirm-dialog"
dialog-context="approvalKeyInfo"
dialog-action="approveKey(approvalKeyInfo, callback)"
dialog-title="Approve Service Key"
dialog-action-title="Approve Key">
<form>
<div style="margin-bottom: 10px;">
Approve service key <strong>{{ getKeyTitle(approvalKeyInfo.key) }}</strong>?
</div>
<div class="markdown-editor" content="approvalKeyInfo.notes"></div>
<span class="co-help-text">
Enter optional notes for additional human-readable information about why the key was approved.
</span>
</form>
</div>
<!-- Created key modal -->
<div id="createdKeyModal" class="modal fade co-dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" ng-show="!creatingKey" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title">Created Preshareable Service Key <strong>{{ getKeyTitle(createdKey) }}</strong></h4>
</div>
<div class="modal-body">
<div class="co-alert co-alert-warning">
Please copy or download the following private key. <strong>Once this dialog is closed the key will not be accessible anywhere else</strong>.
</div>
<textarea class="key-display form-control" onclick="this.focus();this.select()" readonly>{{ createdKey.private_key }}</textarea>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" ng-click="downloadPrivateKey(createdKey)" ng-if="isDownloadSupported()">
<i class="fa fa-download"></i> Download Private Key
</button>
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
<!-- Create key modal -->
<div id="createKeyModal" class="modal fade co-dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" ng-show="!creatingKey" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title">Create Preshareable Service Key</h4>
</div>
<div class="modal-body" ng-show="creatingKey">
<div class="cor-loader"></div>
</div>
<div class="modal-body" ng-show="!creatingKey">
<form name="createForm" ng-submit="createServiceKey()">
<table class="co-form-table">
<tr>
<td><label for="create-key-name">Key Name:</label></td>
<td>
<input class="form-control" name="create-key-name" type="text" ng-model="newKey.name" placeholder="Friendly Key Name" required>
<span class="co-help-text">
A friendly name for the key for later reference.
</span>
</td>
</tr>
<tr>
<td><label for="create-servce-name">Service Name:</label></td>
<td>
<input class="form-control" name="create-servce-name" type="text" ng-model="newKey.service" placeholder="Service Name" ng-pattern="/^[a-z0-9_]+$/" required>
<span class="co-help-text">
The name of the service for the key. Keys within the same cluster should share service names, representing
a single logical service. Must match [a-z0-9_]+.
</span>
</td>
</tr>
<tr>
<td><label for="create-key-expiration">Expires:</label></td>
<td>
<span class="datetime-picker" datetime="newKey.expiration"></span>
<span class="co-help-text">
If specified, the date and time that the key expires. It is highly recommended to have an expiration date.
</span>
</td>
</tr>
<tr>
<td><label for="create-key-notes">Approval Notes:</label></td>
<td>
<div class="markdown-editor" content="newKey.notes"></div>
<span class="co-help-text">
Optional notes for additional human-readable information about why the key was added.
</span>
</td>
</tr>
</table>
</form>
</div>
<div class="modal-footer" ng-show="!creatingKey">
<button type="button" class="btn btn-primary" ng-click="createServiceKey()" ng-disabled="createForm.$invalid">
Create Key
</button>
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
</div>