portainer--portainer
204 行
6.7 KiB
JavaScript
204 行
6.7 KiB
JavaScript
import _ from 'lodash-es';
|
|
import { PorImageRegistryModel } from '@/docker/models/porImageRegistry';
|
|
import { RegistryTypes } from '@/portainer/models/registryTypes';
|
|
import { RegistryCreateRequest, RegistryViewModel } from '@/portainer/models/registry';
|
|
import { DockerHubViewModel } from '@/portainer/models/dockerhub';
|
|
|
|
angular.module('portainer.app').factory('RegistryService', [
|
|
'$q',
|
|
'$async',
|
|
'EndpointService',
|
|
'Registries',
|
|
'ImageHelper',
|
|
'FileUploadService',
|
|
function RegistryServiceFactory($q, $async, EndpointService, Registries, ImageHelper, FileUploadService) {
|
|
return {
|
|
registries,
|
|
registry,
|
|
encodedCredentials,
|
|
deleteRegistry,
|
|
updateRegistry,
|
|
configureRegistry,
|
|
createRegistry,
|
|
createGitlabRegistries,
|
|
retrievePorRegistryModelFromRepository,
|
|
retrievePorRegistryModelFromRepositoryWithRegistries,
|
|
loadRegistriesForDropdown,
|
|
};
|
|
|
|
function registries() {
|
|
var deferred = $q.defer();
|
|
|
|
Registries.query()
|
|
.$promise.then(function success(data) {
|
|
var registries = data.map(function (item) {
|
|
return new RegistryViewModel(item);
|
|
});
|
|
deferred.resolve(registries);
|
|
})
|
|
.catch(function error(err) {
|
|
deferred.reject({ msg: 'Unable to retrieve registries', err: err });
|
|
});
|
|
|
|
return deferred.promise;
|
|
}
|
|
|
|
function registry(id, endpointId) {
|
|
var deferred = $q.defer();
|
|
|
|
Registries.get({ id, endpointId })
|
|
.$promise.then(function success(data) {
|
|
var registry = new RegistryViewModel(data);
|
|
deferred.resolve(registry);
|
|
})
|
|
.catch(function error(err) {
|
|
deferred.reject({ msg: 'Unable to retrieve registry details', err: err });
|
|
});
|
|
|
|
return deferred.promise;
|
|
}
|
|
|
|
function encodedCredentials(registry) {
|
|
var credentials = {
|
|
registryId: registry.Id,
|
|
};
|
|
return btoa(JSON.stringify(credentials));
|
|
}
|
|
|
|
function deleteRegistry(id) {
|
|
return Registries.remove({ id: id }).$promise;
|
|
}
|
|
|
|
function updateRegistry(registry) {
|
|
registry.URL = _.replace(registry.URL, /^https?\:\/\//i, '');
|
|
registry.URL = _.replace(registry.URL, /\/$/, '');
|
|
return Registries.update({ id: registry.Id }, registry).$promise;
|
|
}
|
|
|
|
function configureRegistry(id, registryManagementConfigurationModel) {
|
|
return FileUploadService.configureRegistry(id, registryManagementConfigurationModel);
|
|
}
|
|
|
|
function createRegistry(model) {
|
|
var payload = new RegistryCreateRequest(model);
|
|
return Registries.create(payload).$promise;
|
|
}
|
|
|
|
/**
|
|
* @param {import('@/portainer/models/registry').RegistryCreateFormValues} model
|
|
* @param {Array<import('@/react/portainer/registries/types/gitlabProject').RegistryGitlabProject>} projects
|
|
*/
|
|
function createGitlabRegistries(model, projects) {
|
|
const promises = [];
|
|
_.forEach(projects, (p) => {
|
|
const m = model;
|
|
m.Name = p.PathWithNamespace;
|
|
m.Gitlab.ProjectPath = _.toLower(p.PathWithNamespace);
|
|
m.Gitlab.ProjectId = p.Id;
|
|
m.Password = m.Token;
|
|
const payload = new RegistryCreateRequest(m);
|
|
promises.push(Registries.create(payload).$promise);
|
|
});
|
|
return $q.all(promises);
|
|
}
|
|
|
|
function getURL(reg) {
|
|
let url = reg.URL;
|
|
if (reg.Type === RegistryTypes.GITLAB) {
|
|
url = reg.URL + '/' + reg.Gitlab.ProjectPath;
|
|
} else if (reg.Type === RegistryTypes.QUAY) {
|
|
const name = reg.Quay.UseOrganisation ? reg.Quay.OrganisationName : reg.Username;
|
|
url = reg.URL + '/' + name;
|
|
}
|
|
return url;
|
|
}
|
|
|
|
// findBestMatchRegistry finds out the best match registry for repository
|
|
// matching precedence:
|
|
// 1. registryId matched
|
|
// 2. both domain name and username matched (for dockerhub only)
|
|
// 3. only URL matched
|
|
// 4. pick up the first dockerhub registry
|
|
function findBestMatchRegistry(repository, registries, registryId) {
|
|
let match2, match3, match4;
|
|
|
|
for (const registry of registries) {
|
|
if (registry.Id == registryId) {
|
|
return registry;
|
|
}
|
|
|
|
if (registry.Type === RegistryTypes.DOCKERHUB) {
|
|
// try to match repository examples:
|
|
// <USERNAME>/nginx:latest
|
|
// docker.io/<USERNAME>/nginx:latest
|
|
if (repository.startsWith(registry.Username + '/') || repository.startsWith(getURL(registry) + '/' + registry.Username + '/')) {
|
|
match2 = registry;
|
|
}
|
|
|
|
// try to match repository examples:
|
|
// portainer/portainer-ee:latest
|
|
// <NON-USERNAME>/portainer-ee:latest
|
|
match4 = match4 || registry;
|
|
}
|
|
|
|
if (repository.startsWith(getURL(registry))) {
|
|
match3 = registry;
|
|
}
|
|
}
|
|
|
|
return match2 || match3 || match4;
|
|
}
|
|
|
|
function retrievePorRegistryModelFromRepositoryWithRegistries(repository, registries, registryId) {
|
|
const model = new PorImageRegistryModel();
|
|
const registry = findBestMatchRegistry(repository, registries, registryId);
|
|
if (registry) {
|
|
const url = getURL(registry);
|
|
let lastIndex = repository.lastIndexOf(url);
|
|
lastIndex = lastIndex === -1 ? 0 : lastIndex + url.length;
|
|
let image = repository.substring(lastIndex);
|
|
if (_.startsWith(image, '/')) {
|
|
image = image.substring(1);
|
|
}
|
|
model.Registry = registry;
|
|
model.Image = image;
|
|
} else {
|
|
if (ImageHelper.imageContainsURL(repository)) {
|
|
model.UseRegistry = false;
|
|
}
|
|
model.Registry = new DockerHubViewModel();
|
|
model.Image = repository;
|
|
}
|
|
return model;
|
|
}
|
|
|
|
function retrievePorRegistryModelFromRepository(repository, endpointId, registryId, namespace) {
|
|
return $async(async () => {
|
|
try {
|
|
const regs = await EndpointService.registries(endpointId, namespace);
|
|
return retrievePorRegistryModelFromRepositoryWithRegistries(repository, regs, registryId);
|
|
} catch (err) {
|
|
throw { msg: 'Unable to retrieve the registry associated to the repository', err: err };
|
|
}
|
|
});
|
|
}
|
|
|
|
function loadRegistriesForDropdown(endpointId, namespace) {
|
|
return $async(async () => {
|
|
try {
|
|
const registries = await EndpointService.registries(endpointId, namespace);
|
|
|
|
// hide default(anonymous) dockerhub registry if user has an authenticated one
|
|
if (!registries.some((registry) => registry.Type === RegistryTypes.DOCKERHUB)) {
|
|
registries.push(new DockerHubViewModel());
|
|
}
|
|
|
|
return registries;
|
|
} catch (err) {
|
|
throw { msg: 'Unable to retrieve the registries', err: err };
|
|
}
|
|
});
|
|
}
|
|
},
|
|
]);
|