blob: a74e4d3b298a7f6a4b2698e30eb7509d415e1810 [file] [log] [blame]
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<div class="x_panel">
<div class="x_title">
<ol class="breadcrumb pull-left">
<li ng-if="!settings.isRequest"><a ng-click="navigateToPath('/delivery-services')">Delivery Services</a></li>
<li ng-if="settings.isRequest"><a ng-click="navigateToPath('/delivery-service-requests')">Delivery Service Requests</a></li>
<li ng-if="settings.isRequest" class="active">{{dsRequest.changeType}}</li>
<li class="active">{{deliveryServiceName}}</li>
</ol>
<div class="pull-right" role="group" ng-if="settings.isRequest">
<div class="btn-group" role="group" uib-dropdown is-open="status.isopen">
<button ng-disabled="dsRequest.status == 'rejected' || dsRequest.status == 'complete'" type="button" class="btn btn-link dropdown-toggle" uib-dropdown-toggle aria-haspopup="true" aria-expanded="false">
{{dsRequest.status | uppercase }}&nbsp;
<span ng-show="dsRequest.status == 'draft' || dsRequest.status == 'submitted' || dsRequest.status == 'pending'" class="caret"></span>
</button>
<ul class="dropdown-menu-right dropdown-menu" uib-dropdown-menu>
<li role="menuitem"><a ng-if="dsRequest.status == 'submitted'" ng-click="editStatus('draft')">Change status to: DRAFT</a></li>
<li role="menuitem"><a ng-if="dsRequest.status == 'draft'" ng-click="editStatus('submitted')">Change status to: SUBMITTED</a></li>
<li role="menuitem"><a ng-if="dsRequest.status == 'pending'" ng-click="editStatus('complete')">Change status to: COMPLETE</a></li>
</ul>
</div>
</div>
<div class="pull-right" role="group">
<button type="button" class="btn btn-danger" ng-if="!settings.isNew && !settings.isRequest" ng-disabled="!deletable()" ng-click="confirmDelete(deliveryService)">{{settings.deleteLabel}}</button>
<button class="btn btn-success" ng-if="!settings.isRequest" ng-disabled="deliveryServiceForm.$pristine || deliveryServiceForm.$invalid || !saveable()" ng-click="save(deliveryService)">{{settings.saveLabel}}</button>
<button type="button" class="btn btn-primary" ng-if="!settings.isRequest && !settings.isNew" title="Delivery Service Charts" ng-if="showChartsButton" ng-click="openCharts(deliveryService)"><i class="fa fa-bar-chart fa-fw"></i></button>
<a class="btn btn-primary" ng-if="!settings.isRequest" ng-href="/#!/delivery-service-requests?xmlId={{deliveryService.xmlId}}">View Linked Delivery Service Requests</a>
<div class="btn-group" ng-if="!settings.isRequest && !settings.isNew" role="group" uib-dropdown is-open="more.isopen">
<button name="moreBtn" type="button" class="btn btn-default dropdown-toggle" uib-dropdown-toggle aria-haspopup="true" aria-expanded="false">
More&nbsp;
<span class="caret"></span>
</button>
<ul class="dropdown-menu-right dropdown-menu" uib-dropdown-menu>
<li role="menuitem"><a ng-click="clone(deliveryService)">Clone Delivery Service</a></li>
<hr class="divider"/>
<li role="menuitem"><a ng-click="viewCharts()">View Charts</a></li>
<hr class="divider"/>
<li role="menuitem"><a ng-click="manageSslKeys()">Manage SSL Keys</a></li>
<hr class="divider"/>
<li role="menuitem"><a ng-click="viewJobs()">Manage Invalidation Requests</a></li>
<li role="menuitem"><a ng-click="viewRegexes()">Manage Regexes</a></li>
<li role="menuitem"><a ng-click="viewTargets()">Manage Targets</a></li>
<li role="menuitem"><a ng-click="viewStaticDnsEntries()">Manage Static DNS Entries</a></li>
</ul>
</div>
</div>
<div class="clearfix"></div>
</div>
<div class="x_content">
<div id="deliveryServiceURLs">
<fieldset ng-if="!settings.isNew && !settings.isRequest">
<legend>Delivery Service URL(s)</legend>
<p ng-repeat="url in deliveryService.exampleURLs"><a href="{{::url}}" rel="noreferrer" target="_blank">{{::url}}</a> </p>
</fieldset>
</div>
<form id="deliveryServiceForm" name="deliveryServiceForm" class="form-horizontal form-label-left">
<fieldset>
<legend ng-class="{'fieldset-error': generalConfig.$invalid}" ng-click="showGeneralConfig = !showGeneralConfig">General Configuration Settings <i class="fa" ng-class="showGeneralConfig ? 'fa-caret-down' : 'fa-caret-up'"></i></legend>
<ng-form name="generalConfig" ng-show="showGeneralConfig">
<div class="form-group" ng-class="{'has-error': hasError(generalConfig.xmlId), 'has-feedback': hasError(generalConfig.xmlId)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="xmlId">XML_ID (Key) *<div class="helptooltip">
<div class="helptext">This id becomes a part of the CDN service domain in the form <samp>http://cdn.service-key.company.com/</samp>. Must be all lowercase, no spaces or special characters. May contain dashes.</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<input id="xmlId" name="xmlId" type="text" class="form-control" placeholder="Unique id used for the delivery service" ng-model="deliveryService.xmlId" required maxlength="48" pattern="[a-z0-9]([a-z0-9\-]*[a-z0-9])?" ng-readonly="(!settings.isRequest && !settings.isNew) || (settings.isRequest && changeType == 'update')">
<small class="input-error" ng-show="hasPropertyError(generalConfig.xmlId, 'required')">Required</small>
<small class="input-error" ng-show="hasPropertyError(generalConfig.xmlId, 'maxlength')">Too Long</small>
<small class="input-error" ng-show="hasPropertyError(generalConfig.xmlId, 'pattern')">Must be a valid DNS label (no special characters, capital letters, periods, underscores, or spaces and cannot begin or end with a hyphen)</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.xmlId != dsCurrent.xmlId">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.xmlId}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(generalConfig.displayName), 'has-feedback': hasError(generalConfig.displayName)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="displayName">Display Name *<div class="helptooltip">
<div class="helptext">Name of the service that appears in the Traffic portal. No character restrictions.</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<input id="displayName" name="displayName" type="text" class="form-control" ng-model="deliveryService.displayName" maxlength="48" required>
<small class="input-error" ng-show="hasPropertyError(generalConfig.displayName, 'required')">Required</small>
<small class="input-error" ng-show="hasPropertyError(generalConfig.displayName, 'maxlength')">Too Long</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.displayName != dsCurrent.displayName">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.displayName}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(generalConfig.active), 'has-feedback': hasError(generalConfig.active)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="active">Active *<div class="helptooltip">
<div class="helptext">Whether or not this Delivery Service is active on the CDN and is capable of traffic.</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<select id="active" name="active" class="form-control" ng-model="deliveryService.active" required>
<option disabled hidden value="">Select...</option>
<option ng-value="true">Active</option>
<option ng-value="false">Not Active</option>
</select>
<small class="input-error" ng-show="hasPropertyError(generalConfig.active, 'required')">Required</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.active != dsCurrent.active">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.active ? 'Active' : 'Not Active'}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(generalConfig.type), 'has-feedback': hasError(generalConfig.type)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="type">Content Routing Type *<div class="helptooltip">
<div class="helptext">
DNS is the standard routing type for most CDN services. HTTP Redirect is a specialty routing service that is primarily used for video and large file downloads where localization and latency are significant concerns. A "Live" routing type should be used for all live services.
<br>
<br>
<a href="https://traffic-control-cdn.readthedocs.io/en/latest/overview/delivery_services.html#ds-types" target="_blank">See Delivery Service Types.</a>
</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<select id="type" name="type" class="form-control" ng-model="deliveryService.typeId" ng-options="type.id as type.name for type in types" required>
<option selected disabled hidden value="">Select...</option>
</select>
<small class="input-error" ng-show="hasPropertyError(generalConfig.type, 'required')">Required</small>
<small ng-show="deliveryService.typeId"><a href="/#!/types/{{deliveryService.typeId}}" target="_blank">View Details&nbsp;&nbsp;<i class="fa fs-xs fa-external-link"></i></a></small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.typeId != dsCurrent.typeId">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.type}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(generalConfig.tenantId), 'has-feedback': hasError(generalConfig.tenantId)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="tenantId">Tenant *<div class="helptooltip">
<div class="helptext">Name of company or division of company who owns account. Allows you to group your services and control access. Tenants are setup as a simple hierarchy where you may create parent / child accounts.</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<tree-select handle="tenantId" on-update="deliveryService.tenantId=value" tree-data="[tenants[0]]" initial-value="deliveryService.tenantId"></tree-select>
<small class="input-error" ng-show="hasPropertyError(generalConfig.tenantId, 'required')">Required</small>
<small ng-show="deliveryService.tenantId"><a href="/#!/tenants/{{deliveryService.tenantId}}" target="_blank">View Details&nbsp;&nbsp;<i class="fa fs-xs fa-external-link"></i></a></small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.tenantId != dsCurrent.tenantId">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.tenant}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(generalConfig.cdn), 'has-feedback': hasError(generalConfig.cdn)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="cdn">CDN *<div class="helptooltip">
<div class="helptext">The CDN to which the Delivery Service belongs.</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<select id="cdn" name="cdn" class="form-control" ng-model="deliveryService.cdnId" ng-options="cdn.id as cdn.name for cdn in cdns" required ng-disabled="(!settings.isNew && deliveryService.sslKeyVersion)">
<option hidden disabled selected value="">Select...</option>
</select>
<small class="input-error" ng-show="hasPropertyError(generalConfig.cdnId, 'required')">Required</small>
<small ng-show="deliveryService.cdnId"><a href="/#!/cdns/{{deliveryService.cdnId}}" target="_blank">View Details&nbsp;&nbsp;<i class="fa fs-xs fa-external-link"></i></a></small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.cdnId != dsCurrent.cdnId">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.cdnName}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(generalConfig.protocol), 'has-feedback': hasError(generalConfig.protocol)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="protocol">Protocol *<div class="helptooltip">
<div class="helptext">
The protocol with which to serve this Delivery Service to the clients:
<br>
<br>
<dl>
<dt>HTTP</dt><dd>Deliver only HTTP traffic</dd>
<dt>HTTPS</dt><dd>Deliver only HTTPS traffic</dd>
<dt>HTTP AND HTTPS</dt><dd>Deliver both types of traffic</dd>
<dt>HTTP TO HTTPS</dt><dd>Redirect HTTP traffic to use HTTPS</dd>
</dl>
</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<select id="protocol" name="protocol" class="form-control" ng-model="deliveryService.protocol" required>
<option hidden disabled value="">Select...</option>
<option ng-value="0">HTTP</option>
<option ng-value="1">HTTPS</option>
<option ng-value="2">HTTP and HTTPS</option>
<option ng-value="3">HTTP to HTTPS</option>
</select>
<small class="input-error" ng-show="hasPropertyError(generalConfig.protocol, 'required')">Required</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.protocol != dsCurrent.protocol">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{magicNumberLabel(protocols, dsCurrent.protocol)}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(generalConfig.serviceCategory), 'has-feedback': hasError(generalConfig.serviceCategory)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="serviceCategory">Service Category<div class="helptooltip">
<div class="helptext">The type of content being delivered. Some examples are linear and vod.</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<select id="serviceCategory" name="serviceCategory" class="form-control" ng-model="deliveryService.serviceCategory" ng-options="serviceCategory.name as serviceCategory.name for serviceCategory in serviceCategories">
<option value="">Select...</option>
</select>
<small ng-show="deliveryService.serviceCategory"><a href="/#!/service-categories/edit?name={{deliveryService.serviceCategory}}" target="_blank">View Details&nbsp;&nbsp;<i class="fa fs-xs fa-external-link"></i></a></small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.serviceCategory != dsCurrent.serviceCategory">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.serviceCategory}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(generalConfig.longDesc), 'has-feedback': hasError(generalConfig.longDesc)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="longDesc">Long Description<div class="helptooltip">
<div class="helptext">Free text field not currently used in configuration.</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<textarea id="longDesc" name="longDesc" class="form-control" ng-model="deliveryService.longDesc" spellcheck="true" rows="3"></textarea>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.longDesc != dsCurrent.longDesc">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.longDesc}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(generalConfig.profile), 'has-feedback': hasError(generalConfig.profile)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="profile">Profile<div class="helptooltip">
<div class="helptext">Only used if a Delivery Service uses configurations that specifically require a profile. Example: Multi-Site Origin configurations would require a Delivery Service Profile to be used.</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<select id="profile" name="profile" class="form-control" ng-model="deliveryService.profileId" ng-options="profile.id as profile.name for profile in profiles">
<option selected value="">None</option>
</select>
<small ng-show="deliveryService.profileId"><a href="/#!/profiles/{{deliveryService.profileId}}" target="_blank">View Details&nbsp;&nbsp;<i class="fa fs-xs fa-external-link"></i></a></small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.profileId != dsCurrent.profileId">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.profileName}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(generalConfig.infoUrl), 'has-feedback': hasError(generalConfig.infoUrl)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="infoUrl">Info URL<div class="helptooltip">
<div class="helptext">Free text field used to enter a URL which provides information about the service.</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<input id="infoUrl" name="infoUrl" type="url" title="Must be a valid URL." class="form-control" ng-model="deliveryService.infoUrl" maxlength="255">
<small class="input-error invalid-URL-error">Invalid URL</small>
<small class="input-error" ng-show="hasPropertyError(generalConfig.infoUrl, 'maxlength')">Too Long</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.infoUrl != dsCurrent.infoUrl">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.infoUrl}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(generalConfig.checkPath), 'has-feedback': hasError(generalConfig.checkPath)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="checkPath">Check Path<div class="helptooltip">
<div class="helptext">A path (e.g. <samp>/crossdomain.xml</samp>) with which to verify the connection to the origin server. This can be used by Check Extension scripts to do periodic health checks against the Delivery Service.</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<input id="checkPath" name="checkPath" type="text" class="form-control" ng-model="deliveryService.checkPath" maxlength="255">
<small class="input-error" ng-show="hasPropertyError(generalConfig.checkPath, 'maxlength')">Too Long</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.checkPath != dsCurrent.checkPath">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.checkPath}}</pre>
</aside>
</div>
</div>
<div class="form-group">
<label class="control-label col-md-2 col-sm-2 col-xs-12" for="lastUpdated">
Last Updated
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<input id="lastUpdated" type="text" class="form-control" ng-model="deliveryService.lastUpdated" readonly />
</div>
</div>
</ng-form>
</fieldset>
<fieldset>
<legend ng-class="{'fieldset-error': routingConfig.$invalid}" ng-click="showRoutingConfig = !showRoutingConfig">Routing Configuration Settings <i class="fa" ng-class="showRoutingConfig ? 'fa-caret-down' : 'fa-caret-up'"></i></legend>
<ng-form name="routingConfig" ng-show="showRoutingConfig">
<div class="form-group" ng-class="{'has-error': hasError(routingConfig.routingName), 'has-feedback': hasError(routingConfig.routingName)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="routingName">Routing Name *<div class="helptooltip">
<div class="helptext">The routing name to use for the delivery <abbr title="Fully Qualified Domain Name">FQDN</abbr>, e.g. <samp>routing-name.deliveryservice.cdn-domain</samp>. It must be a valid hostname without periods.</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<input id="routingName" name="routingName" type="text" class="form-control" placeholder="Routing name used for the delivery service resulting in FQDN = <routing name>.<key>.<CDN domain>" ng-model="deliveryService.routingName" maxlength="48" pattern="[a-z0-9]([a-z\-0-9]*[a-z0-9])?" required ng-disabled="(!settings.isNew && deliveryService.sslKeyVersion)">
<small class="input-error" ng-show="hasPropertyError(routingConfig.routingName, 'required')">Required</small>
<small class="input-error" ng-show="hasPropertyError(routingConfig.routingName, 'maxlength')">Too Long</small>
<small class="input-error" ng-show="hasPropertyError(routingConfig.routingName, 'pattern')">Must be a valid DNS label (no special characters, capital letters, periods, underscores, or spaces and cannot begin or end with a hyphen)</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.routingName != dsCurrent.routingName">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.routingName}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(routingConfig.ipv6RoutingEnabled), 'has-feedback': hasError(routingConfig.ipv6RoutingEnabled)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="ipv6RoutingEnabled">IPv6 Routing Enabled *<div class="helptooltip">
<div class="helptext">Enabeld by default, disabling this allows you to turn off CDN responses to IPv6 requests</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<select id="ipv6RoutingEnabled" name="ipv6RoutingEnabled" class="form-control" ng-model="deliveryService.ipv6RoutingEnabled" required>
<option ng-value="true">Enabled</option>
<option ng-value="false">Disabled</option>
</select>
<small class="input-error" ng-show="hasPropertyError(routingConfig.ipv6RoutingEnabled, 'required')">Required</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.ipv6RoutingEnabled != dsCurrent.ipv6RoutingEnabled">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.ipv6RoutingEnabled ? 'Enabled' : 'Disabled'}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(routingConfig.ecsEnabled), 'has-feedback': hasError(routingConfig.ecsEnabled)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="ecsEnabled">EDNS0 Client Subnet Enabled *<div class="helptooltip">
<div class="helptext">Disabled by default, enabling this enables EDNS0 client subnet on the Delivery Service level.</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<select id="ecsEnabled" name="ecsEnabled" class="form-control" ng-model="deliveryService.ecsEnabled" required>
<option ng-value="true">Enabled</option>
<option ng-value="false">Disabled</option>
</select>
<small class="input-error" ng-show="hasPropertyError(routingConfig.ecsEnabled, 'required')">Required</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.ecsEnabled != dsCurrent.ecsEnabled">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.ecsEnabled ? 'Enabled' : 'Disabled'}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(routingConfig.geoProvider), 'has-feedback': hasError(routingConfig.geoProvider)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="geoProvider">Geolocation Provider *<div class="helptooltip">
<div class="helptext">Choose which Geolocation database provider - company that collects data on the location of IP addresses - to use.</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<select id="geoProvider" name="geoProvider" class="form-control" ng-model="deliveryService.geoProvider" required>
<option ng-value="0" selected>MaxMind</option>
<option ng-value="1">Neustar</option>
</select>
<small class="input-error" ng-show="hasPropertyError(routingConfig.geoProvider, 'required')">Required</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.geoProvider != dsCurrent.geoProvider">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{magicNumberLabel(geoProviders, dsCurrent.geoProvider)}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(routingConfig.geoLimit), 'has-feedback': hasError(routingConfig.geoLimit)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="geoLimit">Geo Limit *<div class="helptooltip">
<div class="helptext">
Some services are intended to be limited by geography. The possible settings are:
<br>
<br>
<dl>
<dt>None</dt><dd>Do not limit by geography.</dd>
<dt>Coverage Zone File only</dt><dd>If the requesting IP is not in the Coverage Zone File, do not serve the request.</dd>
<dt>Coverage Zone File and Country Code(s)</dt><dd>If the requesting IP is not in the Coverage Zone File or not in the United States, do not serve the request.</dd>
</dl>
</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<select id="geoLimit" name="geoLimit" class="form-control" ng-model="deliveryService.geoLimit" required>
<option ng-value="0" selected>None</option>
<option ng-value="1">Coverage Zone File only</option>
<option ng-value="2">Coverage Zone File and Country Code(s)</option>
</select>
<small class="input-error" ng-show="hasPropertyError(routingConfig.geoLimit, 'required')">Required</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.geoLimit != dsCurrent.geoLimit">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{magicNumberLabel(geoLimits, dsCurrent.geoLimit)}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(routingConfig.geoLimitCountries), 'has-feedback': hasError(routingConfig.geoLimitCountries)}" ng-show="deliveryService.geoLimit === 1 || deliveryService.geoLimit === 2">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="geoLimitCountries">Geo Limit Countries<div class="helptooltip">
<div class="helptext">How (if at all) is this service to be limited by geography. Example Country Codes: <abbr title="Canada">CA</abbr>, <abbr title="India">IN</abbr>, <abbr title="Puerto Rico">PR</abbr>.</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<input id="geoLimitCountries" name="geoLimitCountries" type="text" class="form-control" ng-model="deliveryService.geoLimitCountries" maxlength="255" pattern="[A-Z]+(,[A-Z]+)*">
<small class="input-error" ng-show="hasPropertyError(routingConfig.geoLimitCountries, 'maxlength')">Too Long</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.geoLimitCountries != dsCurrent.geoLimitCountries">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.geoLimitCountries}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(routingConfig.geoLimitRedirectURL), 'has-feedback': hasError(routingConfig.geoLimitRedirectURL)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="geoLimitRedirectURL">Geo Limit Redirect URL<div class="helptooltip">
<div class="helptext">
Traffic Router will redirect to this URL when Geo Limit check fails.
<br>
<br>
See <a href="https://traffic-control-cdn.readthedocs.io/en/latest/admin/traffic_router.html#tr-ngb" target="_blank">GeoLimit Failure Redirect</a> feature...
</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<input id="geoLimitRedirectURL" name="geoLimitRedirectURL" title="Must be a valid URL" type="url" class="form-control" ng-model="deliveryService.geoLimitRedirectURL">
<small class="input-error invalid-URL-error">Invalid URL</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.geoLimitRedirectURL != dsCurrent.geoLimitRedirectURL">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.geoLimitRedirectURL}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(routingConfig.maxDnsAnswers), 'has-feedback': hasError(routingConfig.maxDnsAnswers)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="maxDnsAnswers">Max DNS Answers<div class="helptooltip">
<div class="helptext">
See <a href="https://traffic-control-cdn.readthedocs.io/en/latest/overview/delivery_services.html#max-dns-answers"> ATS documentation on Max DNS Answers: HTTP-routed Delivery Service</a>
</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<input id="maxDnsAnswers" name="maxDnsAnswers" type="number" class="form-control" placeholder="Max number of IP addresses in DNS answer (0 means all)" ng-model="deliveryService.maxDnsAnswers" step="1" min="0">
<small class="input-error" ng-show="hasPropertyError(routingConfig.maxDnsAnswers, 'min')">Too Small (must be greater than or equal to 0)</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.maxDnsAnswers != dsCurrent.maxDnsAnswers">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.maxDnsAnswers}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(routingConfig.ccrDnsTtl), 'has-feedback': hasError(routingConfig.ccrDnsTtl)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="ccrDnsTtl">Delivery Service DNS TTL<div class="helptooltip">
<div class="helptext">The <abbr title="Time To Live">TTL</abbr> on the DNS record for the Traffic Router A and AAAA records. Setting too high or too low will result in poor caching performance.</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<input id="ccrDnsTtl" name="ccrDnsTtl" type="number" class="form-control" ng-model="deliveryService.ccrDnsTtl" step="1" min="0">
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.ccrDnsTtl != dsCurrent.ccrDnsTtl">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.ccrDnsTtl}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(routingConfig.consistentHashRegex), 'has-feedback': hasError(routingConfig.consistentHashRegex)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="consistentHashRegex">Consistent Hash Regex<div class="helptooltip">
<div class="helptext">
Regex used to extract parts of the request path using grouping in order to build a consistent request string to be used for cache selection. If this field is set on a steering delivery service, it will override the regex set on the target delivery services.
<br>
<br>
<a href="https://traffic-control-cdn.readthedocs.io/en/latest/admin/traffic_router.html#pattern-based-consistenthash" target="_blank">See Pattern-Based Consistent Hashing</a>
</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<input id="consistentHashRegex" name="consistentHashRegex" type="text" class="form-control" ng-model="deliveryService.consistentHashRegex" maxlength="1024">
<small class="input-error" ng-show="hasPropertyError(routingConfig.consistentHashRegex, 'maxlength')">Too Long</small>
<small><a ng-click="encodeRegex(deliveryService.consistentHashRegex)" href="/#!/delivery-services/{{deliveryService.id}}/consistent-hash?pattern={{encodedRegex}}" target="_blank">Test Regex&nbsp;&nbsp;<i class="fa fs-xs fa-external-link"></i></a></small>
<span ng-show="hasError(routingConfig.consistentHashRegex)" class="form-control-feedback"><i class="fa fa-times"></i></span>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.consistentHashRegex != dsCurrent.consistentHashRegex">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.consistentHashRegex}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(routingConfig.regionalGeoBlocking), 'has-feedback': hasError(routingConfig.regionalGeoBlocking)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="regionalGeoBlocking">Regional Geoblocking *<div class="helptooltip">
<div class="helptext">
Define regional geo-blocking rules for Delivery Services in a JSON format and set this to 'Enabled' to use "Regional Geoblocking". <a href="https://traffic-control-cdn.readthedocs.io/en/latest/admin/quick_howto/regionalgeo.html" target="_blank">See Regional Geo-blocking</a>
</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<select id="regionalGeoBlocking" name="regionalGeoBlocking" class="form-control" ng-model="deliveryService.regionalGeoBlocking" required>
<option ng-value="true">Enabled</option>
<option ng-value="false" selected>Disabled</option>
</select>
<small class="input-error" ng-show="hasPropertyError(routingConfig.regionalGeoBlocking, 'required')">Required</small>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.regionalGeoBlocking != dsCurrent.regionalGeoBlocking">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.regionalGeoBlocking ? 'Enabled' : 'Disabled'}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(routingConfig.trResponseHeaders), 'has-feedback': hasError(routingConfig.trResponseHeaders)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="trResponseHeaders">Traffic Router Additional Response Headers<div class="helptooltip">
<div class="helptext">
List of header name:value pairs. One name:value pair per line. Listed pairs will be included in all Traffic Router HTTP(S) responses.
</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<textarea id="trResponseHeaders" name="trResponseHeaders" class="form-control" ng-model="deliveryService.trResponseHeaders" rows="3"></textarea>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.trResponseHeaders != dsCurrent.trResponseHeaders">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.trResponseHeaders}}</pre>
</aside>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(routingConfig.trRequestHeaders), 'has-feedback': hasError(routingConfig.trRequestHeaders)}">
<label class="has-tooltip control-label col-md-2 col-sm-2 col-xs-12" for="trRequestHeaders">Traffic Router Log Request Headers<div class="helptooltip">
<div class="helptext">
List of header keys. One header key per line. Listed headers will be included in Traffic Router access log entries under the <samp>rh=</samp> token.
</div>
</div>
</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<textarea id="trRequestHeaders" name="trRequestHeaders" class="form-control" ng-model="deliveryService.trRequestHeaders" rows="3"></textarea>
<aside class="current-value" ng-if="settings.isRequest" ng-show="deliveryService.trRequestHeaders != dsCurrent.trRequestHeaders">
<h3 ng-if="open()">Current Value</h3>
<h3 ng-if="!open()">Previous Value</h3>
<pre>{{::dsCurrent.trRequestHeaders}}</pre>
</aside>
</div>
</div>
</ng-form>
</fieldset>
<div class="modal-footer">
<button type="button" class="btn btn-danger" ng-if="!settings.isNew" ng-disabled="!deletable()" ng-click="confirmDelete(deliveryService)">{{settings.deleteLabel}}</button>
<button class="btn btn-success" ng-disabled="deliveryServiceForm.$pristine || deliveryServiceForm.$invalid || !saveable()" ng-click="save(deliveryService)">{{settings.saveLabel}}</button>
<button class="btn btn-primary" ng-if="settings.isRequest && fulfillable()" ng-disabled="deliveryServiceForm.$invalid || deliveryServiceForm.$dirty" ng-click="fulfillRequest(deliveryService)">Fulfill Request</button>
<button class="btn btn-primary" ng-if="settings.isRequest && dsRequest.status == 'pending'" ng-click="editStatus('complete')">Complete Request</button>
</div>
</form>
</div>
</div>