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/config/config-setup-tool.html
Joseph Schorr b3d1d7227c Add support to Keystone Auth for external user linking
Also adds Keystone V3 support
2016-10-27 15:42:03 -04:00

1184 lines
48 KiB
HTML

<div class="config-setup-tool-element">
<div class="cor-loader" ng-if="!config"></div>
<div ng-show="config && config['SUPER_USERS']">
<form id="configform" name="configform">
<!-- License -->
<div class="co-panel">
<div class="co-panel-heading">
<i class="fa fa-credit-card-alt"></i> License
</div>
<div class="co-panel-body">
<div class="config-license-field"></div>
</div>
</div>
<!-- Basic Configuration -->
<div class="co-panel">
<div class="co-panel-heading">
<i class="fa fa-gears"></i> Basic Configuration
</div>
<div class="co-panel-body">
<table class="config-table">
<tr>
<td>Enterprise Logo URL:</td>
<td>
<span class="config-string-field" binding="config.ENTERPRISE_LOGO_URL"
placeholder="http://example.com/logo.png"></span>
<div class="help-text">
Enter the full URL to your company's logo.
</div>
</td>
<td>
<img class="registry-logo-preview" ng-src="{{ config.ENTERPRISE_LOGO_URL }}">
</td>
</tr>
<tr>
<td class="non-input">Contact Information:</td>
<td colspan="2">
<span class="config-contacts-field" binding="config.CONTACT_INFO"></span>
<div class="help-text" style="margin-top: 10px;">
Information to show in the Contact Page. If none specified, CoreOS contact information
is displayed.
</div>
</td>
</tr>
<tr>
<td class="non-input">Anonymous Access:</td>
<td colspan="2">
<div class="config-bool-field" binding="config.FEATURE_ANONYMOUS_ACCESS">
Enable Anonymous Access
</div>
<div class="help-text">
If enabled, public repositories and search can be accessed by anyone that can
reach the registry, even if they are not authenticated. Disable to only allow
authenticated users to view and pull "public" resources.
</div>
</td>
</tr>
<tr>
<td class="non-input">User Creation:</td>
<td colspan="2">
<div class="config-bool-field" binding="config.FEATURE_USER_CREATION">
Enable Open User Creation
</div>
<div class="help-text">
If enabled, user accounts can be created by anyone.
Users can always be created in the users panel under this superuser view.
</div>
</td>
</tr>
<tr>
<td class="non-input">Encrypted Client Password:</td>
<td colspan="2">
<div class="config-bool-field" binding="config.FEATURE_REQUIRE_ENCRYPTED_BASIC_AUTH">
Require Encrypted Client Passwords
</div>
<div class="help-text">
If enabled, users will not be able to login from the Docker command
line with a non-encrypted password and must generate an encrypted
password to use.
</div>
<div class="help-text" ng-if="config.AUTHENTICATION_TYPE != 'Database'">
This feature is <strong>highly recommended</strong> for setups with external authentication, as Docker currently stores passwords in <strong>plaintext</strong> on user's machines.
</div>
</td>
</tr>
<tr ng-show="config.FEATURE_MAILING">
<td class="non-input">Team Invitations:</td>
<td colspan="2">
<div class="config-bool-field" binding="config.FEATURE_REQUIRE_TEAM_INVITE">
Require Team Invitations
</div>
<div class="help-text">
If enabled, when adding a new user to a team, they will receive an invitation to join the team, with the option to decline.
Otherwise, users will be immediately part of a team when added by a team administrator.
</div>
</td>
</tr>
</table>
</div>
</div>
<!-- Server Configuration -->
<div class="co-panel">
<div class="co-panel-heading">
<i class="fa fa-cloud"></i> Server Configuration
</div>
<div class="co-panel-body">
<table class="config-table">
<tr>
<td>Server Hostname:</td>
<td>
<span class="config-string-field" binding="config.SERVER_HOSTNAME"
placeholder="Hostname (and optional port if non-standard)"
pattern="{{ HOSTNAME_REGEX }}"></span>
<div class="help-text">
The HTTP host (and optionally the port number if a non-standard HTTP/HTTPS port) of the location
where the registry will be accessible on the network
</div>
</td>
</tr>
<tr>
<td>TLS:</td>
<td>
<select class="form-control" ng-model="mapped.TLS_SETTING">
<option value="internal-tls">Quay Enterprise handles TLS</option>
<option value="external-tls">My own load balancer handles TLS (Not Recommended)</option>
<option value="none">None (Not For Production)</option>
</select>
<div class="co-alert co-alert-danger" ng-if="mapped.TLS_SETTING == 'none'" style="margin-bottom: 20px">
Running without TLS should not be used for production workloads!
</div>
<div class="co-alert co-alert-warning" ng-if="mapped.TLS_SETTING == 'external-tls'" style="margin-bottom: 20px">
Terminating TLS outside of Quay Enterprise can result in unusual behavior if the external load balancer is not
configured properly. <strong>This option is not recommended for simple setups</strong>. Please contact support
if you encounter problems while using this option.
</div>
<div class="co-alert co-alert-info" ng-if="mapped.TLS_SETTING == 'internal-tls'" style="margin-bottom: 20px">
Enabling TLS also enables <a href="https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security">HTTP Strict Transport Security</a>.<br/>
This prevents downgrade attacks and cookie theft, but browsers will reject all future insecure connections on this hostname.
</div>
<table class="config-table" ng-if="mapped.TLS_SETTING == 'internal-tls'">
<tr>
<td class="non-input">Certificate:</td>
<td>
<span class="config-file-field" filename="ssl.cert" has-file="hasfile.SSLCert"></span>
<div class="help-text">
The certificate must be in PEM format.
</div
</td>
</tr>
<tr>
<td class="non-input">Private key:</td>
<td>
<span class="config-file-field" filename="ssl.key" has-file="hasfile.SSLKey"></span>
</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
</div>
<!-- Redis -->
<div class="co-panel">
<div class="co-panel-heading">
<img src="/static/img/redis-small.png"> redis
</div>
<div class="co-panel-body">
<div class="description">
<p>A <a href="http://redis.io" ng-safenewtab>redis</a> key-value store is required for real-time events and build logs.</p>
</div>
<table class="config-table">
<tr>
<td>Redis Hostname:</td>
<td>
<span class="config-string-field" binding="mapped.redis.host"
placeholder="The redis server hostname"
pattern="{{ HOSTNAME_REGEX }}"
validator="validateHostname(value)">></span>
</td>
</tr>
<tr>
<td>Redis port:</td>
<td>
<span class="config-numeric-field" binding="mapped.redis.port" default-value="6379"></span>
<div class="help-text">
Access to this port and hostname must be allowed from all hosts running
the enterprise registry
</div>
</td>
</tr>
<tr>
<td>Redis password:</td>
<td>
<input class="form-control" type="password" ng-model="mapped.redis.password"
placeholder="Optional password for connecting to redis">
</td>
</tr>
</table>
</div>
</div> <!-- /Redis -->
<!-- Registry Storage -->
<div class="co-panel">
<div class="co-panel-heading">
<i class="fa fa-download"></i> Registry Storage
</div>
<div class="co-panel-body">
<div class="description">
<p>
Registry images can be stored either locally or in a remote storage system.
<strong>A remote storage system is required for high-availability systems.</strong>
</p>
<div class="config-bool-field feature-storage-replication" binding="config.FEATURE_STORAGE_REPLICATION">
Enable Storage Replication
<div class="help-text">
If enabled, replicates storage to other regions. See <a href="https://tectonic.com/quay-enterprise/docs/latest/geo-replication.html" ng-safenewtab>documentation</a> for more information.
</div>
</div>
<div class="storage-config" ng-class="$last ? 'last' : ''" ng-repeat="sc in storageConfig">
<table class="config-table">
<tr>
<td class="non-input">Location ID:</td>
<td>
<input class="form-control" ng-if="allowChangeLocationStorageConfig(sc.location)" ng-class="storageConfigError[$index].location ? 'ng-invalid' : ''" ng-model="sc.location" ng-pattern="/^[a-zA-Z0-9_-]+$/" required>
<div ng-if="!allowChangeLocationStorageConfig(sc.location)">
{{ sc.location }}
</div>
<div class="co-alert co-alert-danger" ng-show="storageConfigError[$index].location">
{{ storageConfigError[$index].location }}
</div>
<div class="input-util" ng-if="allowRemoveStorageConfig(sc.location)"><a class="remove-link" ng-click="removeStorageConfig(sc)">Remove</a></div>
</td>
</tr>
<tr ng-if="config.FEATURE_STORAGE_REPLICATION">
<td class="non-input">Set Default:</td>
<td>
<div class="config-bool-field" binding="sc.defaultLocation">
Replicate to storage engine by default
</div>
</td>
</tr>
<tr>
<td class="non-input">Storage Engine:</td>
<td>
<select class="form-control" ng-class="storageConfigError[$index].engine ? 'ng-invalid' : ''" ng-model="sc.data[0]">
<option value="LocalStorage">Locally mounted directory</option>
<option value="S3Storage">Amazon S3</option>
<option value="GoogleCloudStorage">Google Cloud Storage</option>
<option value="RadosGWStorage">Ceph Object Gateway (RADOS)</option>
<option value="SwiftStorage">OpenStack Storage (Swift)</option>
</select>
<div class="co-alert co-alert-danger" ng-if="storageConfigError[$index].engine">
{{ storageConfigError[$index].engine }}
</div>
</td>
</tr>
<!-- Fields -->
<tr ng-repeat="field in STORAGE_CONFIG_FIELDS[sc.data[0]]">
<td>{{ field.title }}:</td>
<td>
<span class="config-map-field"
binding="sc.data[1][field.name]"
ng-if="field.kind == 'map'"
keys="field.keys"></span>
<span class="config-string-field"
binding="sc.data[1][field.name]"
placeholder="{{ field.placeholder }}"
ng-if="field.kind == 'text'"
is-optional="field.optional"></span>
<span class="config-bool-field"
binding="sc.data[1][field.name]"
ng-if="field.kind == 'bool'">
{{ field.placeholder }}
</span>
<div ng-if="field.kind == 'option'">
<select class="form-control" ng-model="sc.data[1][field.name]">
<option ng-repeat="value in field.values" value="{{ value }}"
ng-selected="sc.data[1][field.name] == value">{{ value }}</option>
</select>
</div>
<div class="help-text" ng-if="field.help_text">
{{ field.help_text }}
</div>
<div class="help-text" ng-if="field.help_url">
See <a href="{{ field.help_url }}" ng-safenewtab>Documentation</a> for more information
</div>
</td>
</tr>
</table>
</div>
<div class="add-storage-link" ng-if="canAddStorageConfig()">
<a ng-click="addStorageConfig()">Add Additional Storage Engine</a>
</div>
</div>
</div>
</div>
<!-- Security Scanner -->
<div class="co-panel">
<div class="co-panel-heading">
<i class="fa fa-bug"></i> Security Scanner
</div>
<div class="co-panel-body">
<div class="description">
<p>If enabled, all images pushed to Quay will be scanned via the external security scanning service, with vulnerability information available in the UI and API, as well
as async notification support.
</p>
</div>
<div class="config-bool-field" binding="config.FEATURE_SECURITY_SCANNER">
Enable Security Scanning
</div>
<div class="co-alert co-alert-info" ng-if="config.FEATURE_SECURITY_SCANNER" style="margin-top: 20px;">
A scanner compliant with the Quay Security Scanning API must be running to use this feature. Documentation on running <a href="https://github.com/coreos/clair" ng-safenewtab>Clair</a> can be found at <a href="https://tectonic.com/quay-enterprise/docs/latest/clair.html" ng-safenewtab>Running Clair Security Scanner</a>.
</div>
<table class="config-table" ng-if="config.FEATURE_SECURITY_SCANNER">
<tr>
<td>Security Scanner Endpoint:</td>
<td>
<span class="config-string-field" binding="config.SECURITY_SCANNER_ENDPOINT"
placeholder="Security Scanner API endpoint (Example: http://myhost:6060)"
pattern="http(s)?://.+"></span>
<div class="help-text">
The HTTP URL at which the security scanner is running.
</div>
</td>
</tr>
<tr>
<td>Authentication Key:</td>
<td>
<span class="config-service-key-field" service-name="{{ config.SECURITY_SCANNER_ISSUER_NAME || 'secscan' }}"></span>
<div class="help-text">
The security scanning service requires an authorized service key to speak to Quay. Once setup, the key
can be managed in the Service Keys panel under the Super User Admin Panel.
</div>
</td>
</tr>
</table>
</div>
</div>
<!-- ACI Conversion -->
<div class="co-panel">
<div class="co-panel-heading">
<i class="fa rocket-icon" style="width: 20px; height: 20px; background-size: cover; vertical-align: middle;"></i> <a href="http://github.com/coreos/rkt" ng-safenewtab>rkt</a> Conversion
</div>
<div class="co-panel-body">
<div class="description">
<p>If enabled, all images in the registry can be fetched via <code>rkt fetch</code> or any other <a href="https://github.com/appc/spec/blob/master/spec/discovery.md" ng-safenewtab>AppC discovery</a>-compliant implementation.</p>
</div>
<div class="config-bool-field" binding="config.FEATURE_ACI_CONVERSION">
Enable ACI Conversion
</div>
<div class="co-alert co-alert-info" ng-if="config.FEATURE_ACI_CONVERSION" style="margin-top: 20px;">
Documentation on generating these keys can be found at <a href="https://tectonic.com/quay-enterprise/docs/latest/aci-signing-keys.html" ng-safenewtab>Generating ACI Signing Keys</a>.
</div>
<table class="config-table" ng-if="config.FEATURE_ACI_CONVERSION">
<tr>
<td class="non-input">GPG2 Public Key File:</td>
<td>
<span class="config-file-field" filename="signing-public.gpg" has-file="hasfile.gpgSigningPublic"></span>
<div class="help-text">
The certificate must be in PEM format.
</div
</td>
</tr>
<tr>
<td class="non-input">GPG2 Private Key File:</td>
<td>
<span class="config-file-field" filename="signing-private.gpg" has-file="hasfile.gpgSigningPrivate"></span>
</td>
</tr>
<tr>
<td class="non-input">GPG2 Private Key Name:</td>
<td>
<span class="config-string-field" binding="config.GPG2_PRIVATE_KEY_NAME"
placeholder="Name of the private key in the private key file (Example: EAB32227)"></span>
</td>
</tr>
</table>
</div>
</div>
<!-- E-mail -->
<div class="co-panel">
<div class="co-panel-heading">
<i class="fa fa-envelope"></i> E-mail
</div>
<div class="co-panel-body">
<div class="description">
<p>Valid e-mail server configuration is required for notification e-mails and the ability of
users to reset their passwords.</p>
</div>
<div class="config-bool-field" binding="config.FEATURE_MAILING">
Enable E-mails
</div>
<table class="config-table" ng-if="config.FEATURE_MAILING">
<tr>
<td>SMTP Server:</td>
<td>
<span class="config-string-field" binding="config.MAIL_SERVER"
placeholder="SMTP server for sending e-mail"
pattern="{{ HOSTNAME_REGEX }}"
validator="validateHostname(value)">></span>
</td>
</tr>
<tr>
<td>SMTP Server Port:</td>
<td>
<span class="config-numeric-field" binding="config.MAIL_PORT"
default-value="587"></span>
</td>
</tr>
<tr>
<td>TLS:</td>
<td>
<div class="config-bool-field" binding="config.MAIL_USE_TLS">
Require TLS
</div>
</td>
</tr>
<tr>
<td>Mail Sender:</td>
<td>
<input class="form-control" type="email" ng-model="config.MAIL_DEFAULT_SENDER"
placeholder="E-mail address"></span>
<div class="help-text">
E-mail address from which all e-mails are sent. If not specified,
<code>support@quay.io</code> will be used.
</div>
</td>
</tr>
<tr>
<td>Authentication:</td>
<td>
<div class="config-bool-field" binding="config.MAIL_USE_AUTH">
Requires Authentication
</div>
<table class="config-table" ng-if="config.MAIL_USE_AUTH">
<tr>
<td>Username:</td>
<td>
<span class="config-string-field" binding="config.MAIL_USERNAME"
placeholder="Username for authentication"></span>
</td>
</tr>
<tr>
<td>Password:</td>
<td>
<input class="form-control" type="password"
ng-model="config.MAIL_PASSWORD"
placeholder="Password for authentication"></span>
</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
</div> <!-- /E-mail -->
<!-- Authentication -->
<div class="co-panel">
<div class="co-panel-heading">
<i class="fa fa-users"></i> Authentication
</div>
<div class="co-panel-body">
<div class="description">
<p>
Authentication for the registry can be handled by either the registry itself, LDAP or external JWT endpoint.
<br>
Additional external authentication providers (such as GitHub) can be used on top of this choice.
</p>
</div>
<div class="co-alert co-alert-warning" ng-if="config.AUTHENTICATION_TYPE != 'Database' && !config.FEATURE_REQUIRE_ENCRYPTED_BASIC_AUTH">
It is <strong>highly recommended</strong> to require encrypted client passwords. External passwords used in the Docker client will be stored in <strong>plaintext</strong>!
<a ng-click="config.FEATURE_REQUIRE_ENCRYPTED_BASIC_AUTH = true">Enable this requirement now</a>.
</div>
<div class="co-alert co-alert-success" ng-if="config.AUTHENTICATION_TYPE != 'Database' && config.FEATURE_REQUIRE_ENCRYPTED_BASIC_AUTH">
Note: The "Require Encrypted Client Passwords" feature is currently enabled which will
prevent passwords from being saved as plaintext by the Docker client.
</div>
<table class="config-table">
<tr>
<td class="non-input">Authentication:</td>
<td>
<select class="form-control" ng-model="config.AUTHENTICATION_TYPE">
<option value="Database">Local Database</option>
<option value="LDAP">LDAP</option>
<option value="Keystone">Keystone (OpenStack Identity)</option>
<option value="JWT">JWT Custom Authentication</option>
</select>
</td>
</tr>
</table>
<!-- Keystone Authentication -->
<table class="config-table" ng-if="config.AUTHENTICATION_TYPE == 'Keystone'">
<tr>
<td>Keystone API Version:</td>
<td>
<select ng-model="config.KEYSTONE_AUTH_VERSION">
<option value="2">2.0</option>
<option value="3">V3</option>
</select>
</td>
</tr>
<tr>
<td>Keystone Authentication URL:</td>
<td>
<span class="config-string-field" binding="config.KEYSTONE_AUTH_URL"
pattern="http(s)?://.+"></span>
<div class="help-text">
The URL (starting with http or https) of the Keystone Server endpoint for auth.
</div>
</td>
</tr>
<tr>
<td>Keystone Administrator Username:</td>
<td>
<span class="config-string-field" binding="config.KEYSTONE_ADMIN_USERNAME"></span>
<div class="help-text">
The username for the Keystone admin.
</div>
</td>
</tr>
<tr>
<td>Keystone Administrator Password:</td>
<td>
<input type="password" ng-model="config.KEYSTONE_ADMIN_PASSWORD"
class="form-control" required></span>
<div class="help-text">
The password for the Keystone admin.
</div>
</td>
</tr>
<tr>
<td>Keystone Administrator Tenant:</td>
<td>
<span class="config-string-field" binding="config.KEYSTONE_ADMIN_TENANT"></span>
<div class="help-text">
The tenant (project/group) that contains the administrator user.
</div>
</td>
</tr>
</table>
<!-- JWT Custom Authentication -->
<div class="co-alert co-alert-info" ng-if="config.AUTHENTICATION_TYPE == 'JWT'">
JSON Web Token authentication allows your organization to provide an HTTP endpoint that
verifies user credentials on behalf of <span class="registry-name"></span>.
<br>
Documentation
on the API required can be found here: <a href="https://github.com/coreos/jwt-auth-example" ng-safenewtab>https://github.com/coreos/jwt-auth-example</a>.
</div>
<table class="config-table" ng-if="config.AUTHENTICATION_TYPE == 'JWT'">
<tr>
<td>Authentication Issuer:</td>
<td>
<span class="config-string-field" binding="config.JWT_AUTH_ISSUER"></span>
<div class="help-text">
The id of the issuer signing the JWT token. Must be unique to your organization.
</div>
</td>
</tr>
<tr>
<td>Public Key:</td>
<td>
<span class="config-file-field" filename="jwt-authn.cert" has-file="hasfile.JWTCert"></span>
<div class="help-text">
A certificate containing the public key portion of the key pair used to sign
the JSON Web Tokens. This file must be in PEM format.
</div
</td>
</tr>
<tr>
<td>User Verification Endpoint:</td>
<td>
<span class="config-string-field" binding="config.JWT_VERIFY_ENDPOINT"
pattern="http(s)?://.+"></span>
<div class="help-text">
The URL (starting with http or https) on the JWT authentication server for verifying username and password credentials.
</div>
<div class="help-text" style="margin-top: 6px;">
Credentials will be sent in the <code>Authorization</code> header as Basic Auth, and this endpoint should return <code>200 OK</code> on success (or a <code>4**</code> otherwise).
</div>
</td>
</tr>
<tr>
<td>User Query Endpoint:</td>
<td>
<span class="config-string-field" binding="config.JWT_QUERY_ENDPOINT"
pattern="http(s)?://.+" is-optional="true"></span>
<div class="help-text">
The URL (starting with http or https) on the JWT authentication server for looking up
users based on a prefix query. This is optional.
</div>
<div class="help-text" style="margin-top: 6px;">
The prefix query will be sent as a query parameter with name <code>query</code>.
</div>
</td>
</tr>
<tr>
<td>User Lookup Endpoint:</td>
<td>
<span class="config-string-field" binding="config.JWT_GETUSER_ENDPOINT"
pattern="http(s)?://.+" is-optional="true"></span>
<div class="help-text">
The URL (starting with http or https) on the JWT authentication server for looking up
a user by username or email address.
</div>
<div class="help-text" style="margin-top: 6px;">
The username or email address will be sent as a query parameter with name <code>username</code>.
</div>
</td>
</tr>
</table>
<!-- LDAP Authentication -->
<table class="config-table" ng-if="config.AUTHENTICATION_TYPE == 'LDAP'">
<tr>
<td>LDAP URI:</td>
<td>
<span class="config-string-field" binding="config.LDAP_URI"
pattern="ldap(s)?://.+"></span>
<div class="help-text">
The full LDAP URI, including the ldap:// or ldaps:// prefix.
</div>
</td>
</tr>
<tr>
<td>Base DN:</td>
<td>
<span class="config-string-list-field" item-title="DN piece" item-delimiter="," binding="config.LDAP_BASE_DN"></span>
<div class="help-text">
A Distinguished Name path which forms the base path for looking up all LDAP records.
</div>
<div class="help-text">
Example: dc=my,dc=domain,dc=com
</div>
</td>
</tr>
<tr>
<td>User Relative DN:</td>
<td>
<span class="config-string-list-field" item-title="RDN piece" item-delimiter="," binding="config.LDAP_USER_RDN"></span>
<div class="help-text">
A Distinguished Name path which forms the base path for looking up all user LDAP records,
relative to the Base DN defined above.
</div>
<div class="help-text">
Example: ou=employees
</div>
</td>
</tr>
<tr>
<td>Secondary User Relative DNs:</td>
<td>
<span class="config-list-field" item-title="RDN" binding="config.LDAP_SECONDARY_USER_RDNS"></span>
<div class="help-text">
A list of Distinguished Name path(s) which forms the secondary base path(s) for
looking up all user LDAP records, relative to the Base DN defined above. These path(s)
will be tried if the user is not found via the primary relative DN.
</div>
<div class="help-text">
Example: [ou=employees]
</div>
</td>
</tr>
<tr>
<td>Administrator DN:</td>
<td><span class="config-string-field" binding="config.LDAP_ADMIN_DN"></span>
<div class="help-text">
The Distinguished Name for the Administrator account. This account must be able to login and view the records for all user accounts.
</div>
<div class="help-text">
Example: uid=admin,ou=employees,dc=my,dc=domain,dc=com
</div>
</td>
</tr>
<tr>
<td>Administrator DN Password:</td>
<td>
<div class="co-alert co-alert-warning">
Note: This will be stored in
<strong>plaintext</strong> inside the config.yaml, so setting up a dedicated account or using
<a href="http://tools.ietf.org/id/draft-stroeder-hashed-userpassword-values-01.html" ng-safenewtab>a password hash</a> is <strong>highly</strong> recommended.
</div>
<span class="config-string-field" binding="config.LDAP_ADMIN_PASSWD"></span>
<div class="help-text">
The password for the Administrator DN.
</div>
</td>
</tr>
<tr>
<td>UID Attribute:</td>
<td>
<span class="config-string-field" binding="config.LDAP_UID_ATTR" default-value="uid"></span>
<div class="help-text">
The name of the property field in your LDAP user records that stores your
users' username. Typically "uid".
</div>
</td>
</tr>
<tr>
<td>Mail Attribute:</td>
<td>
<span class="config-string-field" binding="config.LDAP_EMAIL_ATTR" default-value="mail"></span>
<div class="help-text">
The name of the property field in your LDAP user records that stores your
users' e-mail address(es). Typically "mail".
</div>
</td>
</tr>
<tr ng-if="config.LDAP_URI.indexOf('ldaps://') == 0">
<td class="non-input">Custom TLS Certificate:</td>
<td>
<span class="config-file-field" filename="ldap.crt" has-file="hasfile.LDAPTLSCert"></span>
<div class="help-text">
If specified, the certificate (in PEM format) for the LDAP TLS connection.
</div
</td>
</tr>
<tr ng-if="config.LDAP_URI.indexOf('ldaps://') == 0">
<td class="non-input">Allow insecure:</td>
<td>
<div class="config-bool-field" binding="config.LDAP_ALLOW_INSECURE_FALLBACK">
Allow fallback to non-TLS connections
</div>
<div class="help-text">
If enabled, LDAP will fallback to <strong>insecure non-TLS connections</strong> if TLS does not succeed.
</div>
</td>
</tr>
</table>
</div>
</div> <!-- /Authentication -->
<!-- GitHub Authentication -->
<div class="co-panel">
<div class="co-panel-heading">
<i class="fa fa-github"></i> GitHub (Enterprise) Authentication
</div>
<div class="co-panel-body">
<div class="description">
<p>
If enabled, users can use GitHub or GitHub Enterprise to authenticate to the registry.
</p>
<p>
<strong>Note:</strong> A registered GitHub (Enterprise) OAuth application is required.
View instructions on how to
<a href="https://coreos.com/docs/enterprise-registry/github-app/" ng-safenewtab>
Create an OAuth Application in GitHub
</a>
</p>
</div>
<div class="config-bool-field" binding="config.FEATURE_GITHUB_LOGIN">
Enable GitHub Authentication
</div>
<table class="config-table" ng-if="config.FEATURE_GITHUB_LOGIN">
<tr>
<td>GitHub:</td>
<td>
<select class="form-control" ng-model="mapped.GITHUB_LOGIN_KIND">
<option value="hosted">GitHub.com</option>
<option value="enterprise">GitHub Enterprise</option>
</select>
</td>
</tr>
<tr ng-if="mapped.GITHUB_LOGIN_KIND == 'enterprise'">
<td>GitHub Endpoint:</td>
<td>
<span class="config-string-field"
binding="config.GITHUB_LOGIN_CONFIG.GITHUB_ENDPOINT"
placeholder="https://my.githubserver"
pattern="{{ GITHOST_REGEX }}">
</span>
<div class="help-text">
The GitHub Enterprise endpoint. Must start with http:// or https://.
</div>
</td>
</tr>
<tr>
<td>OAuth Client ID:</td>
<td>
<span class="config-string-field" binding="config.GITHUB_LOGIN_CONFIG.CLIENT_ID">
</span>
</td>
</tr>
<tr>
<td>OAuth Client Secret:</td>
<td>
<span class="config-string-field" binding="config.GITHUB_LOGIN_CONFIG.CLIENT_SECRET">
</span>
</td>
</tr>
<tr>
<td>Organization Filtering:</td>
<td>
<div class="config-bool-field" binding="config.GITHUB_LOGIN_CONFIG.ORG_RESTRICT">
Restrict By Organization Membership
</div>
<div class="help-text" style="margin-bottom: 20px;">
If enabled, only members of specified GitHub
<span ng-if="mapped.GITHUB_LOGIN_KIND == 'enterprise'">Enterprise</span> organizations will be allowed to login via GitHub
<span ng-if="mapped.GITHUB_LOGIN_KIND == 'enterprise'">Enterprise</span>.
</div>
<span class="config-list-field"
item-title="Organization ID"
binding="config.GITHUB_LOGIN_CONFIG.ALLOWED_ORGANIZATIONS"
ng-if="config.GITHUB_LOGIN_CONFIG.ORG_RESTRICT">
</span>
</td>
</tr>
</table>
</div>
</div> <!-- /GitHub Authentication -->
<!-- Google Authentication -->
<div class="co-panel">
<div class="co-panel-heading">
<i class="fa fa-google"></i> Google Authentication
</div>
<div class="co-panel-body">
<div class="description">
<p>
If enabled, users can use Google to authenticate to the registry.
</p>
<p>
<strong>Note:</strong> A registered Google OAuth application is required.
Visit the
<a href="https://console.developers.google.com" ng-safenewtab>
Google Developer Console
</a>
to register an application.
</p>
</div>
<div class="config-bool-field" binding="config.FEATURE_GOOGLE_LOGIN">
Enable Google Authentication
</div>
<table class="config-table" ng-if="config.FEATURE_GOOGLE_LOGIN">
<tr>
<td>OAuth Client ID:</td>
<td>
<span class="config-string-field" binding="config.GOOGLE_LOGIN_CONFIG.CLIENT_ID">
</span>
</td>
</tr>
<tr>
<td>OAuth Client Secret:</td>
<td>
<span class="config-string-field" binding="config.GOOGLE_LOGIN_CONFIG.CLIENT_SECRET">
</span>
</td>
</tr>
</table>
</div>
</div> <!-- /Google Authentication -->
<!-- Build Support -->
<div class="co-panel">
<div class="co-panel-heading">
<i class="fa fa-tasks"></i> Dockerfile Build Support
</div>
<div class="co-panel-body">
<div class="description">
If enabled, users can submit Dockerfiles to be built and pushed by the Enterprise Registry.
</div>
<div class="config-bool-field" binding="config.FEATURE_BUILD_SUPPORT">
Enable Dockerfile Build
</div>
<div ng-if="config.FEATURE_BUILD_SUPPORT" style="margin-top: 10px">
<strong>Note: Build workers are required for this feature.</strong>
See <a href="https://coreos.com/docs/enterprise-registry/build-support/" ng-safenewtab>Adding Build Workers</a> for instructions on how to setup build workers.
</div>
</div>
</div> <!-- /Build Support -->
<!-- GitHub Trigger -->
<div class="co-panel" ng-if="config.FEATURE_BUILD_SUPPORT" style="margin-top: 20px;">
<div class="co-panel-heading">
<i class="fa fa-github"></i> GitHub (Enterprise) Build Triggers
</div>
<div class="co-panel-body">
<div class="description">
<p>
If enabled, users can setup GitHub or GitHub Enterprise triggers to invoke Registry builds.
</p>
<p>
<strong>Note:</strong> A registered GitHub (Enterprise) OAuth application (<strong>separate from GitHub Authentication</strong>) is required.
View instructions on how to
<a href="https://coreos.com/docs/enterprise-registry/github-app/" ng-safenewtab>
Create an OAuth Application in GitHub
</a>
</p>
</div>
<div class="config-bool-field" binding="config.FEATURE_GITHUB_BUILD">
Enable GitHub Triggers
</div>
<table class="config-table" ng-if="config.FEATURE_GITHUB_BUILD">
<tr>
<td>GitHub:</td>
<td>
<select class="form-control" ng-model="mapped.GITHUB_TRIGGER_KIND">
<option value="hosted">GitHub.com</option>
<option value="enterprise">GitHub Enterprise</option>
</select>
</td>
</tr>
<tr ng-if="mapped.GITHUB_TRIGGER_KIND == 'enterprise'">
<td>GitHub Endpoint:</td>
<td>
<span class="config-string-field"
binding="config.GITHUB_TRIGGER_CONFIG.GITHUB_ENDPOINT"
placeholder="https://my.githubserver"
pattern="{{ GITHOST_REGEX }}">
</span>
<div class="help-text">
The GitHub Enterprise endpoint. Must start with http:// or https://.
</div>
</td>
</tr>
<tr>
<td>OAuth Client ID:</td>
<td>
<span class="config-string-field" binding="config.GITHUB_TRIGGER_CONFIG.CLIENT_ID">
</span>
</td>
</tr>
<tr>
<td>OAuth Client Secret:</td>
<td>
<span class="config-string-field" binding="config.GITHUB_TRIGGER_CONFIG.CLIENT_SECRET">
</span>
</td>
</tr>
</table>
</div>
</div> <!-- /GitHub Trigger -->
<!-- BitBucket Trigger -->
<div class="co-panel" ng-if="config.FEATURE_BUILD_SUPPORT" style="margin-top: 20px;">
<div class="co-panel-heading">
<i class="fa fa-bitbucket"></i> BitBucket Build Triggers
</div>
<div class="co-panel-body">
<div class="description">
<p>
If enabled, users can setup BitBucket triggers to invoke Registry builds.
</p>
<p>
<strong>Note:</strong> A registered BitBucket OAuth application is required.
View instructions on how to
<a href="https://coreos.com/docs/enterprise-registry/bitbucket-app/" ng-safenewtab>
Create an OAuth Application in BitBucket
</a>
</p>
</div>
<div class="config-bool-field" binding="config.FEATURE_BITBUCKET_BUILD">
Enable BitBucket Triggers
</div>
<table class="config-table" ng-if="config.FEATURE_BITBUCKET_BUILD">
<tr>
<td>OAuth Consumer Key:</td>
<td>
<span class="config-string-field" binding="config.BITBUCKET_TRIGGER_CONFIG.CONSUMER_KEY">
</span>
</td>
</tr>
<tr>
<td>OAuth Consumer Secret:</td>
<td>
<span class="config-string-field" binding="config.BITBUCKET_TRIGGER_CONFIG.CONSUMER_SECRET">
</span>
</td>
</tr>
</table>
</div>
</div> <!-- /BitBucket Trigger -->
<!-- GitLab Trigger -->
<div class="co-panel" ng-if="config.FEATURE_BUILD_SUPPORT" style="margin-top: 20px;">
<div class="co-panel-heading">
<i class="fa fa-gitlab"></i> GitLab Build Triggers
</div>
<div class="co-panel-body">
<div class="description">
<p>
If enabled, users can setup GitLab triggers to invoke Registry builds.
</p>
<p>
<strong>Note:</strong> A registered GitLab OAuth application is required.
Visit the
<a href="{{ config.GITLAB_TRIGGER_CONFIG.GITLAB_ENDPOINT || 'https://gitlab.com' }}/admin/applications" ng-safenewtab>
GitLab applications admin panel
</a>
to create a new application.
</p>
<p>The callback URL to use is:&nbsp;&nbsp;
<code>{{ config.PREFERRED_URL_SCHEME || 'http' }}://{{ config.SERVER_HOSTNAME || 'localhost' }}/oauth2/gitlab/callback/trigger</code>
</p>
</div>
<div class="config-bool-field" binding="config.FEATURE_GITLAB_BUILD">
Enable GitLab Triggers
</div>
<table class="config-table" ng-if="config.FEATURE_GITLAB_BUILD">
<tr>
<td>GitLab:</td>
<td>
<select class="form-control" ng-model="mapped.GITLAB_TRIGGER_KIND">
<option value="hosted">GitLab.com</option>
<option value="enterprise">GitLab CE/EE</option>
</select>
</td>
</tr>
<tr ng-if="mapped.GITLAB_TRIGGER_KIND == 'enterprise'">
<td>GitLab Endpoint:</td>
<td>
<span class="config-string-field"
binding="config.GITLAB_TRIGGER_CONFIG.GITLAB_ENDPOINT"
placeholder="https://my.gitlabserver"
pattern="{{ GITHOST_REGEX }}">
</span>
<div class="help-text">
The GitLab Enterprise endpoint. Must start with http:// or https://.
</div>
</td>
</tr>
<tr>
<td>OAuth Client ID:</td>
<td>
<span class="config-string-field" binding="config.GITLAB_TRIGGER_CONFIG.CLIENT_ID">
</span>
</td>
</tr>
<tr>
<td>OAuth Client Secret:</td>
<td>
<span class="config-string-field" binding="config.GITLAB_TRIGGER_CONFIG.CLIENT_SECRET">
</span>
</td>
</tr>
</table>
</div>
</div> <!-- /GitLab Trigger -->
</form>
<!-- Save Bar -->
<div class="cor-floating-bottom-bar">
<button class="btn" ng-class="mapped.$hasChanges ? 'btn-primary' : 'btn-success'"
ng-click="checkValidateAndSave()" ng-show="configform.$valid">
<i class="fa fa-lg" ng-class="mapped.$hasChanges ? 'fa-dot-circle-o' : 'fa-check-circle'"></i>
<span ng-if="mapped.$hasChanges">Save Configuration Changes</span>
<span ng-if="!mapped.$hasChanges">Configuration Saved</span>
</button>
<button class="btn btn-warning" ng-click="checkValidateAndSave()" ng-show="!configform.$valid"
ng-click="checkValidateAndSave()">
<i class="fa fa-lg fa-sort"></i>
<span ng-if="configform.$error['required'].length">
{{ configform.$error['required'].length }} configuration field<span ng-show="configform.$error['required'].length != 1">s</span> remaining
</span>
<span ng-if="!configform.$error['required'].length">
Invalid configuration field
</span>
</button>
</div>
<!-- Modal message dialog -->
<div class="modal co-dialog fade initial-setup-modal" id="validateAndSaveModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">
Checking your settings
</h4>
</div>
<div class="modal-body">
<div class="service-verification">
<div class="service-verification-row" ng-repeat="serviceInfo in validating">
<span class="quay-spinner" ng-show="serviceInfo.status == 'validating'"></span>
<i class="fa fa-lg fa-check-circle" ng-show="serviceInfo.status == 'success'"></i>
<i class="fa fa-lg fa-warning" ng-show="serviceInfo.status == 'error'"></i>
<span class="service-title">{{ serviceInfo.service.title }}</span>
<div class="service-verification-error" ng-show="serviceInfo.status == 'error'">{{ serviceInfo.errorMessage }}</div>
</div>
</div>
</div>
<!-- Footer: Saving configuration -->
<div class="modal-footer working" ng-show="savingConfiguration">
<span class="cor-loader-inline"></span> Saving Configuration...
</div>
<!-- Footer: Validating -->
<div class="modal-footer working"
ng-show="!savingConfiguration && validationStatus(validating) == 'validating'">
<span class="cor-loader-inline"></span> Validating settings...
<button class="btn btn-default" ng-click="cancelValidation()">
Stop Validating
</button>
</div>
<!-- Footer: Valid Config -->
<div class="modal-footer"
ng-show="!savingConfiguration && validationStatus(validating) == 'success'">
<span class="left-align">
<i class="fa fa-check"></i>
Configuration Validated
</span>
<button class="btn btn-primary"
ng-click="saveConfiguration()"
ng-disabled="savingConfiguration">
<i class="fa fa-upload" style="margin-right: 10px;"></i>Save Configuration
</button>
</div>
<!-- Footer: Invalid Config -->
<div class="modal-footer"
ng-show="!savingConfiguration && validationStatus(validating) == 'failed'">
<span class="left-align">
<i class="fa fa-warning"></i>
Problem Detected
</span>
<button class="btn btn-default" data-dismiss="modal">
Continue Editing
</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
</div>
</div>