initial import for Open Source 🎉
This commit is contained in:
parent
1898c361f3
commit
9c0dd3b722
2048 changed files with 218743 additions and 0 deletions
468
static/js/directives/repo-view/repo-panel-mirroring.js
Normal file
468
static/js/directives/repo-view/repo-panel-mirroring.js
Normal file
|
@ -0,0 +1,468 @@
|
|||
import { vendor } from "postcss";
|
||||
|
||||
/**
|
||||
* An element which displays the mirroring panel for a repository view.
|
||||
*/
|
||||
angular.module('quay').directive('repoPanelMirror', function () {
|
||||
var directiveDefinitionObject = {
|
||||
priority: 0,
|
||||
templateUrl: '/static/directives/repo-view/repo-panel-mirroring.html',
|
||||
replace: false,
|
||||
transclude: false,
|
||||
restrict: 'C',
|
||||
scope: {
|
||||
'repository': '=repository',
|
||||
'isEnabled': '=isEnabled'
|
||||
},
|
||||
controllerAs: 'vm',
|
||||
controller: function ($scope, ApiService, Features) {
|
||||
|
||||
let vm = this;
|
||||
|
||||
// Feature Flagged
|
||||
if (!Features.REPO_MIRROR) { return; }
|
||||
|
||||
// Shared by API Calls
|
||||
let params = { 'repository': $scope.repository.namespace + '/' + $scope.repository.name };
|
||||
|
||||
/**
|
||||
* Mirror Configuration
|
||||
*/
|
||||
vm.isSetup = false;
|
||||
vm.expirationDate = null;
|
||||
vm.isEnabled = null;
|
||||
vm.httpProxy = null;
|
||||
vm.httpsProxy = null;
|
||||
vm.externalReference = null;
|
||||
vm.noProxy = null;
|
||||
vm.retriesRemaining = null;
|
||||
vm.robot = null;
|
||||
vm.status = null;
|
||||
vm.syncInterval = null;
|
||||
vm.syncStartDate = null;
|
||||
vm.tags = null;
|
||||
vm.username = null;
|
||||
vm.verifyTLS = null;
|
||||
|
||||
/**
|
||||
* Fetch the latest Repository Mirror Configuration
|
||||
*/
|
||||
vm.getMirror = function() {
|
||||
ApiService.getRepoMirrorConfig(null, params)
|
||||
.then(function (resp) {
|
||||
vm.isSetup = true;
|
||||
|
||||
vm.isEnabled = resp.is_enabled;
|
||||
vm.externalReference = resp.external_reference;
|
||||
vm.syncInterval = resp.sync_interval;
|
||||
vm.username = resp.external_registry_username;
|
||||
vm.syncStartDate = resp.sync_start_date;
|
||||
vm.status = resp.sync_status;
|
||||
vm.expirationDate = resp.sync_expiration_date;
|
||||
vm.retriesRemaining = resp.sync_retries_remaining;
|
||||
|
||||
vm.robot = {};
|
||||
if (resp.robot_username) {
|
||||
vm.robot = {
|
||||
'name': resp.robot_username,
|
||||
'kind': 'user',
|
||||
'is_robot': true
|
||||
};
|
||||
}
|
||||
|
||||
vm.tags = resp.root_rule.rule_value || []; // TODO: Use RepoMirrorRule-specific endpoint
|
||||
|
||||
// TODO: These are not consistently provided by the API. Correct that in the API.
|
||||
vm.verifyTLS = resp.external_registry_config.verify_tls;
|
||||
if (resp.external_registry_config.proxy) {
|
||||
vm.httpProxy = resp.external_registry_config.proxy.http_proxy;
|
||||
vm.httpsProxy = resp.external_registry_config.proxy.https_proxy;
|
||||
vm.noProxy = resp.external_registry_config.proxy.no_proxy;
|
||||
}
|
||||
}, function (err) { console.info("No repository mirror configuration.", err); });
|
||||
}
|
||||
|
||||
/**
|
||||
* Human-friendly status messages
|
||||
*/
|
||||
vm.statusLabels = {
|
||||
"NEVER_RUN": "Scheduled",
|
||||
"SYNC_NOW": "Scheduled Now",
|
||||
"SYNCING": "Sync In Progress",
|
||||
"SUCCESS": "Last Sync Succeeded",
|
||||
"FAIL": "Last Sync Failed"
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert (Unix) Timestamp to ISO Formatted Date String used by the API
|
||||
*/
|
||||
vm.timestampToISO = function(ts) {
|
||||
let dt = moment.unix(ts).toISOString().split('.')[0] + 'Z'; // Remove milliseconds
|
||||
return dt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert ISO Date String to (Unix) Timestamp
|
||||
*/
|
||||
vm.timestampFromISO = function(dt) {
|
||||
let ts = moment(dt).unix();
|
||||
return ts;
|
||||
}
|
||||
|
||||
/**
|
||||
* When set to a truthy value, any `cor-confirm-dialog` associated with these variables will
|
||||
* be displayed.
|
||||
*/
|
||||
vm.credentialsChanges = null;
|
||||
vm.httpProxyChanges = null;
|
||||
vm.httpsProxyChanges = null;
|
||||
vm.locationChanges = null;
|
||||
vm.noProxyChanges = null;
|
||||
vm.syncIntervalChanges = null;
|
||||
vm.syncStartDateChanges = null;
|
||||
vm.tagChanges = null;
|
||||
|
||||
/**
|
||||
* The following `show` functions initialize and trigger the display of a modal to modify
|
||||
* configuration attributes.
|
||||
*/
|
||||
|
||||
vm.showChangeSyncInterval = function() {
|
||||
vm.syncIntervalChanges = {
|
||||
'fieldName': 'synchronization interval',
|
||||
'values': {
|
||||
'sync_interval': vm.syncInterval
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vm.showChangeSyncStartDate = function() {
|
||||
let ts = vm.timestampFromISO(vm.syncStartDate);
|
||||
vm.syncStartDateChanges = {
|
||||
'fieldName': 'next synchronization date',
|
||||
'values': {
|
||||
'sync_start_date': ts
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vm.showChangeTags = function() {
|
||||
vm.tagChanges = {
|
||||
'fieldName': 'tag patterns',
|
||||
'values': {
|
||||
'rule_value': vm.tags || []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vm.showChangeCredentials = function() {
|
||||
vm.credentialsChanges = {
|
||||
'fieldName': 'credentials',
|
||||
'values': {
|
||||
'external_registry_username': vm.username,
|
||||
'external_registry_password': null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vm.showChangeHTTPProxy = function() {
|
||||
vm.httpProxyChanges = {
|
||||
'fieldName': 'HTTP Proxy',
|
||||
'values': {
|
||||
'external_registry_config': {
|
||||
'proxy': {
|
||||
'http_proxy': vm.httpProxy
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vm.showChangeHTTPsProxy = function() {
|
||||
vm.httpsProxyChanges = {
|
||||
'fieldName': 'HTTPs Proxy',
|
||||
'values': {
|
||||
'external_registry_config': {
|
||||
'proxy': {
|
||||
'https_proxy': vm.httpsProxy
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vm.showChangeNoProxy = function() {
|
||||
vm.noProxyChanges = {
|
||||
'fieldName': 'No Proxy',
|
||||
'values': {
|
||||
'external_registry_config': {
|
||||
'proxy': {
|
||||
'no_proxy': vm.noProxy
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vm.showChangeExternalRepository = function() {
|
||||
vm.externalRepositoryChanges = {
|
||||
'fieldName': 'External Repository',
|
||||
'values': {
|
||||
'external_reference': vm.externalReference
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit API request to modify repository mirroring attribute(s)
|
||||
*/
|
||||
vm.changeConfig = function(data, callback) {
|
||||
|
||||
let fieldName = data.fieldName || 'configuration';
|
||||
let requestBody = data.values;
|
||||
let errMsg = "Unable to change " + fieldName + '.';
|
||||
let handleError = ApiService.errorDisplay(errMsg, callback);
|
||||
|
||||
let handleSuccess = function() {
|
||||
vm.getMirror(); // Fetch updated configuration
|
||||
if (callback) callback(true);
|
||||
}
|
||||
|
||||
ApiService.changeRepoMirrorConfig(requestBody, params)
|
||||
.then(handleSuccess, handleError);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform the DatePicker's Unix timestamp into a string compatible with the API
|
||||
* before attempting to change it.
|
||||
*/
|
||||
vm.changeSyncStartDate = function(data, callback) {
|
||||
let newSyncStartDate = vm.timestampToISO(data.values.sync_start_date);
|
||||
data.values.sync_start_date = newSyncStartDate;
|
||||
return vm.changeConfig(data, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable `Verify TLS`.
|
||||
*/
|
||||
vm.enableVerifyTLS = function() {
|
||||
let data = {
|
||||
'fieldName': 'TLS verification',
|
||||
'values': {
|
||||
'external_registry_config': {
|
||||
'verify_tls': true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return vm.changeConfig(data, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable `Verify TLS`
|
||||
*/
|
||||
vm.disableVerifyTLS = function() {
|
||||
let data = {
|
||||
'fieldName': 'TLS verification',
|
||||
'values': {
|
||||
'external_registry_config': {
|
||||
'verify_tls': false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return vm.changeConfig(data, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle `Verify TLS`.
|
||||
*/
|
||||
vm.toggleVerifyTLS = function() {
|
||||
if (vm.verifyTLS) return vm.disableVerifyTLS();
|
||||
else return vm.enableVerifyTLS();
|
||||
}
|
||||
|
||||
/**
|
||||
* Change Robot user.
|
||||
*/
|
||||
vm.changeRobot = function(robot) {
|
||||
if (!vm.robot) return;
|
||||
if (!robot || robot.name == vm.robot.name) return;
|
||||
|
||||
let data = {
|
||||
'fieldName': 'robot',
|
||||
'values': {
|
||||
'robot_username': robot.name
|
||||
}
|
||||
}
|
||||
|
||||
return vm.changeConfig(data, null)
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete Credentials
|
||||
*/
|
||||
vm.deleteCredentials = function() {
|
||||
let data = {
|
||||
'fieldName': 'credentials',
|
||||
'values': {
|
||||
'external_registry_username': null,
|
||||
'external_registry_password': null
|
||||
}
|
||||
}
|
||||
|
||||
return vm.changeConfig(data, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable mirroring configuration.
|
||||
*/
|
||||
vm.enableMirroring = function() {
|
||||
let data = {
|
||||
'fieldName': 'enabled state',
|
||||
'values': {
|
||||
'is_enabled': true
|
||||
}
|
||||
}
|
||||
|
||||
return vm.changeConfig(data, null)
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable mirroring configuration.
|
||||
*/
|
||||
vm.disableMirroring = function() {
|
||||
let data = {
|
||||
'fieldName': 'enabled state',
|
||||
'values': {
|
||||
'is_enabled': false
|
||||
}
|
||||
}
|
||||
|
||||
return vm.changeConfig(data, null)
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle mirroring on/off.
|
||||
*/
|
||||
vm.toggleMirroring = function() {
|
||||
if (vm.isEnabled) return vm.disableMirroring();
|
||||
else return vm.enableMirroring();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update Tag-Rules
|
||||
*/
|
||||
vm.changeTagRules = function(data, callback) {
|
||||
let csv = data.values.rule_value;
|
||||
let patterns = csv.split(',');
|
||||
|
||||
patterns.map(s => s.trim()); // Trim excess whitespace
|
||||
patterns = Array.from(new Set(patterns)); // De-duplicate
|
||||
|
||||
if (patterns.length < 1) {
|
||||
bootbox.alert('Rule value required');
|
||||
callback(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
data = {
|
||||
'root_rule': {
|
||||
'rule_type': 'TAG_GLOB_CSV',
|
||||
'rule_value': patterns
|
||||
}
|
||||
}
|
||||
|
||||
let displayError = ApiService.errorDisplay('Could not change Tag Rules', callback);
|
||||
|
||||
ApiService
|
||||
.changeRepoMirrorRule(data, params)
|
||||
.then(function(resp) {
|
||||
vm.getMirror();
|
||||
callback(true);
|
||||
}, displayError);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger Immediate Synchronization
|
||||
*/
|
||||
vm.syncNow = function () {
|
||||
let displayError = ApiService.errorDisplay('Unable to sync now', null);
|
||||
|
||||
ApiService
|
||||
.syncNow(null, params)
|
||||
.then(function(resp) {
|
||||
vm.getMirror(); // Reload latest changes
|
||||
return true;
|
||||
}, displayError);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel In-Progress Synchronization
|
||||
*/
|
||||
vm.syncCancel = function() {
|
||||
let displayError = ApiService.errorDisplay('Unable to cancel sync', null);
|
||||
|
||||
ApiService
|
||||
.syncCancel(null, params)
|
||||
.then(function(resp) {
|
||||
vm.getMirror(); // Reload latest changes
|
||||
return true;
|
||||
}, displayError);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Load the current mirror configuration on initialization
|
||||
if ($scope.repository.state == 'MIRROR') {
|
||||
vm.getMirror();
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure mirroing.
|
||||
* TODO: Move this, and the associated template/view, to its own component and use the
|
||||
* wizard-flow instead of a single form.
|
||||
*/
|
||||
vm.setupMirror = function() {
|
||||
|
||||
// Apply transformations
|
||||
let now = vm.timestampToISO(moment().unix());
|
||||
let syncStartDate = vm.timestampToISO(vm.syncStartDate) || now;
|
||||
let patterns = Array.from(new Set(vm.tags.split(',').map(s => s.trim()))); // trim + de-dupe
|
||||
|
||||
let requestBody = {
|
||||
'external_reference': vm.externalReference,
|
||||
'external_registry_username': vm.username,
|
||||
'external_registry_password': vm.password,
|
||||
'sync_interval': vm.syncInterval,
|
||||
'sync_start_date': syncStartDate,
|
||||
'robot_username': vm.robot.name,
|
||||
'external_registry_config': {
|
||||
'verify_tls': vm.verifyTLS || false, // `null` not allowed
|
||||
'proxy': {
|
||||
'http_proxy': vm.httpProxy,
|
||||
'https_proxy': vm.httpsProxy,
|
||||
'no_proxy': vm.noProxy
|
||||
}
|
||||
},
|
||||
'root_rule': {
|
||||
'rule_type': 'TAG_GLOB_CSV',
|
||||
'rule_value': patterns
|
||||
}
|
||||
}
|
||||
|
||||
let successHandler = function(resp) { vm.getMirror(); return true; }
|
||||
let errorHandler = ApiService.errorDisplay('Unable to setup mirror.', null);
|
||||
ApiService.createRepoMirrorConfig(requestBody, params).then(successHandler, errorHandler);
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
return directiveDefinitionObject;
|
||||
});
|
Reference in a new issue