fix(registry): Add input prompt and checker in edit page [EE-2705] (#7106)

* EE-2705 restrict registry edit options for different registry type
pull/7204/head
Chao Geng 2022-07-06 19:11:59 +08:00 committed by GitHub
parent 8bf1c91bc9
commit b4acbfc9e1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 175 additions and 43 deletions

View File

@ -97,25 +97,25 @@
</div>
</div>
<!-- !aws-secret-access-key -->
<!-- region -->
<div class="form-group">
<label for="registry_region" class="col-sm-3 col-lg-2 control-label text-left">Region</label>
<div class="col-sm-9 col-lg-10">
<input type="text" class="form-control" id="registry_region" name="registry_region" placeholder="us-west-1" ng-model="$ctrl.model.Ecr.Region" required />
</div>
</div>
<div class="form-group" ng-show="$ctrl.registryFormEcr.registry_region.$invalid">
<div class="col-sm-12 small text-warning">
<div ng-messages="$ctrl.registryFormEcr.registry_region.$error">
<p ng-message="required"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> This field is required.</p>
<p ng-message="used"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> A registry with the same name already exists.</p>
</div>
</div>
</div>
<!-- !region -->
</div>
<!-- region -->
<div class="form-group">
<label for="registry_region" class="col-sm-3 col-lg-2 control-label text-left">Region</label>
<div class="col-sm-9 col-lg-10">
<input type="text" class="form-control" id="registry_region" name="registry_region" placeholder="us-west-1" ng-model="$ctrl.model.Ecr.Region" required />
</div>
</div>
<div class="form-group" ng-show="$ctrl.registryFormEcr.registry_region.$invalid">
<div class="col-sm-12 small text-warning">
<div ng-messages="$ctrl.registryFormEcr.registry_region.$error">
<p ng-message="required"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> This field is required.</p>
<p ng-message="used"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> A registry with the same name already exists.</p>
</div>
</div>
</div>
<!-- !region -->
<!-- actions -->
<div class="col-sm-12 form-section-title"> Actions </div>
<div class="form-group">

View File

@ -1,5 +1,21 @@
<form class="form-horizontal" name="registryFormQuay" ng-submit="$ctrl.formAction()">
<form class="form-horizontal" name="$ctrl.registryFormQuay" ng-submit="$ctrl.formAction()">
<div class="col-sm-12 form-section-title"> Quay account details </div>
<!-- name-input -->
<div class="form-group">
<label for="registry_name" class="col-sm-3 col-lg-2 control-label text-left">Name</label>
<div class="col-sm-9 col-lg-10">
<input type="text" class="form-control" id="registry_name" name="registry_name" ng-model="$ctrl.model.Name" placeholder="Quay" required />
</div>
</div>
<div class="form-group" ng-show="$ctrl.registryFormQuay.registry_name.$invalid">
<div class="col-sm-12 small text-warning">
<div ng-messages="$ctrl.registryFormQuay.registry_name.$error">
<p ng-message="required"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> This field is required.</p>
<p ng-message="used"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> A registry with the same name already exists.</p>
</div>
</div>
</div>
<!-- !name-input -->
<!-- credentials-user -->
<div class="form-group">
<label for="registry_username" class="col-sm-3 col-lg-2 control-label text-left">Username</label>
@ -7,9 +23,9 @@
<input type="text" class="form-control" id="registry_username" name="registry_username" ng-model="$ctrl.model.Username" required auto-focus />
</div>
</div>
<div class="form-group" ng-show="registryFormQuay.registry_username.$invalid">
<div class="form-group" ng-show="$ctrl.registryFormQuay.registry_username.$invalid">
<div class="col-sm-12 small text-warning">
<div ng-messages="registryFormQuay.registry_username.$error">
<div ng-messages="$ctrl.registryFormQuay.registry_username.$error">
<p ng-message="required"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> This field is required.</p>
</div>
</div>
@ -22,9 +38,9 @@
<input type="password" class="form-control" id="registry_password" name="registry_password" ng-model="$ctrl.model.Password" required />
</div>
</div>
<div class="form-group" ng-show="registryFormQuay.registry_password.$invalid">
<div class="form-group" ng-show="$ctrl.registryFormQuay.registry_password.$invalid">
<div class="col-sm-12 small text-warning">
<div ng-messages="registryFormQuay.registry_password.$error">
<div ng-messages="$ctrl.registryFormQuay.registry_password.$error">
<p ng-message="required"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> This field is required.</p>
</div>
</div>
@ -47,9 +63,9 @@
<input type="text" class="form-control" id="organisation_name" name="organisation_name" ng-model="$ctrl.model.Quay.organisationName" required />
</div>
</div>
<div class="form-group" ng-show="registryFormQuay.organisation_name.$invalid">
<div class="form-group" ng-show="$ctrl.registryFormQuay.organisation_name.$invalid">
<div class="col-sm-12 small text-warning">
<div ng-messages="registryFormQuay.organisation_name.$error">
<div ng-messages="$ctrl.registryFormQuay.organisation_name.$error">
<p ng-message="required"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> This field is required.</p>
</div>
</div>
@ -64,7 +80,7 @@
<button
type="submit"
class="btn btn-primary btn-sm"
ng-disabled="$ctrl.actionInProgress || !registryFormQuay.$valid"
ng-disabled="$ctrl.actionInProgress || !$ctrl.registryFormQuay.$valid"
button-spinner="$ctrl.actionInProgress"
analytics-on
analytics-category="portainer"

View File

@ -1,3 +1,9 @@
class controller {
$postLink() {
this.registryFormQuay.registry_name.$validators.used = (modelValue) => !this.nameIsUsed(modelValue);
}
}
angular.module('portainer.app').component('registryFormQuay', {
templateUrl: './registry-form-quay.html',
bindings: {
@ -5,5 +11,7 @@ angular.module('portainer.app').component('registryFormQuay', {
formAction: '<',
formActionLabel: '@',
actionInProgress: '<',
nameIsUsed: '<',
},
controller,
});

View File

@ -90,6 +90,7 @@
form-action="$ctrl.createRegistry"
form-action-label="Add registry"
action-in-progress="$ctrl.state.actionInProgress"
name-is-used="($ctrl.nameIsUsed)"
></registry-form-quay>
<registry-form-azure
@ -138,7 +139,6 @@
action-in-progress="$ctrl.state.actionInProgress"
reset-defaults="$ctrl.useDefaultGitlabConfiguration"
></registry-form-gitlab>
<registry-form-dockerhub
ng-if="$ctrl.model.Type === $ctrl.RegistryTypes.DOCKERHUB"
model="$ctrl.model"

View File

@ -149,6 +149,8 @@ class CreateRegistryController {
$onInit() {
return this.$async(async () => {
this.model = new RegistryCreateFormValues();
this.model.Type = RegistryTypes.DOCKERHUB;
this.selectDockerHub();
const from = this.$transition$.from();
const params = this.$transition$.params('from');

View File

@ -4,12 +4,29 @@
<div class="col-sm-12">
<rd-widget>
<rd-widget-body>
<form class="form-horizontal">
<form class="form-horizontal" name="editRegistry">
<!-- provider -->
<div class="form-group">
<label for="registry_name" class="col-sm-3 col-lg-2 control-label text-left">Provider</label>
<div class="col-sm-9 col-lg-10">
<input type="text" class="form-control" ng-model="$ctrl.provider" disabled />
</div>
</div>
<!-- name-input -->
<div class="form-group">
<label for="registry_name" class="col-sm-3 col-lg-2 control-label text-left">Name</label>
<div class="col-sm-9 col-lg-10">
<input type="text" class="form-control" id="registry_name" ng-model="$ctrl.formValues.Name" placeholder="e.g. my-registry" ng-change="$ctrl.onChangeName()" />
<input
type="text"
class="form-control"
id="registry_name"
name="registry_name"
ng-model="$ctrl.registry.Name"
placeholder="e.g. my-registry"
ng-change="$ctrl.onChangeName()"
required
/>
</div>
</div>
<div class="form-group" ng-show="$ctrl.state.nameAlreadyExists">
@ -19,15 +36,66 @@
</div>
</div>
</div>
<div class="form-group" ng-show="editRegistry.registry_name.$invalid">
<div class="col-sm-12 small text-warning">
<div ng-messages="editRegistry.registry_name.$error">
<p ng-message="required"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> This field is required.</p>
</div>
</div>
</div>
<!-- !name-input -->
<!-- registry-url-input -->
<div class="form-group" ng-if="registry.Type !== RegistryTypes.DOCKERHUB && registry.Type !== RegistryTypes.QUAY && registry.Type !== RegistryTypes.GITLAB">
<div class="form-group">
<label for="registry_url" class="col-sm-3 col-lg-2 control-label text-left">
Registry URL
<portainer-tooltip message="'URL or IP address of a Docker registry. Any protocol or trailing slash will be stripped if present.'"> </portainer-tooltip>
</label>
<div class="col-sm-9 col-lg-10">
<input type="text" class="form-control" id="registry_url" ng-model="$ctrl.registry.URL" placeholder="e.g. 10.0.0.10:5000 or myregistry.domain.tld" />
<input
type="text"
class="form-control"
id="registry_url"
name="registry_url"
ng-model="$ctrl.registry.URL"
placeholder="e.g. 10.0.0.10:5000 or myregistry.domain.tld"
ng-disabled="$ctrl.registry.Type === $ctrl.RegistryTypes.DOCKERHUB || $ctrl.registry.Type === $ctrl.RegistryTypes.QUAY || $ctrl.registry.Type === $ctrl.RegistryTypes.GITLAB"
required
/>
</div>
</div>
<div class="form-group" ng-show="editRegistry.registry_url.$invalid">
<div class="col-sm-12 small text-warning">
<div ng-messages="editRegistry.registry_url.$error">
<p ng-message="required"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> This field is required.</p>
</div>
</div>
</div>
<!-- base-url-input -->
<div ng-if="$ctrl.registry.Type === $ctrl.RegistryTypes.PROGET">
<div class="form-group">
<label for="registry_base_url" class="col-sm-3 col-lg-2 control-label text-left">
Base URL
<portainer-tooltip message="'The base URL of the ProGet registry.'"> </portainer-tooltip>
</label>
<div class="col-sm-9 col-lg-10">
<input
type="text"
class="form-control"
id="registry_base_url"
name="registry_base_url"
ng-model="$ctrl.registry.BaseURL"
placeholder="e.g. 10.0.0.10:5000 or myregistry.domain.tld"
required
/>
</div>
</div>
<div class="form-group" ng-show="editRegistry.registry_base_url.$invalid">
<div class="col-sm-12 small text-warning">
<div ng-messages="editRegistry.registry_base_url.$error">
<p ng-message="required"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> This field is required.</p>
</div>
</div>
</div>
</div>
<!-- !registry-url-input -->
@ -60,7 +128,14 @@
{{ $ctrl.registry.Type === $ctrl.RegistryTypes.ECR ? 'AWS Access Key' : 'Username' }}
</label>
<div class="col-sm-9 col-lg-10">
<input type="text" class="form-control" id="credentials_username" ng-model="$ctrl.registry.Username" />
<input type="text" class="form-control" id="credentials_username" name="credentials_username" ng-model="$ctrl.registry.Username" required />
</div>
</div>
<div class="form-group" ng-show="editRegistry.credentials_username.$invalid">
<div class="col-sm-12 small text-warning">
<div ng-messages="editRegistry.credentials_username.$error">
<p ng-message="required"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> This field is required.</p>
</div>
</div>
</div>
<!-- !credentials-user -->
@ -70,7 +145,14 @@
{{ $ctrl.passwordLabel() }}
</label>
<div class="col-sm-9 col-lg-10">
<input type="password" class="form-control" id="credentials_password" ng-model="$ctrl.formValues.Password" placeholder="*******" />
<input type="password" class="form-control" id="credentials_password" name="credentials_password" ng-model="$ctrl.Password" autocomplete="off" required />
</div>
</div>
<div class="form-group" ng-show="editRegistry.credentials_password.$invalid">
<div class="col-sm-12 small text-warning">
<div ng-messages="editRegistry.credentials_password.$error">
<p ng-message="required"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> This field is required.</p>
</div>
</div>
</div>
<!-- !credentials-password -->
@ -94,6 +176,13 @@
<input type="text" class="form-control" id="organisation_name" name="organisation_name" ng-model="$ctrl.registry.Quay.OrganisationName" required />
</div>
</div>
<div class="form-group" ng-show="editRegistry.organisation_name.$invalid">
<div class="col-sm-12 small text-warning">
<div ng-messages="editRegistry.organisation_name.$error">
<p ng-message="required"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> This field is required.</p>
</div>
</div>
</div>
<!-- !organisation_name -->
</div>
</div>
@ -103,12 +192,12 @@
<div class="form-group">
<label for="registry_region" class="col-sm-3 col-lg-2 control-label text-left">Region</label>
<div class="col-sm-9 col-lg-10">
<input type="text" class="form-control" id="registry_region" name="registry_region" placeholder="us-west-1" ng-model="$ctrl.registry.Ecr.Region" required />
<input type="text" class="form-control" id="registry_region" name="registry_region" ng-model="$ctrl.registry.Ecr.Region" placeholder="us-west-1" required />
</div>
</div>
<div class="form-group" ng-show="registryFormEcr.registry_region.$invalid">
<div class="form-group" ng-show="editRegistry.registry_region.$invalid">
<div class="col-sm-12 small text-warning">
<div ng-messages="registryFormEcr.registry_region.$error">
<div ng-messages="editRegistry.registry_region.$error">
<p ng-message="required"><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> This field is required.</p>
</div>
</div>
@ -121,7 +210,7 @@
<button
type="button"
class="btn btn-primary btn-sm"
ng-disabled="$ctrl.isUpdateButtonDisabled()"
ng-disabled="$ctrl.isUpdateButtonDisabled() || editRegistry.$invalid"
ng-click="$ctrl.updateRegistry()"
button-spinner="$ctrl.state.actionInProgress"
>

View File

@ -13,9 +13,7 @@ export default class RegistryController {
loading: false,
};
this.formValues = {
Password: '',
};
this.Password = '';
}
passwordLabel() {
@ -35,8 +33,7 @@ export default class RegistryController {
try {
this.state.actionInProgress = true;
const registry = this.registry;
registry.Password = this.formValues.Password;
registry.Name = this.formValues.Name;
registry.Password = this.Password;
await this.RegistryService.updateRegistry(registry);
this.Notifications.success('Registry successfully updated');
@ -50,7 +47,7 @@ export default class RegistryController {
}
onChangeName() {
this.state.nameAlreadyExists = _.includes(this.registriesNames, this.formValues.Name);
this.state.nameAlreadyExists = _.includes(this.registriesNames, this.registry.Name);
}
isUpdateButtonDisabled() {
@ -63,6 +60,26 @@ export default class RegistryController {
);
}
getRegistryProvider(registryType) {
switch (registryType) {
case RegistryTypes.QUAY:
return 'Quay.io';
case RegistryTypes.AZURE:
return 'Azure';
case RegistryTypes.CUSTOM:
return 'Custom';
case RegistryTypes.GITLAB:
return 'Gitlab';
case RegistryTypes.PROGET:
return 'ProGet';
case RegistryTypes.DOCKERHUB:
return 'Docker Hub';
case RegistryTypes.ECR:
return 'AWS ECR';
default:
return '';
}
}
async $onInit() {
try {
this.state.loading = true;
@ -70,7 +87,7 @@ export default class RegistryController {
const registryId = this.$state.params.id;
const registry = await this.RegistryService.registry(registryId);
this.registry = registry;
this.formValues.Name = registry.Name;
this.provider = this.getRegistryProvider(registry.Type);
const registries = await this.RegistryService.registries();
_.pullAllBy(registries, [registry], 'Id');