Skip to content
This repository was archived by the owner on Nov 24, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
- SANs information to the SSL key endpoint and Traffic Portal page.
- Added definition for `heartbeat.polling.interval` for CDN Traffic Monitor config in API documentation.
- New `pkg` script options, `-h`, `-s`, `-S`, and `-L`.
- Added `Invalidation Type` (REFRESH or REFETCH) for invalidating content to Traffic Portal.

### Fixed
- [#6197](https://github.com/apache/trafficcontrol/issues/6197) - TO `/deliveryservices/:id/routing` makes requests to all TRs instead of by CDN.
Expand Down
2 changes: 1 addition & 1 deletion cache-config/testing/ort-tests/tcdata/todb.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ func SetupRoles(db *sql.DB) error {

sqlStmt := `
INSERT INTO role (name, description, priv_level) VALUES ('disallowed','Block all access',0) ON CONFLICT DO NOTHING;
INSERT INTO role (name, description, priv_level) VALUES ('read-only user','Block all access', 10) ON CONFLICT DO NOTHING;
INSERT INTO role (name, description, priv_level) VALUES ('read-only','Block all access', 10) ON CONFLICT DO NOTHING;
INSERT INTO role (name, description, priv_level) VALUES ('operations','Block all access', 20) ON CONFLICT DO NOTHING;
INSERT INTO role (name, description, priv_level) VALUES ('admin','super-user', 30) ON CONFLICT DO NOTHING;
INSERT INTO role (name, description, priv_level) VALUES ('portal','Portal User', 2) ON CONFLICT DO NOTHING;
Expand Down
2 changes: 1 addition & 1 deletion traffic_ops/testing/api/v2/todb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ func SetupRoles(db *sql.DB) error {

sqlStmt := `
INSERT INTO role (name, description, priv_level) VALUES ('disallowed','Block all access',0) ON CONFLICT DO NOTHING;
INSERT INTO role (name, description, priv_level) VALUES ('read-only user','Block all access', 10) ON CONFLICT DO NOTHING;
INSERT INTO role (name, description, priv_level) VALUES ('read-only','Block all access', 10) ON CONFLICT DO NOTHING;
INSERT INTO role (name, description, priv_level) VALUES ('operations','Block all access', 20) ON CONFLICT DO NOTHING;
INSERT INTO role (name, description, priv_level) VALUES ('admin','super-user', 30) ON CONFLICT DO NOTHING;
INSERT INTO role (name, description, priv_level) VALUES ('portal','Portal User', 2) ON CONFLICT DO NOTHING;
Expand Down
2 changes: 1 addition & 1 deletion traffic_ops/testing/api/v3/todb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ func SetupRoles(db *sql.DB) error {

sqlStmt := `
INSERT INTO role (name, description, priv_level) VALUES ('disallowed','Block all access',0) ON CONFLICT DO NOTHING;
INSERT INTO role (name, description, priv_level) VALUES ('read-only user','Block all access', 10) ON CONFLICT DO NOTHING;
INSERT INTO role (name, description, priv_level) VALUES ('read-only','Block all access', 10) ON CONFLICT DO NOTHING;
INSERT INTO role (name, description, priv_level) VALUES ('operations','Block all access', 20) ON CONFLICT DO NOTHING;
INSERT INTO role (name, description, priv_level) VALUES ('admin','super-user', 30) ON CONFLICT DO NOTHING;
INSERT INTO role (name, description, priv_level) VALUES ('portal','Portal User', 2) ON CONFLICT DO NOTHING;
Expand Down
2 changes: 1 addition & 1 deletion traffic_ops/testing/api/v4/crconfig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func SnapshotWithReadOnlyUser(t *testing.T) {
RegistrationSent: new(time.Time),
LocalPassword: util.StrPtr("test_pa$$word"),
ConfirmLocalPassword: util.StrPtr("test_pa$$word"),
Role: "read-only user",
Role: "read-only",
}
user.Email = util.StrPtr("email_tm@domain.com")
user.TenantID = resp.Response[0].ID
Expand Down
2 changes: 1 addition & 1 deletion traffic_ops/testing/api/v4/tc-fixtures.json
Original file line number Diff line number Diff line change
Expand Up @@ -5541,7 +5541,7 @@
"phoneNumber": "",
"postalCode": "",
"publicSshKey": "",
"role": "read-only user",
"role": "read-only",
"stateOrProvince": "",
"tenant": "tenant1",
"uid": 0,
Expand Down
2 changes: 1 addition & 1 deletion traffic_ops/testing/api/v4/todb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ func SetupRoles(db *sql.DB) error {

sqlStmt := `
INSERT INTO role (name, description, priv_level) VALUES ('disallowed','Block all access',0) ON CONFLICT DO NOTHING;
INSERT INTO role (name, description, priv_level) VALUES ('read-only user','Block all access', 10) ON CONFLICT DO NOTHING;
INSERT INTO role (name, description, priv_level) VALUES ('read-only','Block all access', 10) ON CONFLICT DO NOTHING;
INSERT INTO role (name, description, priv_level) VALUES ('operations','Block all access', 20) ON CONFLICT DO NOTHING;
INSERT INTO role (name, description, priv_level) VALUES ('admin','super-user', 30) ON CONFLICT DO NOTHING;
INSERT INTO role (name, description, priv_level) VALUES ('portal','Portal User', 2) ON CONFLICT DO NOTHING;
Expand Down
2 changes: 1 addition & 1 deletion traffic_ops/testing/api/v4/topologies_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -996,7 +996,7 @@ func CRUDTopologyReadOnlyUser(t *testing.T) {
RegistrationSent: new(time.Time),
LocalPassword: util.StrPtr("test_pa$$word"),
ConfirmLocalPassword: util.StrPtr("test_pa$$word"),
Role: "read-only user",
Role: "read-only",
}
user.Email = util.StrPtr("email@domain.com")
user.TenantID = resp.Response[0].ID
Expand Down
6 changes: 3 additions & 3 deletions traffic_portal/app/src/common/api/JobService.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
var JobService = function($http, ENV) {

this.getJobs = function(queryParams) {
return $http.get(ENV.api.stable + 'jobs', {params: queryParams}).then(
return $http.get(ENV.api.unstable + 'jobs', {params: queryParams}).then(
function(result) {
return result.data.response;
},
Expand All @@ -31,7 +31,7 @@ var JobService = function($http, ENV) {
};

this.createJob = function(job) {
return $http.post(ENV.api.stable + 'jobs', job).then(
return $http.post(ENV.api.unstable + 'jobs', job).then(
function (result) {
return result;
},
Expand All @@ -42,7 +42,7 @@ var JobService = function($http, ENV) {
};

this.deleteJob = function(id) {
return $http.delete(ENV.api.stable + 'jobs', {params: {id: id}}).then(
return $http.delete(ENV.api.unstable + 'jobs', {params: {id: id}}).then(
function(result) {
return result;
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,20 @@
<span ng-show="hasError(jobForm.regex)" class="form-control-feedback"><i class="fa fa-times"></i></span>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(jobForm.ttl), 'has-feedback': hasError(jobForm.ttl)}">
<div class="form-group" ng-class="{'has-error': hasError(jobForm.ttlhours), 'has-feedback': hasError(jobForm.ttlhours)}">
<label class="control-label col-md-2 col-sm-2 col-xs-12">TTL (hours) *</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<input name="ttl" type="number" class="form-control" placeholder="Number of hours until the invalidation request expires" ng-model="job.ttl" ng-maxlength="3" ng-pattern="/^\d+$/" required autofocus>
<small class="input-error" ng-show="hasPropertyError(jobForm.ttl, 'required')">Required Whole Number</small>
<small class="input-error" ng-show="hasPropertyError(jobForm.ttl, 'maxlength')">Too Long</small>
<small class="input-error" ng-show="hasPropertyError(jobForm.ttl, 'pattern')">Whole Number</small>
<span ng-show="hasError(jobForm.ttl)" class="form-control-feedback"><i class="fa fa-times"></i></span>
<input name="ttlhours" type="number" class="form-control" placeholder="Number of hours until the invalidation request expires" ng-model="job.ttlhours" min="1" max="999" required autofocus>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW, "Number of hours until the invalidation request expires" is not a an appropriate placeholder value for an input[type="number"].

From the MDN section on input labeling:

The placeholder should never be required to understand your forms. It is not a label, and should not be used as a substitute, because it isn't. The placeholder is used to provide a hint as to what an inputted value should look like, not an explanation or prompt.

So it's supposed to be an example input, and this looks more like a label. Traditionally we'd put that in the "helptext" tooltips for the input labels, though for all I care it could just be the entire label text content. The title attribute might also be appropriate, though whether or not any user would encounter that is very implementation-dependent (and since we use form[novalidate]s no non-screen-reading user would ever see them unless they decide to hover it in a Chromium or Gecko engine browser).

<small class="input-error" ng-show="hasPropertyError(jobForm.ttlhours, 'required')">Required Whole Number</small>
<span ng-show="hasError(jobForm.ttlhours)" class="form-control-feedback"><i class="fa fa-times"></i></span>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(jobForm.invalidationtype), 'has-feedback': hasError(jobForm.invalidationtype)}">
<label class="control-label col-md-2 col-sm-2 col-xs-12">Invalidation Type *</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<select name="invalidationtype" class="form-control" ng-model="job.invalidationType" ng-options="invalidationtype as invalidationtype for invalidationtype in invalidationtypes" required>
</select>
<small class="input-error" ng-show="hasPropertyError(jobForm.invalidationtype, 'required')">Required</small>
</div>
</div>
<div class="modal-footer">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ var FormNewDeliveryServiceJobController = function(deliveryService, job, $scope,
// extends the FormDeliveryServiceJobController to inherit common methods
angular.extend(this, $controller('FormDeliveryServiceJobController', { deliveryService: deliveryService, job: job, $scope: $scope }));

// define invalidation types
$scope.invalidationtypes = [
'REFRESH',
'REFETCH'
];
// set default invalidation type
$scope.job.invalidationType = $scope.invalidationtypes[0];

$scope.jobName = 'New';

$scope.settings = {
Expand Down
20 changes: 13 additions & 7 deletions traffic_portal/app/src/common/modules/form/job/form.job.tpl.html
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
<div class="form-group" ng-class="{'has-error': hasError(jobForm.deliveryservice), 'has-feedback': hasError(jobForm.deliveryservice)}">
<label class="control-label col-md-2 col-sm-2 col-xs-12">Delivery Service *</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<select name="deliveryservice" class="form-control" ng-model="job.deliveryService" ng-options="deliveryservice.id as deliveryservice.xmlId for deliveryservice in deliveryservices" required>
<select name="deliveryservice" class="form-control" ng-model="job.deliveryService" ng-options="deliveryservice.xmlId as deliveryservice.xmlId for deliveryservice in deliveryservices" required>
<option value="">Select...</option>
</select>
<small class="input-error" ng-show="hasPropertyError(jobForm.deliveryservice, 'required')">Required</small>
Expand All @@ -47,14 +47,20 @@
<span ng-show="hasError(jobForm.regex)" class="form-control-feedback"><i class="fa fa-times"></i></span>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(jobForm.ttl), 'has-feedback': hasError(jobForm.ttl)}">
<div class="form-group" ng-class="{'has-error': hasError(jobForm.ttlhours), 'has-feedback': hasError(jobForm.ttlhours)}">
<label class="control-label col-md-2 col-sm-2 col-xs-12">TTL (hours) *</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<input name="ttl" type="number" class="form-control" placeholder="Number of hours until the invalidation request expires" ng-model="job.ttl" ng-maxlength="3" ng-pattern="/^\d+$/" required autofocus>
<small class="input-error" ng-show="hasPropertyError(jobForm.ttl, 'required')">Required Whole Number</small>
<small class="input-error" ng-show="hasPropertyError(jobForm.ttl, 'maxlength')">Too Long</small>
<small class="input-error" ng-show="hasPropertyError(jobForm.ttl, 'pattern')">Whole Number</small>
<span ng-show="hasError(jobForm.ttl)" class="form-control-feedback"><i class="fa fa-times"></i></span>
<input name="ttlhours" type="number" class="form-control" placeholder="Number of hours until the invalidation request expires" ng-model="job.ttlhours" min="1" max="999" required autofocus>
<small class="input-error" ng-show="hasPropertyError(jobForm.ttlhours, 'required')">Required Whole Number</small>
<span ng-show="hasError(jobForm.ttlhours)" class="form-control-feedback"><i class="fa fa-times"></i></span>
</div>
</div>
<div class="form-group" ng-class="{'has-error': hasError(jobForm.invalidationtype), 'has-feedback': hasError(jobForm.invalidationtype)}">
<label class="control-label col-md-2 col-sm-2 col-xs-12">Invalidation Type *</label>
<div class="col-md-10 col-sm-10 col-xs-12">
<select name="invalidationtype" class="form-control" ng-model="job.invalidationType" ng-options="invalidationtype as invalidationtype for invalidationtype in invalidationtypes" required>
</select>
<small class="input-error" ng-show="hasPropertyError(jobForm.invalidationtype, 'required')">Required</small>
</div>
</div>
<div class="modal-footer">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ var FormNewJobController = function(job, $scope, $controller, jobService, messag
// extends the FormJobController to inherit common methods
angular.extend(this, $controller('FormJobController', { job: job, $scope: $scope }));

// define invalidation types
$scope.invalidationtypes = [
'REFRESH',
'REFETCH'
];
// set default invalidation type
$scope.job.invalidationType = $scope.invalidationtypes[0];

$scope.jobName = 'New';

$scope.settings = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ var TableJobsController = function(tableName, jobs, $document, $scope, $state, $
hide: false
},
{
headerName: "Parameters",
field: "parameters",
headerName: "TTL (Hours)",
field: "ttlHours",
hide: false
},
{
Expand All @@ -54,6 +54,11 @@ var TableJobsController = function(tableName, jobs, $document, $scope, $state, $
headerName: "Created By",
field: "createdBy",
hide: false
},
{
headerName: "Invalidation Type",
field: "invalidationType",
hide: false
}
];

Expand All @@ -63,9 +68,7 @@ var TableJobsController = function(tableName, jobs, $document, $scope, $state, $
// need to convert this to a date object for ag-grid filter to work properly
x.startTime = new Date(x.startTime.replace("+00", "Z"));

// going to derive the expires date from start + TTL (hours). Format: TTL:24h
let ttl = parseInt(x.parameters.slice('TTL:'.length, x.parameters.length-1), 10);
x.expires = new Date(x.startTime.getTime() + ttl*3600*1000);
x.expires = new Date(x.startTime.getTime() + x.ttlHours*3600*1000);
return x;
});

Expand Down
5 changes: 3 additions & 2 deletions traffic_portal/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions traffic_portal/test/integration/Data/jobs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,9 @@ export const jobs = {
description: "create an invalidation request",
DeliveryService: "dstestjob1",
Regex: "/test",
Ttl: "1",
validationMessage: "Invalidation request created"
TtlHours: "1",
InvalidationType: "REFRESH",
validationMessage: "Invalidation (REFRESH) request created"
}
],
}
Expand Down
9 changes: 6 additions & 3 deletions traffic_portal/test/integration/PageObjects/Jobs.po.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,16 @@ import { SideNavigationPage } from './SideNavigationPage.po';
interface Job {
DeliveryService: string;
Regex: string;
Ttl: string;
TtlHours: string;
InvalidationType: string;
validationMessage: string;
}
export class JobsPage extends BasePage {
private moreBtn = element(by.name('moreBtn'));
private createJobMenuItem = element(by.name('createJobMenuItem'));
private txtRegex = element(by.name('regex'));
private txtTtl = element(by.name('ttl'));
private txtTtl = element(by.name('ttlhours'));
private txtInvalidationType = element(by.name('invalidationtype'));
private txtDeliveryservice = element(by.name('deliveryservice'));
private randomize = randomize;

Expand All @@ -55,7 +57,8 @@ export class JobsPage extends BasePage {
await this.createJobMenuItem.click();
await this.txtDeliveryservice.sendKeys(jobs.DeliveryService + this.randomize)
await this.txtRegex.sendKeys(jobs.Regex);
await this.txtTtl.sendKeys(jobs.Ttl);
await this.txtTtl.sendKeys(jobs.TtlHours);
await this.txtInvalidationType.sendKeys(jobs.InvalidationType);
await basePage.ClickCreate();
result = await basePage.GetOutputMessage().then(value => value.includes(jobs.validationMessage));
return result;
Expand Down