Fix designate-dashboard lint
Previously the lint test was failing to run because there was no configuration file for it. This patch adds the .eslintrc file and fixes the found lint issues. This patch also adds tox environments to run the lint and karma tests. Change-Id: Idcef4c3ce4e9455acceed645c2530355989a7ee2
This commit is contained in:
parent
7ee73c9e1c
commit
64993055e7
41
.eslintrc
Normal file
41
.eslintrc
Normal file
@ -0,0 +1,41 @@
|
||||
# Set up globals
|
||||
globals:
|
||||
angular: false
|
||||
|
||||
extends: openstack
|
||||
|
||||
# Most environment options are not explicitly enabled or disabled, only
|
||||
# included here for completeness' sake. They are commented out, because the
|
||||
# global updates.py script would otherwise override them during a global
|
||||
# requirements synchronization.
|
||||
#
|
||||
# Individual projects should choose which platforms they deploy to.
|
||||
|
||||
env:
|
||||
# browser global variables.
|
||||
browser: true
|
||||
|
||||
# Adds all of the Jasmine testing global variables for version 1.3 and 2.0.
|
||||
jasmine: true
|
||||
|
||||
# Enable eslint-plugin-angular
|
||||
plugins:
|
||||
- angular
|
||||
|
||||
# Below we adjust rules specific to horizon's usage of openstack's linting
|
||||
# rules, and its own plugin inclusions.
|
||||
rules:
|
||||
#############################################################################
|
||||
# Disabled Rules from eslint-config-openstack
|
||||
#############################################################################
|
||||
valid-jsdoc: 1
|
||||
brace-style: 1
|
||||
no-extra-parens: 1
|
||||
consistent-return: 1
|
||||
callback-return: 1
|
||||
guard-for-in: 1
|
||||
block-scoped-var: 1
|
||||
semi-spacing: 1
|
||||
no-redeclare: 1
|
||||
no-new: 1
|
||||
no-warning-comments: 0
|
@ -71,7 +71,8 @@
|
||||
'designatedashboard.basePath'
|
||||
];
|
||||
|
||||
function run(registry, basePath) {
|
||||
function run() {
|
||||
// function run(registry, basePath) {
|
||||
//registry.setDefaultSummaryTemplateUrl(basePath + 'table/default-drawer.html');
|
||||
}
|
||||
|
||||
|
@ -37,12 +37,7 @@
|
||||
'designatedashboard.resources.os-designate-floatingip.actions.unset'
|
||||
];
|
||||
|
||||
function run(
|
||||
registry,
|
||||
resourceTypeString,
|
||||
setAction,
|
||||
unsetAction)
|
||||
{
|
||||
function run(registry, resourceTypeString, setAction, unsetAction) {
|
||||
var resourceType = registry.getResourceType(resourceTypeString);
|
||||
|
||||
resourceType
|
||||
|
@ -33,7 +33,7 @@
|
||||
'horizon.framework.widgets.modal-wait-spinner.service'
|
||||
];
|
||||
|
||||
/**
|
||||
/*
|
||||
* @ngDoc factory
|
||||
* @name designatedashboard.resources.os-designate-floatingip.actions.set
|
||||
*
|
||||
@ -51,44 +51,44 @@
|
||||
var dnsServiceEnabled;
|
||||
var title = null; // Set once perform is called
|
||||
var formConfig = {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"ptrdname": {
|
||||
"type": "string",
|
||||
"pattern": /^.+\.$/
|
||||
schema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
ptrdname: {
|
||||
type: "string",
|
||||
pattern: /^.+\.$/
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"ttl": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"maximum": 2147483647
|
||||
description: {
|
||||
type: "string"
|
||||
},
|
||||
ttl: {
|
||||
type: "integer",
|
||||
minimum: 0,
|
||||
maximum: 2147483647
|
||||
}
|
||||
}
|
||||
},
|
||||
"form": [
|
||||
form: [
|
||||
{
|
||||
"key": "ptrdname",
|
||||
"title": gettext("Domain Name"),
|
||||
"description": gettext("Domain name ending in '.'"),
|
||||
"validationMessage": gettext("Domain must end with '.'"),
|
||||
"placeholder": "smtp.example.com.",
|
||||
"type": "text",
|
||||
"required": true
|
||||
key: "ptrdname",
|
||||
title: gettext("Domain Name"),
|
||||
description: gettext("Domain name ending in '.'"),
|
||||
validationMessage: gettext("Domain must end with '.'"),
|
||||
placeholder: "smtp.example.com.",
|
||||
type: "text",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
"key": "description",
|
||||
"type": "textarea",
|
||||
"title": gettext("Description"),
|
||||
"description": gettext("Details about the PTR record.")
|
||||
key: "description",
|
||||
type: "textarea",
|
||||
title: gettext("Description"),
|
||||
description: gettext("Details about the PTR record.")
|
||||
},
|
||||
{
|
||||
"key": "ttl",
|
||||
"title": gettext("TTL"),
|
||||
"description": gettext("Time To Live in seconds."),
|
||||
"type": "number"
|
||||
key: "ttl",
|
||||
title: gettext("TTL"),
|
||||
description: gettext("Time To Live in seconds."),
|
||||
type: "number"
|
||||
}
|
||||
]
|
||||
};
|
||||
|
@ -34,7 +34,7 @@
|
||||
'horizon.framework.widgets.modal-wait-spinner.service'
|
||||
];
|
||||
|
||||
/**
|
||||
/*
|
||||
* @ngDoc factory
|
||||
* @name designatedashboard.resources.os-designate-floatingip.actions.unset
|
||||
*
|
||||
@ -50,20 +50,21 @@
|
||||
schemaFormModalService,
|
||||
toast,
|
||||
waitSpinner) {
|
||||
var dnsServiceEnabled;
|
||||
var title = null; // Set on perform
|
||||
var currentFloatingIpId; // Used to remember the ID we are modifying since it isn't returned by the unset API call
|
||||
// currentFloatingIpId is used to remember the ID we are modifying since
|
||||
// it isn't returned by the unset API call
|
||||
var dnsServiceEnabled, currentFloatingIpId;
|
||||
|
||||
// Unset it just a simple case of "set", but with ptrdname of 'null'
|
||||
var formConfig = {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
schema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
}
|
||||
},
|
||||
"form": [
|
||||
form: [
|
||||
],
|
||||
"model": {
|
||||
model: {
|
||||
}
|
||||
};
|
||||
|
||||
@ -118,7 +119,7 @@
|
||||
waitSpinner.hideModalSpinner();
|
||||
}
|
||||
|
||||
function onSuccess(response) {
|
||||
function onSuccess() {
|
||||
waitSpinner.hideModalSpinner();
|
||||
toast.add('success', message.success);
|
||||
|
||||
|
@ -26,7 +26,7 @@
|
||||
'horizon.framework.widgets.toast.service'
|
||||
];
|
||||
|
||||
/**
|
||||
/*
|
||||
* @ngdoc service
|
||||
* @param {Object} httpService
|
||||
* @param {Object} toastService
|
||||
@ -60,7 +60,7 @@
|
||||
* @returns {Object} The result of the API call
|
||||
*/
|
||||
function list(params) {
|
||||
var config = params ? {'params': params} : {};
|
||||
var config = params ? {params: params} : {};
|
||||
return httpService.get(apiPassthroughUrl + 'v2/reverse/floatingips', config)
|
||||
.catch(function () {
|
||||
toastService.add('error', gettext('Unable to retrieve the floating ip PTRs.'));
|
||||
@ -68,7 +68,7 @@
|
||||
}
|
||||
|
||||
function get(id, params) {
|
||||
var config = params ? {'params': params} : {};
|
||||
var config = params ? {params: params} : {};
|
||||
return httpService.get(apiPassthroughUrl + 'v2/reverse/floatingips/' + id, config)
|
||||
.catch(function () {
|
||||
toastService.add('error', gettext('Unable to get the floating ip PTR ' + id));
|
||||
@ -94,10 +94,11 @@
|
||||
description: data.description,
|
||||
ttl: data.ttl
|
||||
};
|
||||
return httpService.patch(apiPassthroughUrl + 'v2/reverse/floatingips/' + floatingIpID, apiData)
|
||||
return httpService.patch(
|
||||
apiPassthroughUrl + 'v2/reverse/floatingips/' + floatingIpID, apiData)
|
||||
.catch(function () {
|
||||
toastService.add('error', gettext('Unable to set the floating IP PTR record.'));
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -115,7 +116,7 @@
|
||||
ptrdname: null,
|
||||
description: null,
|
||||
ttl: null
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
}());
|
||||
|
@ -18,7 +18,9 @@
|
||||
|
||||
angular
|
||||
.module('designatedashboard.resources.os-designate-floatingip.details')
|
||||
.controller('designatedashboard.resources.os-designate-floatingip.details.overviewController', controller);
|
||||
.controller(
|
||||
'designatedashboard.resources.os-designate-floatingip.details.overviewController',
|
||||
controller);
|
||||
|
||||
controller.$inject = [
|
||||
'designatedashboard.resources.os-designate-floatingip.resourceType',
|
||||
@ -33,7 +35,7 @@
|
||||
) {
|
||||
var ctrl = this;
|
||||
|
||||
ctrl.item;
|
||||
ctrl.item = {};
|
||||
ctrl.resourceType = registry.getResourceType(resourceTypeCode);
|
||||
|
||||
$scope.context.loadPromise.then(onGetResponse);
|
||||
|
@ -40,7 +40,8 @@
|
||||
config.$inject = [ '$provide', '$windowProvider' ];
|
||||
|
||||
function config($provide, $windowProvider) {
|
||||
var path = $windowProvider.$get().STATIC_URL + 'designatedashboard/resources/os-designate-floatingip/';
|
||||
var path = $windowProvider.$get().STATIC_URL +
|
||||
'designatedashboard/resources/os-designate-floatingip/';
|
||||
$provide.constant('designatedashboard.resources.os-designate-floatingip.basePath', path);
|
||||
}
|
||||
|
||||
@ -52,13 +53,7 @@
|
||||
'designatedashboard.resources.util'
|
||||
];
|
||||
|
||||
function run(
|
||||
detailRoute,
|
||||
registry,
|
||||
api,
|
||||
resourceTypeString,
|
||||
util)
|
||||
{
|
||||
function run(detailRoute, registry, api, resourceTypeString, util) {
|
||||
var resourceType = registry.getResourceType(resourceTypeString);
|
||||
resourceType
|
||||
.setNames(gettext('Floating IP'), gettext('Floating IPs'))
|
||||
@ -100,12 +95,13 @@
|
||||
id: 'address',
|
||||
priority: 1,
|
||||
sortDefault: true,
|
||||
template: '<a ng-href="{$ \'' + detailRoute + 'OS::Designate::FloatingIp/\' + item.id $}">{$ item.address $}</a>'
|
||||
template: '<a ng-href="{$ \'' + detailRoute +
|
||||
'OS::Designate::FloatingIp/\' + item.id $}">{$ item.address $}</a>'
|
||||
})
|
||||
.append({
|
||||
id: 'ptrdname',
|
||||
filters: ['noValue'],
|
||||
priority: 1,
|
||||
priority: 1
|
||||
})
|
||||
.append({
|
||||
id: 'status',
|
||||
|
@ -27,7 +27,7 @@
|
||||
'designatedashboard.resources.os-designate-recordset.typeMap'
|
||||
];
|
||||
|
||||
/**
|
||||
/*
|
||||
* Service to return a schema form config for action forms. Especially useful for forms
|
||||
* like create and update that differ only in the readonly state of certain form fields.
|
||||
*
|
||||
@ -43,7 +43,7 @@
|
||||
|
||||
/////////////////
|
||||
|
||||
/**
|
||||
/*
|
||||
* Returns the create form config
|
||||
* @returns {{schema, form, model}|*}
|
||||
*/
|
||||
@ -51,7 +51,7 @@
|
||||
return getCreateUpdateFormConfig(false);
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* Return the update form config
|
||||
* @returns {{schema, form, model}|*}
|
||||
*/
|
||||
@ -59,7 +59,7 @@
|
||||
return getCreateUpdateFormConfig(true);
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* Return the create/update form. The two forms are identical except for
|
||||
* during update, some fields are read-only.
|
||||
*
|
||||
@ -68,96 +68,96 @@
|
||||
*/
|
||||
function getCreateUpdateFormConfig(readonly) {
|
||||
return {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"pattern": /^.+\.$/
|
||||
schema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
name: {
|
||||
type: "string",
|
||||
pattern: /^.+\.$/
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
description: {
|
||||
type: "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": editableTypes
|
||||
type: {
|
||||
type: "string",
|
||||
enum: editableTypes
|
||||
},
|
||||
"ttl": {
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"maximum": 2147483647
|
||||
ttl: {
|
||||
type: "integer",
|
||||
minimum: 1,
|
||||
maximum: 2147483647
|
||||
},
|
||||
"records": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"record": {
|
||||
"type": "string"
|
||||
records: {
|
||||
type: "array",
|
||||
items: {
|
||||
type: "object",
|
||||
properties: {
|
||||
record: {
|
||||
type: "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"minItems": 1,
|
||||
"uniqueItems": true
|
||||
minItems: 1,
|
||||
uniqueItems: true
|
||||
}
|
||||
}
|
||||
},
|
||||
"form": [
|
||||
form: [
|
||||
{
|
||||
"key": "type",
|
||||
"readonly": readonly,
|
||||
"title": gettext("Type"),
|
||||
"description": gettext("Select the type of record set"),
|
||||
"type": "select",
|
||||
"titleMap": editableTypes.map(function toTitleMap(type) {
|
||||
key: "type",
|
||||
readonly: readonly,
|
||||
title: gettext("Type"),
|
||||
description: gettext("Select the type of record set"),
|
||||
type: "select",
|
||||
titleMap: editableTypes.map(function toTitleMap(type) {
|
||||
return {
|
||||
"value": type,
|
||||
"name": typeMap[type]
|
||||
}
|
||||
value: type,
|
||||
name: typeMap[type]
|
||||
};
|
||||
}),
|
||||
"required": true
|
||||
required: true
|
||||
},
|
||||
{
|
||||
"key": "name",
|
||||
"readonly": readonly,
|
||||
"type": "text",
|
||||
"title": gettext("Name"),
|
||||
"description": gettext("DNS name for the record set, ending in '.'"),
|
||||
"validationMessage": gettext("DNS name must end with '.'"),
|
||||
"placeholder": "www.example.com.",
|
||||
"required": true
|
||||
key: "name",
|
||||
readonly: readonly,
|
||||
type: "text",
|
||||
title: gettext("Name"),
|
||||
description: gettext("DNS name for the record set, ending in '.'"),
|
||||
validationMessage: gettext("DNS name must end with '.'"),
|
||||
placeholder: "www.example.com.",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
"key": "description",
|
||||
"type": "textarea",
|
||||
"title": gettext("Description"),
|
||||
"description": gettext("Details about the zone.")
|
||||
key: "description",
|
||||
type: "textarea",
|
||||
title: gettext("Description"),
|
||||
description: gettext("Details about the zone.")
|
||||
},
|
||||
{
|
||||
"key": "ttl",
|
||||
"title": gettext("TTL"),
|
||||
"description": gettext("Time To Live in seconds."),
|
||||
"type": "number",
|
||||
"required": true
|
||||
key: "ttl",
|
||||
title: gettext("TTL"),
|
||||
description: gettext("Time To Live in seconds."),
|
||||
type: "number",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
"key": "records",
|
||||
"title": gettext("Records"),
|
||||
"type": "array",
|
||||
"description": gettext("Records for the record set."),
|
||||
"add": gettext("Add Record"),
|
||||
"items": [
|
||||
key: "records",
|
||||
title: gettext("Records"),
|
||||
type: "array",
|
||||
description: gettext("Records for the record set."),
|
||||
add: gettext("Add Record"),
|
||||
items: [
|
||||
{
|
||||
"key": "records[].record",
|
||||
"title": gettext("Record")
|
||||
key: "records[].record",
|
||||
title: gettext("Record")
|
||||
}
|
||||
],
|
||||
"required": true
|
||||
required: true
|
||||
}
|
||||
],
|
||||
"model": {
|
||||
"type": "A",
|
||||
"ttl": 3600
|
||||
model: {
|
||||
type: "A",
|
||||
ttl: 3600
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -35,7 +35,7 @@
|
||||
'horizon.framework.widgets.modal-wait-spinner.service'
|
||||
];
|
||||
|
||||
/**
|
||||
/*
|
||||
* @ngDoc factory
|
||||
* @name designatedashboard.resources.os-designate-recordset.actions.create
|
||||
*
|
||||
@ -73,7 +73,7 @@
|
||||
dnsServiceEnabled = serviceCatalog.ifTypeEnabled('dns');
|
||||
}
|
||||
|
||||
function allowed(item) {
|
||||
function allowed() {
|
||||
return $q.all([
|
||||
createRecordSetPolicy,
|
||||
dnsServiceEnabled
|
||||
|
@ -111,7 +111,7 @@
|
||||
// Remember the record sets we are allowed to delete so that on delete modal submit
|
||||
// we can map the recordset ID back to the full recordset. Then we can fetch the
|
||||
// corresponding zone ID
|
||||
allowedRecordsets = result.pass.map(getEntity)
|
||||
allowedRecordsets = result.pass.map(getEntity);
|
||||
outcome = deleteModal.open(scope, allowedRecordsets, context).then(createResult);
|
||||
}
|
||||
return outcome;
|
||||
@ -157,7 +157,7 @@
|
||||
|
||||
function editableRecordType(recordset) {
|
||||
return $qExtensions.booleanAsPromise(
|
||||
!(recordset.type == 'NS' && recordset.name == recordset.zone_name) && // not apex NS
|
||||
!(recordset.type === 'NS' && recordset.name === recordset.zone_name) && // not apex NS
|
||||
editableTypes.indexOf(recordset.type) > -1
|
||||
);
|
||||
}
|
||||
@ -165,7 +165,7 @@
|
||||
function deleteRecordSet(recordSetId) {
|
||||
var recordSet = allowedRecordsets.find(function(element) {
|
||||
return element.id === recordSetId;
|
||||
})
|
||||
});
|
||||
return recordsetApi.deleteRecordSet(recordSet.zone_id, recordSet.id);
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@
|
||||
'horizon.framework.widgets.modal-wait-spinner.service'
|
||||
];
|
||||
|
||||
/**
|
||||
/*
|
||||
* @ngDoc factory
|
||||
* @name designatedashboard.resources.os-designate-recordset.actions.update
|
||||
*
|
||||
@ -56,7 +56,7 @@
|
||||
schemaFormModalService,
|
||||
toast,
|
||||
waitSpinner) {
|
||||
var updateRecordSetPolicy, dnsServiceEnabled;
|
||||
var updateRecordSetPolicy;
|
||||
var title = gettext("Update Record Set");
|
||||
var message = {
|
||||
success: gettext('Record Set %s was successfully updated.')
|
||||
@ -93,7 +93,7 @@
|
||||
|
||||
function editableRecordType(recordset) {
|
||||
return $qExtensions.booleanAsPromise(
|
||||
!(recordset.type == 'NS' && recordset.name == recordset.zone_name) && // not apex NS
|
||||
!(recordset.type === 'NS' && recordset.name === recordset.zone_name) && // not apex NS
|
||||
editableTypes.indexOf(recordset.type) > -1
|
||||
);
|
||||
}
|
||||
@ -111,7 +111,7 @@
|
||||
// Map the records objects to record objects
|
||||
if (item.hasOwnProperty("records")) {
|
||||
var records = item.records.map(function (item) {
|
||||
return {"record": item}
|
||||
return {record: item};
|
||||
});
|
||||
formConfig.model.records = records;
|
||||
}
|
||||
|
@ -27,7 +27,7 @@
|
||||
'horizon.framework.widgets.toast.service'
|
||||
];
|
||||
|
||||
/**
|
||||
/*
|
||||
* @ngdoc service
|
||||
* @param {Object} httpService
|
||||
* @param {Object} toastService
|
||||
@ -48,7 +48,7 @@
|
||||
|
||||
///////////////
|
||||
|
||||
/**
|
||||
/*
|
||||
* @name list
|
||||
* @description
|
||||
* Get a list of record sets.
|
||||
@ -68,7 +68,7 @@
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* @name get
|
||||
* @description
|
||||
* Get a single record set by ID.
|
||||
@ -86,14 +86,15 @@
|
||||
// common when then delete action removes a record set. Mask this failure by
|
||||
// always returning a successful promise instead of terminating the $http promise
|
||||
// in the .error handler.
|
||||
return httpService.get(apiPassthroughUrl + 'v2/zones/' + zoneId + '/recordsets/' + recordSetId + '/')
|
||||
return httpService.get(
|
||||
apiPassthroughUrl + 'v2/zones/' + zoneId + '/recordsets/' + recordSetId + '/')
|
||||
.then(undefined, function onError() {
|
||||
toastService.add('error', gettext('Unable to retrieve the record set.'));
|
||||
return $q.when({});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* @name delete
|
||||
* @description
|
||||
* Delete a single record set by ID
|
||||
@ -106,7 +107,8 @@
|
||||
* @returns {*}
|
||||
*/
|
||||
function deleteRecordSet(zoneId, recordSetId) {
|
||||
return httpService.delete(apiPassthroughUrl + 'v2/zones/' + zoneId + '/recordsets/' + recordSetId + '/')
|
||||
return httpService.delete(
|
||||
apiPassthroughUrl + 'v2/zones/' + zoneId + '/recordsets/' + recordSetId + '/')
|
||||
.catch(function () {
|
||||
toastService.add('error', gettext('Unable to delete the record set.'));
|
||||
});
|
||||
@ -127,7 +129,8 @@
|
||||
description: data.description,
|
||||
records: data.records
|
||||
};
|
||||
return httpService.put(apiPassthroughUrl + 'v2/zones/' + zoneId + '/recordsets/' + recordSetId, apiData)
|
||||
return httpService.put(
|
||||
apiPassthroughUrl + 'v2/zones/' + zoneId + '/recordsets/' + recordSetId, apiData)
|
||||
.catch(function () {
|
||||
toastService.add('error', gettext('Unable to update the record set.'));
|
||||
});
|
||||
|
@ -32,7 +32,7 @@
|
||||
'designatedashboard.resources.os-designate-recordset.resourceType',
|
||||
'designatedashboard.resources.os-designate-recordset.api',
|
||||
'designatedashboard.resources.os-designate-recordset.basePath',
|
||||
'horizon.framework.conf.resource-type-registry.service',
|
||||
'horizon.framework.conf.resource-type-registry.service'
|
||||
];
|
||||
|
||||
function run(
|
||||
@ -48,7 +48,7 @@
|
||||
.setPathParser(pathParser)
|
||||
.setSummaryTemplateUrl(basePath + 'details/drawer.html');
|
||||
|
||||
/**
|
||||
/*
|
||||
*
|
||||
* @param identifier
|
||||
* The object returned by the pathParser containing the zone ID and record set ID to load
|
||||
@ -57,7 +57,7 @@
|
||||
return recordSetApi.get(identifier.zoneId, identifier.recordSetId);
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* Because a record set is contained by a zone, we implement a custom
|
||||
* pathGenerator to encode the zone ID and record set ID for the generic
|
||||
* details panel.
|
||||
@ -71,7 +71,7 @@
|
||||
return item.zone_id + '/' + item.id;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* Given a path, extract the zone and record set ids
|
||||
*
|
||||
* @param path
|
||||
@ -86,14 +86,14 @@
|
||||
return {
|
||||
zoneId: split[0],
|
||||
recordSetId: split[1]
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
resourceType.detailsViews
|
||||
.prepend({
|
||||
id: 'recordsetDetailsOverview',
|
||||
name: gettext('Overview'),
|
||||
template: basePath + 'details/overview.html',
|
||||
template: basePath + 'details/overview.html'
|
||||
}, 0);
|
||||
|
||||
// Append a record set view to the zones resource view
|
||||
@ -102,7 +102,7 @@
|
||||
.append({
|
||||
id: 'zoneRecordSets',
|
||||
name: gettext('Record Sets'),
|
||||
template: basePath + 'details/zone-recordsets.html',
|
||||
template: basePath + 'details/zone-recordsets.html'
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,9 @@
|
||||
|
||||
angular
|
||||
.module('designatedashboard.resources.os-designate-recordset')
|
||||
.controller('designatedashboard.resources.os-designate-recordset.zoneRecordSetsController', controller);
|
||||
.controller(
|
||||
'designatedashboard.resources.os-designate-recordset.zoneRecordSetsController',
|
||||
controller);
|
||||
|
||||
controller.$inject = [
|
||||
'$scope',
|
||||
|
@ -36,42 +36,43 @@
|
||||
'OS::Designate::RecordSet')
|
||||
.constant(
|
||||
'designatedashboard.resources.os-designate-recordset.typeMap',
|
||||
{
|
||||
'A': gettext('A - Address record'),
|
||||
'AAAA': gettext('AAAA - IPv6 address record'),
|
||||
'CNAME': gettext('CNAME - Canonical name record'),
|
||||
'MX': gettext('MX - Mail exchange record'),
|
||||
'PTR': gettext('PTR - Pointer record'),
|
||||
'SPF': gettext('SPF - Sender Policy Framework'),
|
||||
'SRV': gettext('SRV - Service locator'),
|
||||
'SSHFP': gettext('SSHFP - SSH Public Key Fingerprint'),
|
||||
'TXT': gettext('TXT - Text record'),
|
||||
'SOA': gettext('SOA - Start of authority record'),
|
||||
'NS': gettext('NS - Name server'),
|
||||
'CAA': gettext('CAA - Certificate Authority Authorization record'),
|
||||
})
|
||||
{
|
||||
A: gettext('A - Address record'),
|
||||
AAAA: gettext('AAAA - IPv6 address record'),
|
||||
CNAME: gettext('CNAME - Canonical name record'),
|
||||
MX: gettext('MX - Mail exchange record'),
|
||||
PTR: gettext('PTR - Pointer record'),
|
||||
SPF: gettext('SPF - Sender Policy Framework'),
|
||||
SRV: gettext('SRV - Service locator'),
|
||||
SSHFP: gettext('SSHFP - SSH Public Key Fingerprint'),
|
||||
TXT: gettext('TXT - Text record'),
|
||||
SOA: gettext('SOA - Start of authority record'),
|
||||
NS: gettext('NS - Name server'),
|
||||
CAA: gettext('CAA - Certificate Authority Authorization record')
|
||||
})
|
||||
.constant(
|
||||
'designatedashboard.resources.os-designate-recordset.editableTypes',
|
||||
[
|
||||
"A",
|
||||
"AAAA",
|
||||
"CNAME",
|
||||
"MX",
|
||||
"NS",
|
||||
"PTR",
|
||||
"SPF",
|
||||
"SRV",
|
||||
"SSHFP",
|
||||
"TXT",
|
||||
"CAA",
|
||||
])
|
||||
[
|
||||
"A",
|
||||
"AAAA",
|
||||
"CNAME",
|
||||
"MX",
|
||||
"NS",
|
||||
"PTR",
|
||||
"SPF",
|
||||
"SRV",
|
||||
"SSHFP",
|
||||
"TXT",
|
||||
"CAA"
|
||||
])
|
||||
.config(config)
|
||||
.run(run);
|
||||
|
||||
config.$inject = ['$provide', '$windowProvider'];
|
||||
|
||||
function config($provide, $windowProvider) {
|
||||
var path = $windowProvider.$get().STATIC_URL + 'designatedashboard/resources/os-designate-recordset/';
|
||||
var path = $windowProvider.$get().STATIC_URL +
|
||||
'designatedashboard/resources/os-designate-recordset/';
|
||||
$provide.constant('designatedashboard.resources.os-designate-recordset.basePath', path);
|
||||
}
|
||||
|
||||
@ -166,7 +167,9 @@
|
||||
sortDefault: true,
|
||||
filters: ['noName'],
|
||||
// For link format, see pathGenerator in details.module.js
|
||||
template: '<a ng-href="{$ \'' + detailRoute + 'OS::Designate::RecordSet/\' + item.zone_id + \'/\' + item.id $}">{$ item.name $}</a>'
|
||||
template: '<a ng-href="{$ \'' + detailRoute +
|
||||
'OS::Designate::RecordSet/\' + item.zone_id + \'/\' +' +
|
||||
'item.id $}">{$ item.name $}</a>'
|
||||
})
|
||||
.append({
|
||||
id: 'type',
|
||||
@ -198,7 +201,7 @@
|
||||
return {
|
||||
label: typeMap[key],
|
||||
key: key
|
||||
}
|
||||
};
|
||||
})
|
||||
})
|
||||
.append({
|
||||
@ -220,7 +223,7 @@
|
||||
]
|
||||
});
|
||||
|
||||
/**
|
||||
/*
|
||||
* list all recordsets within a zone. Requires "zoneId" in the params. All other
|
||||
* params will be passed unmodified as URL params to the API.
|
||||
*
|
||||
|
@ -41,7 +41,7 @@
|
||||
|
||||
/////////////////
|
||||
|
||||
/**
|
||||
/*
|
||||
* Returns the create zone form config
|
||||
* @returns {{schema, form, model}|*}
|
||||
*/
|
||||
@ -49,7 +49,7 @@
|
||||
return getCreateUpdateFormConfig(false);
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* Return the update zone form config
|
||||
* @returns {{schema, form, model}|*}
|
||||
*/
|
||||
@ -57,7 +57,7 @@
|
||||
return getCreateUpdateFormConfig(true);
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* Return the create/update zone form. The two forms are identical except for
|
||||
* during update, some fields are read-only.
|
||||
*
|
||||
@ -66,118 +66,118 @@
|
||||
*/
|
||||
function getCreateUpdateFormConfig(readonly) {
|
||||
return {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"pattern": /^.+\.$/
|
||||
schema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
name: {
|
||||
type: "string",
|
||||
pattern: /^.+\.$/
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
description: {
|
||||
type: "string"
|
||||
},
|
||||
"email": {
|
||||
"type": "string",
|
||||
"format": "email",
|
||||
"pattern": /^[^@]+@[^@]+$/
|
||||
email: {
|
||||
type: "string",
|
||||
format: "email",
|
||||
pattern: /^[^@]+@[^@]+$/
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
type: {
|
||||
type: "string",
|
||||
enum: [
|
||||
"PRIMARY",
|
||||
"SECONDARY"
|
||||
]
|
||||
},
|
||||
"ttl": {
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"maximum": 2147483647
|
||||
ttl: {
|
||||
type: "integer",
|
||||
minimum: 1,
|
||||
maximum: 2147483647
|
||||
},
|
||||
"masters": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"address": {
|
||||
"type": "string"
|
||||
masters: {
|
||||
type: "array",
|
||||
items: {
|
||||
type: "object",
|
||||
properties: {
|
||||
address: {
|
||||
type: "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"minItems": 1,
|
||||
"uniqueItems": true
|
||||
minItems: 1,
|
||||
uniqueItems: true
|
||||
}
|
||||
}
|
||||
},
|
||||
"form": [
|
||||
form: [
|
||||
{
|
||||
"key": "name",
|
||||
"readonly": readonly,
|
||||
"title": gettext("Name"),
|
||||
"description": gettext("Zone name ending in '.'"),
|
||||
"validationMessage": gettext("Zone must end with '.'"),
|
||||
"placeholder": "example.com.",
|
||||
"type": "text",
|
||||
"required": true
|
||||
key: "name",
|
||||
readonly: readonly,
|
||||
title: gettext("Name"),
|
||||
description: gettext("Zone name ending in '.'"),
|
||||
validationMessage: gettext("Zone must end with '.'"),
|
||||
placeholder: "example.com.",
|
||||
type: "text",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
"key": "description",
|
||||
"type": "textarea",
|
||||
"title": gettext("Description"),
|
||||
"description": gettext("Details about the zone.")
|
||||
key: "description",
|
||||
type: "textarea",
|
||||
title: gettext("Description"),
|
||||
description: gettext("Details about the zone.")
|
||||
},
|
||||
{
|
||||
"key": "email",
|
||||
"title": gettext("Email Address"),
|
||||
"description": gettext("Email address to contact the zone owner."),
|
||||
"validationMessage": gettext("Email address must contain a single '@' character"),
|
||||
"type": "text",
|
||||
"condition": "model.type == 'PRIMARY'",
|
||||
"required": true
|
||||
key: "email",
|
||||
title: gettext("Email Address"),
|
||||
description: gettext("Email address to contact the zone owner."),
|
||||
validationMessage: gettext("Email address must contain a single '@' character"),
|
||||
type: "text",
|
||||
condition: "model.type == 'PRIMARY'",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
"key": "ttl",
|
||||
"title": gettext("TTL"),
|
||||
"description": gettext("Time To Live in seconds."),
|
||||
"type": "number",
|
||||
"condition": "model.type == 'PRIMARY'",
|
||||
"required": true
|
||||
key: "ttl",
|
||||
title: gettext("TTL"),
|
||||
description: gettext("Time To Live in seconds."),
|
||||
type: "number",
|
||||
condition: "model.type == 'PRIMARY'",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
"key": "type",
|
||||
"readonly": readonly,
|
||||
"title": gettext("Type"),
|
||||
"description": gettext("Select the type of zone"),
|
||||
"type": "select",
|
||||
"titleMap": [
|
||||
key: "type",
|
||||
readonly: readonly,
|
||||
title: gettext("Type"),
|
||||
description: gettext("Select the type of zone"),
|
||||
type: "select",
|
||||
titleMap: [
|
||||
{
|
||||
"value": "PRIMARY",
|
||||
"name": gettext("Primary")
|
||||
value: "PRIMARY",
|
||||
name: gettext("Primary")
|
||||
},
|
||||
{
|
||||
"value": "SECONDARY",
|
||||
"name": gettext("Secondary")
|
||||
value: "SECONDARY",
|
||||
name: gettext("Secondary")
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "masters",
|
||||
"readonly": readonly,
|
||||
"title": gettext("Masters"),
|
||||
"type": "array",
|
||||
"description": gettext("DNS master(s) for the Secondary zone."),
|
||||
"condition": "model.type == 'SECONDARY'",
|
||||
"add": gettext("Add Master"),
|
||||
"items": [
|
||||
key: "masters",
|
||||
readonly: readonly,
|
||||
title: gettext("Masters"),
|
||||
type: "array",
|
||||
description: gettext("DNS master(s) for the Secondary zone."),
|
||||
condition: "model.type == 'SECONDARY'",
|
||||
add: gettext("Add Master"),
|
||||
items: [
|
||||
{
|
||||
"key": "masters[].address",
|
||||
"title": gettext("IP Address")
|
||||
key: "masters[].address",
|
||||
title: gettext("IP Address")
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"model": {
|
||||
"type": "PRIMARY",
|
||||
"ttl": 3600
|
||||
model: {
|
||||
type: "PRIMARY",
|
||||
ttl: 3600
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -34,7 +34,7 @@
|
||||
'horizon.framework.widgets.modal-wait-spinner.service'
|
||||
];
|
||||
|
||||
/**
|
||||
/*
|
||||
* @ngDoc factory
|
||||
* @name designatedashboard.resources.os-designate-zone.actions.create
|
||||
*
|
||||
|
@ -70,8 +70,8 @@
|
||||
//////////////
|
||||
|
||||
function initAction() {
|
||||
context = { };
|
||||
deleteZonePromise = policy.ifAllowed({rules: [['dns', 'delete_zone']]});
|
||||
context = { };
|
||||
deleteZonePromise = policy.ifAllowed({rules: [['dns', 'delete_zone']]});
|
||||
}
|
||||
|
||||
function perform(items, scope) {
|
||||
|
@ -35,7 +35,7 @@
|
||||
'horizon.framework.widgets.modal-wait-spinner.service'
|
||||
];
|
||||
|
||||
/**
|
||||
/*
|
||||
* @ngDoc factory
|
||||
* @name designatedashboard.resources.os-designate-zone.actions.update
|
||||
*
|
||||
@ -52,7 +52,7 @@
|
||||
schemaFormModalService,
|
||||
toast,
|
||||
waitSpinner) {
|
||||
var updateZonePolicy, dnsServiceEnabled;
|
||||
var updateZonePolicy;
|
||||
var title = gettext("Update Zone");
|
||||
var message = {
|
||||
success: gettext('Zone %s was successfully updated.')
|
||||
@ -98,8 +98,8 @@
|
||||
// Map the masters objects to address objects
|
||||
if (item.hasOwnProperty("masters")) {
|
||||
var masters = item.masters.map(function (item) {
|
||||
return { "address": item }
|
||||
})
|
||||
return { address: item };
|
||||
});
|
||||
formConfig.masters = masters;
|
||||
}
|
||||
return schemaFormModalService.open(formConfig).then(onSubmit, onCancel);
|
||||
@ -112,7 +112,7 @@
|
||||
if (context.model.hasOwnProperty("masters")) {
|
||||
var masters = context.model.masters.map(function (item) {
|
||||
return item.address;
|
||||
})
|
||||
});
|
||||
zoneModel.masters = masters;
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@
|
||||
'horizon.framework.widgets.toast.service'
|
||||
];
|
||||
|
||||
/**
|
||||
/*
|
||||
* @ngdoc service
|
||||
* @param {Object} httpService
|
||||
* @param {Object} toastService
|
||||
@ -69,7 +69,7 @@
|
||||
});
|
||||
}*/
|
||||
function list(params) {
|
||||
var config = params ? {'params': params} : {};
|
||||
var config = params ? {params: params} : {};
|
||||
return httpService.get(apiPassthroughUrl + 'v2/zones/', config)
|
||||
.catch(function () {
|
||||
toastService.add('error', gettext('Unable to retrieve the zone.'));
|
||||
@ -93,7 +93,7 @@
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* @name deleteZone
|
||||
* @description
|
||||
* Delete a single zone by ID
|
||||
@ -121,7 +121,7 @@
|
||||
return httpService.post(apiPassthroughUrl + 'v2/zones/', data)
|
||||
.catch(function() {
|
||||
toastService.add('error', gettext('Unable to create the zone.'));
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -143,10 +143,10 @@
|
||||
ttl: data.ttl,
|
||||
description: data.description
|
||||
};
|
||||
return httpService.patch(apiPassthroughUrl + 'v2/zones/' + id + '/', apiData )
|
||||
return httpService.patch(apiPassthroughUrl + 'v2/zones/' + id + '/', apiData)
|
||||
.catch(function() {
|
||||
toastService.add('error', gettext('Unable to update the zone.'));
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
}());
|
||||
|
@ -50,7 +50,7 @@
|
||||
.prepend({
|
||||
id: 'zoneDetailsOverview',
|
||||
name: gettext('Overview'),
|
||||
template: basePath + 'details/overview.html',
|
||||
template: basePath + 'details/overview.html'
|
||||
}, 0);
|
||||
|
||||
function loadFunction(identifier) {
|
||||
|
@ -33,7 +33,7 @@
|
||||
) {
|
||||
var ctrl = this;
|
||||
|
||||
ctrl.item;
|
||||
ctrl.item = {};
|
||||
ctrl.resourceType = registry.getResourceType(resourceTypeCode);
|
||||
|
||||
$scope.context.loadPromise.then(onGetResponse);
|
||||
|
@ -40,7 +40,8 @@
|
||||
config.$inject = ['$provide', '$windowProvider'];
|
||||
|
||||
function config($provide, $windowProvider) {
|
||||
var path = $windowProvider.$get().STATIC_URL + 'designatedashboard/resources/os-designate-zone/';
|
||||
var path = $windowProvider.$get().STATIC_URL +
|
||||
'designatedashboard/resources/os-designate-zone/';
|
||||
$provide.constant('designatedashboard.resources.os-designate-zone.basePath', path);
|
||||
}
|
||||
|
||||
@ -136,7 +137,8 @@
|
||||
id: 'name',
|
||||
priority: 1,
|
||||
sortDefault: true,
|
||||
template: '<a ng-href="{$ \'' + detailRoute + 'OS::Designate::Zone/\' + item.id $}">{$ item.name $}</a>'
|
||||
template: '<a ng-href="{$ \'' + detailRoute +
|
||||
'OS::Designate::Zone/\' + item.id $}">{$ item.name $}</a>'
|
||||
})
|
||||
.append({
|
||||
id: 'type',
|
||||
@ -185,9 +187,9 @@
|
||||
|
||||
function typeMap() {
|
||||
return {
|
||||
'primary': gettext('Primary'),
|
||||
'secondary': gettext('Secondary')
|
||||
}
|
||||
primary: gettext('Primary'),
|
||||
secondary: gettext('Secondary')
|
||||
};
|
||||
}
|
||||
|
||||
function listZones() {
|
||||
|
@ -21,10 +21,9 @@
|
||||
.factory('designatedashboard.resources.util', utilService);
|
||||
|
||||
utilService.$inject = [
|
||||
'horizon.framework.util.q.extensions',
|
||||
'horizon.framework.util.q.extensions'
|
||||
];
|
||||
|
||||
|
||||
function utilService($qExtensions) {
|
||||
var service = {
|
||||
notDeleted: notDeleted,
|
||||
@ -47,9 +46,9 @@
|
||||
return $qExtensions.booleanAsPromise(resource.status !== 'PENDING');
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a model object based on the given item, using only the fields present in the form config 'key's.
|
||||
* Only 'truthy' values are copied.
|
||||
/*
|
||||
* Build a model object based on the given item, using only the fields
|
||||
* present in the form config 'key's. Only 'truthy' values are copied.
|
||||
*
|
||||
* @param form - an array of objects describing the form. Must have a 'key' attribute.
|
||||
* @param item - the data to copy into the model
|
||||
@ -68,19 +67,19 @@
|
||||
|
||||
function actionMap() {
|
||||
return {
|
||||
'none': gettext('None'),
|
||||
'create': gettext('Create')
|
||||
}
|
||||
none: gettext('None'),
|
||||
create: gettext('Create')
|
||||
};
|
||||
}
|
||||
|
||||
function statusMap() {
|
||||
return {
|
||||
'active': gettext('Active'),
|
||||
'pending': gettext('Pending')
|
||||
}
|
||||
active: gettext('Active'),
|
||||
pending: gettext('Pending')
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* hz-resource-table tracks by 'id' which doesn't change when an individual item is updated.
|
||||
* Create a synthetic '_timestampId' using the item id plus the specified timestamp field.
|
||||
* When this field is used as a track-by in hz-resource-table, items in the table to update
|
||||
@ -97,7 +96,7 @@
|
||||
var _idField = idField || 'id';
|
||||
var timestamp = Date.now();
|
||||
items.map(function annotateFloatingIp(item) {
|
||||
if ( angular.isDefined(timestampField) ) {
|
||||
if (angular.isDefined(timestampField)) {
|
||||
timestamp = item[timestampField];
|
||||
}
|
||||
item._timestampId = item[_idField] + timestamp;
|
||||
|
@ -6,8 +6,9 @@
|
||||
"repository": "none",
|
||||
"license": "Apache 2.0",
|
||||
"devDependencies": {
|
||||
"eslint": "1.10.3",
|
||||
"eslint": "^1.10.3",
|
||||
"eslint-config-openstack": "1.2.4",
|
||||
"eslint-plugin-angular": "^1.0.1",
|
||||
"jasmine-core": "2.4.1",
|
||||
"karma": "~1.1.2",
|
||||
"karma-firefox-launcher": "2.1.0",
|
||||
@ -23,4 +24,3 @@
|
||||
},
|
||||
"dependencies": {}
|
||||
}
|
||||
|
||||
|
12
tox.ini
12
tox.ini
@ -66,3 +66,15 @@ exclude=.venv,.git,.tox,dist,doc,*openstack/common*,*lib/python*,*egg,build,rele
|
||||
|
||||
[testenv:releasenotes]
|
||||
commands = sphinx-build -a -E -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html
|
||||
|
||||
[testenv:eslint]
|
||||
# npm must be installed on the system, for example
|
||||
# sudo apt-get install npm
|
||||
commands = npm install
|
||||
npm run lint
|
||||
|
||||
[testenv:karma]
|
||||
# npm must be installed on the system, for example
|
||||
# sudo apt-get install npm
|
||||
commands = npm install
|
||||
npm test
|
||||
|
Loading…
Reference in New Issue
Block a user