diff --git a/api/http/handler/registries/registry_create.go b/api/http/handler/registries/registry_create.go index 67f8a4ee8..00b2c0259 100644 --- a/api/http/handler/registries/registry_create.go +++ b/api/http/handler/registries/registry_create.go @@ -26,6 +26,8 @@ type registryCreatePayload struct { Password string `example:"registry_password"` // Gitlab specific details, required when type = 4 Gitlab portainer.GitlabRegistryData + // Quay specific details, required when type = 1 + Quay portainer.QuayRegistryData } func (payload *registryCreatePayload) Validate(r *http.Request) error { @@ -74,6 +76,7 @@ func (handler *Handler) registryCreate(w http.ResponseWriter, r *http.Request) * UserAccessPolicies: portainer.UserAccessPolicies{}, TeamAccessPolicies: portainer.TeamAccessPolicies{}, Gitlab: payload.Gitlab, + Quay: payload.Quay, } err = handler.DataStore.Registry().CreateRegistry(registry) diff --git a/api/http/handler/registries/registry_update.go b/api/http/handler/registries/registry_update.go index 7ba5ad7ff..85540d72d 100644 --- a/api/http/handler/registries/registry_update.go +++ b/api/http/handler/registries/registry_update.go @@ -24,6 +24,7 @@ type registryUpdatePayload struct { Password *string `example:"registry_password"` UserAccessPolicies portainer.UserAccessPolicies TeamAccessPolicies portainer.TeamAccessPolicies + Quay *portainer.QuayRegistryData } func (payload *registryUpdatePayload) Validate(r *http.Request) error { @@ -110,6 +111,10 @@ func (handler *Handler) registryUpdate(w http.ResponseWriter, r *http.Request) * registry.TeamAccessPolicies = payload.TeamAccessPolicies } + if payload.Quay != nil { + registry.Quay = *payload.Quay + } + err = handler.DataStore.Registry().UpdateRegistry(registry.ID, registry) if err != nil { return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist registry changes inside the database", err} diff --git a/api/portainer.go b/api/portainer.go index bc21cb56e..12e8a7a8e 100644 --- a/api/portainer.go +++ b/api/portainer.go @@ -379,6 +379,12 @@ type ( ProjectPath string `json:"ProjectPath"` } + // QuayRegistryData represents data required for Quay registry to work + QuayRegistryData struct { + UseOrganisation bool `json:"UseOrganisation"` + OrganisationName string `json:"OrganisationName"` + } + // JobType represents a job type JobType int @@ -508,6 +514,7 @@ type ( Password string `json:"Password,omitempty" example:"registry_password"` ManagementConfiguration *RegistryManagementConfiguration `json:"ManagementConfiguration"` Gitlab GitlabRegistryData `json:"Gitlab"` + Quay QuayRegistryData `json:"Quay"` UserAccessPolicies UserAccessPolicies `json:"UserAccessPolicies"` TeamAccessPolicies TeamAccessPolicies `json:"TeamAccessPolicies"` diff --git a/app/docker/helpers/imageHelper.js b/app/docker/helpers/imageHelper.js index ff149b939..04ede1bf0 100644 --- a/app/docker/helpers/imageHelper.js +++ b/app/docker/helpers/imageHelper.js @@ -40,6 +40,11 @@ angular.module('portainer.docker').factory('ImageHelper', [ if (registry.Registry.Type === RegistryTypes.GITLAB) { const slash = _.startsWith(registry.Image, ':') ? '' : '/'; fullImageName = registry.Registry.URL + '/' + registry.Registry.Gitlab.ProjectPath + slash + registry.Image; + } + if (registry.Registry.Type === RegistryTypes.QUAY) { + const name = registry.Registry.Quay.UseOrganisation ? registry.Registry.Quay.OrganisationName : registry.Registry.Username; + const url = registry.Registry.URL ? registry.Registry.URL + '/' : ''; + fullImageName = url + name + '/' + registry.Image; } else { const url = registry.Registry.URL ? registry.Registry.URL + '/' : ''; fullImageName = url + registry.Image; diff --git a/app/portainer/components/forms/registry-form-quay/registry-form-quay.html b/app/portainer/components/forms/registry-form-quay/registry-form-quay.html index d3d2204ff..ff6883e09 100644 --- a/app/portainer/components/forms/registry-form-quay/registry-form-quay.html +++ b/app/portainer/components/forms/registry-form-quay/registry-form-quay.html @@ -32,6 +32,35 @@ + + +
This field is required.
+