API v2 Dashboard
A Horizon dashboard based on the Designate v2 API. Using some of the latest Angular code available in Mitaka Horizon and a passthough API to avoid the need for the designate-client.. To view the new panel: - copy the following: * designatedashboard/enabled/_1710_project_dns_panel_group.py * designatedashboard/enabled/_1721_project_ngdns_panel.py * designatedashboard/enabled/_1722_dns_reversedns_panel.py into horizon/openstack_dashboard/local/enabled/ and restart horizon. Change-Id: I726bffbdc9514e1dc04dcb8e888d9808c6203867
This commit is contained in:
parent
5627ddb4a6
commit
54e46c9275
16
designatedashboard/api/rest/__init__.py
Normal file
16
designatedashboard/api/rest/__init__.py
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# (c) Copyright <year(s)> Hewlett Packard Enterprise Development LP
|
||||||
|
#
|
||||||
|
# Licensed 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.
|
||||||
|
"""REST API for Horizon dashboard Javascript code.
|
||||||
|
"""
|
||||||
|
from . import passthrough # noqa
|
114
designatedashboard/api/rest/passthrough.py
Normal file
114
designatedashboard/api/rest/passthrough.py
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
# Copyright 2016, Hewlett Packard Enterprise Development, LP
|
||||||
|
#
|
||||||
|
# Licensed 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.
|
||||||
|
"""API for the passthrough service.
|
||||||
|
"""
|
||||||
|
from django.conf import settings
|
||||||
|
from django.views import generic
|
||||||
|
import functools
|
||||||
|
import logging
|
||||||
|
import requests
|
||||||
|
from requests.exceptions import HTTPError
|
||||||
|
|
||||||
|
from horizon import exceptions
|
||||||
|
from openstack_dashboard.api import base
|
||||||
|
from openstack_dashboard.api.rest import urls
|
||||||
|
from openstack_dashboard.api.rest import utils as rest_utils
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def _passthrough_request(request_method, url,
|
||||||
|
request, data=None, params=None):
|
||||||
|
"""Makes a request to the appropriate service API with an optional payload.
|
||||||
|
|
||||||
|
Should set any necessary auth headers and SSL parameters.
|
||||||
|
"""
|
||||||
|
service = 'dns' \
|
||||||
|
''
|
||||||
|
# Set verify if a CACERT is set and SSL_NO_VERIFY isn't True
|
||||||
|
verify = getattr(settings, 'OPENSTACK_SSL_CACERT', None)
|
||||||
|
if getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', False):
|
||||||
|
verify = False
|
||||||
|
|
||||||
|
response = request_method(
|
||||||
|
_get_service_url(request, service) + url,
|
||||||
|
headers={'X-Auth-Token': request.user.token.id},
|
||||||
|
json=data,
|
||||||
|
verify=verify,
|
||||||
|
params=params
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
response.raise_for_status()
|
||||||
|
except HTTPError as e:
|
||||||
|
LOG.debug(e.response.content)
|
||||||
|
for error in rest_utils.http_errors:
|
||||||
|
if (e.response.status_code == getattr(error, 'status_code', 0) and
|
||||||
|
exceptions.HorizonException in error.__bases__):
|
||||||
|
raise error
|
||||||
|
raise
|
||||||
|
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
# Create some convenience partial functions
|
||||||
|
passthrough_get = functools.partial(_passthrough_request, requests.get)
|
||||||
|
passthrough_post = functools.partial(_passthrough_request, requests.post)
|
||||||
|
passthrough_put = functools.partial(_passthrough_request, requests.put)
|
||||||
|
passthrough_patch = functools.partial(_passthrough_request, requests.patch)
|
||||||
|
passthrough_delete = functools.partial(_passthrough_request, requests.delete)
|
||||||
|
|
||||||
|
|
||||||
|
def _get_service_url(request, service):
|
||||||
|
"""Get service's URL from keystone; allow an override in settings"""
|
||||||
|
service_url = getattr(settings, service.upper() + '_URL', None)
|
||||||
|
try:
|
||||||
|
service_url = base.url_for(request, service)
|
||||||
|
except exceptions.ServiceCatalogException:
|
||||||
|
pass
|
||||||
|
# Currently the keystone endpoint is http://host:port/
|
||||||
|
# without the version.
|
||||||
|
return service_url
|
||||||
|
|
||||||
|
|
||||||
|
@urls.register
|
||||||
|
class Passthrough(generic.View):
|
||||||
|
"""Pass-through API for executing service requests.
|
||||||
|
|
||||||
|
Horizon only adds auth and CORS proxying.
|
||||||
|
"""
|
||||||
|
url_regex = r'dns/(?P<path>.+)$'
|
||||||
|
|
||||||
|
@rest_utils.ajax()
|
||||||
|
def get(self, request, path):
|
||||||
|
return passthrough_get(path, request).json()
|
||||||
|
|
||||||
|
@rest_utils.ajax()
|
||||||
|
def post(self, request, path):
|
||||||
|
data = dict(request.DATA) if request.DATA else {}
|
||||||
|
return passthrough_post(path, request, data).json()
|
||||||
|
|
||||||
|
@rest_utils.ajax()
|
||||||
|
def put(self, request, path):
|
||||||
|
data = dict(request.DATA) if request.DATA else {}
|
||||||
|
return passthrough_put(path, request, data).json()
|
||||||
|
|
||||||
|
@rest_utils.ajax()
|
||||||
|
def patch(self, request, path):
|
||||||
|
data = dict(request.DATA) if request.DATA else {}
|
||||||
|
return passthrough_patch(path, request, data).json()
|
||||||
|
|
||||||
|
@rest_utils.ajax()
|
||||||
|
def delete(self, request, path):
|
||||||
|
return passthrough_delete(path, request).json()
|
@ -23,6 +23,7 @@ from openstack_dashboard.api.network import tenant_floating_ip_list
|
|||||||
from openstack_dashboard.api.nova import server_list
|
from openstack_dashboard.api.nova import server_list
|
||||||
|
|
||||||
from designatedashboard import api
|
from designatedashboard import api
|
||||||
|
from designatedashboard.api import rest # noqa
|
||||||
|
|
||||||
from .forms import DomainCreate # noqa
|
from .forms import DomainCreate # noqa
|
||||||
from .forms import DomainUpdate # noqa
|
from .forms import DomainUpdate # noqa
|
||||||
|
1
designatedashboard/dashboards/project/ngdns/__init__.py
Normal file
1
designatedashboard/dashboards/project/ngdns/__init__.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
from designatedashboard.api import rest # noqa
|
@ -0,0 +1,25 @@
|
|||||||
|
# (c) Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||||
|
#
|
||||||
|
# Licensed 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.
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
import horizon
|
||||||
|
from openstack_dashboard.dashboards.project import dashboard
|
||||||
|
|
||||||
|
|
||||||
|
class ReverseDns(horizon.Panel):
|
||||||
|
name = _("Reverse DNS")
|
||||||
|
slug = 'reverse_dns'
|
||||||
|
permissions = ('openstack.services.dns',)
|
||||||
|
|
||||||
|
dashboard.Project.register(ReverseDns)
|
@ -0,0 +1,22 @@
|
|||||||
|
# (c) Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||||
|
#
|
||||||
|
# Licensed 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.
|
||||||
|
|
||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
from designatedashboard.dashboards.project.ngdns.reverse_dns import views
|
||||||
|
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
url('', views.IndexView.as_view(), name='index'),
|
||||||
|
]
|
@ -0,0 +1,19 @@
|
|||||||
|
# (c) Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||||
|
#
|
||||||
|
# Licensed 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.
|
||||||
|
|
||||||
|
from django.views import generic
|
||||||
|
|
||||||
|
|
||||||
|
class IndexView(generic.TemplateView):
|
||||||
|
template_name = 'angular.html'
|
25
designatedashboard/dashboards/project/ngdns/zones/panel.py
Normal file
25
designatedashboard/dashboards/project/ngdns/zones/panel.py
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
# (c) Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||||
|
#
|
||||||
|
# Licensed 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.
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
import horizon
|
||||||
|
from openstack_dashboard.dashboards.project import dashboard
|
||||||
|
|
||||||
|
|
||||||
|
class Zones(horizon.Panel):
|
||||||
|
name = _("Zones")
|
||||||
|
slug = 'dnszones'
|
||||||
|
permissions = ('openstack.services.dns',)
|
||||||
|
|
||||||
|
dashboard.Project.register(Zones)
|
22
designatedashboard/dashboards/project/ngdns/zones/urls.py
Normal file
22
designatedashboard/dashboards/project/ngdns/zones/urls.py
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# (c) Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||||
|
#
|
||||||
|
# Licensed 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.
|
||||||
|
|
||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
from designatedashboard.dashboards.project.ngdns.zones import views
|
||||||
|
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
url('', views.IndexView.as_view(), name='index'),
|
||||||
|
]
|
19
designatedashboard/dashboards/project/ngdns/zones/views.py
Normal file
19
designatedashboard/dashboards/project/ngdns/zones/views.py
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# (c) Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||||
|
#
|
||||||
|
# Licensed 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.
|
||||||
|
|
||||||
|
from django.views import generic
|
||||||
|
|
||||||
|
|
||||||
|
class IndexView(generic.TemplateView):
|
||||||
|
template_name = 'angular.html'
|
@ -32,3 +32,5 @@ ADD_EXCEPTIONS = {
|
|||||||
# Python panel class of the PANEL to be added.
|
# Python panel class of the PANEL to be added.
|
||||||
ADD_PANEL = (
|
ADD_PANEL = (
|
||||||
'designatedashboard.dashboards.project.dns_domains.panel.DNSDomains')
|
'designatedashboard.dashboards.project.dns_domains.panel.DNSDomains')
|
||||||
|
|
||||||
|
DISABLED = True
|
||||||
|
40
designatedashboard/enabled/_1721_dns_zones_panel.py
Normal file
40
designatedashboard/enabled/_1721_dns_zones_panel.py
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
# Copyright 2013 Hewlett-Packard Development Company, L.P.
|
||||||
|
#
|
||||||
|
# Licensed 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.
|
||||||
|
|
||||||
|
from designatedashboard import exceptions
|
||||||
|
|
||||||
|
# The name of the panel to be added to HORIZON_CONFIG. Required.
|
||||||
|
PANEL = 'dnszones'
|
||||||
|
# The name of the dashboard the PANEL associated with. Required.
|
||||||
|
PANEL_DASHBOARD = 'project'
|
||||||
|
# The name of the panel group the PANEL is associated with.
|
||||||
|
PANEL_GROUP = 'dns'
|
||||||
|
|
||||||
|
ADD_EXCEPTIONS = {
|
||||||
|
'recoverable': exceptions.RECOVERABLE,
|
||||||
|
'not_found': exceptions.NOT_FOUND,
|
||||||
|
'unauthorized': exceptions.UNAUTHORIZED,
|
||||||
|
}
|
||||||
|
|
||||||
|
ADD_INSTALLED_APPS = ['designatedashboard']
|
||||||
|
|
||||||
|
# Python panel class of the PANEL to be added.
|
||||||
|
ADD_PANEL = (
|
||||||
|
'designatedashboard.dashboards.project.ngdns.zones.panel.Zones')
|
||||||
|
|
||||||
|
ADD_ANGULAR_MODULES = ['designatedashboard']
|
||||||
|
|
||||||
|
ADD_SCSS_FILES = ['designatedashboard/designatedashboard.scss']
|
||||||
|
|
||||||
|
AUTO_DISCOVER_STATIC_FILES = True
|
38
designatedashboard/enabled/_1722_dns_reversedns_panel.py
Normal file
38
designatedashboard/enabled/_1722_dns_reversedns_panel.py
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
# Copyright 2013 Hewlett-Packard Development Company, L.P.
|
||||||
|
#
|
||||||
|
# Licensed 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.
|
||||||
|
|
||||||
|
from designatedashboard import exceptions
|
||||||
|
|
||||||
|
# The name of the panel to be added to HORIZON_CONFIG. Required.
|
||||||
|
PANEL = 'reverse_dns'
|
||||||
|
# The name of the dashboard the PANEL associated with. Required.
|
||||||
|
PANEL_DASHBOARD = 'project'
|
||||||
|
# The name of the panel group the PANEL is associated with.
|
||||||
|
PANEL_GROUP = 'dns'
|
||||||
|
|
||||||
|
ADD_EXCEPTIONS = {
|
||||||
|
'recoverable': exceptions.RECOVERABLE,
|
||||||
|
'not_found': exceptions.NOT_FOUND,
|
||||||
|
'unauthorized': exceptions.UNAUTHORIZED,
|
||||||
|
}
|
||||||
|
|
||||||
|
# Python panel class of the PANEL to be added.
|
||||||
|
ADD_PANEL = (
|
||||||
|
'designatedashboard.dashboards.project.ngdns.reverse_dns.panel.ReverseDns')
|
||||||
|
|
||||||
|
ADD_ANGULAR_MODULES = ['designatedashboard']
|
||||||
|
|
||||||
|
ADD_SCSS_FILES = ['designatedashboard/designatedashboard.scss']
|
||||||
|
|
||||||
|
AUTO_DISCOVER_STATIC_FILES = True
|
@ -0,0 +1,78 @@
|
|||||||
|
/**
|
||||||
|
* (c) Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||||
|
*
|
||||||
|
* Licensed 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc overview
|
||||||
|
* @ngname designatedashboard
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Provides the services and widgets required
|
||||||
|
* to support and display the project search panel.
|
||||||
|
*/
|
||||||
|
angular
|
||||||
|
.module('designatedashboard', [
|
||||||
|
'ngRoute',
|
||||||
|
'designatedashboard.resources'
|
||||||
|
])
|
||||||
|
.constant(
|
||||||
|
'designatedashboard.apiPassthroughUrl', '/api/dns/')
|
||||||
|
.config(config)
|
||||||
|
.run(run);
|
||||||
|
|
||||||
|
config.$inject = [
|
||||||
|
'$provide',
|
||||||
|
'$routeProvider',
|
||||||
|
'$windowProvider'
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name designatedashboard.basePath
|
||||||
|
* @description Base path for the project dashboard
|
||||||
|
*
|
||||||
|
* @param {function} $provide ng provide service
|
||||||
|
*
|
||||||
|
* @param {function} $routeProvider ng route service
|
||||||
|
*
|
||||||
|
* @param {function} $windowProvider NG window provider
|
||||||
|
*
|
||||||
|
* @returns {undefined}
|
||||||
|
*/
|
||||||
|
function config($provide, $routeProvider, $windowProvider) {
|
||||||
|
var path = $windowProvider.$get().STATIC_URL + 'designatedashboard/';
|
||||||
|
$provide.constant('designatedashboard.basePath', path);
|
||||||
|
|
||||||
|
$routeProvider
|
||||||
|
.when('/project/dnszones/', {
|
||||||
|
templateUrl: path + 'zones.html'
|
||||||
|
})
|
||||||
|
.when('/project/reverse_dns/', {
|
||||||
|
templateUrl: path + 'reverse_dns.html'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
run.$inject = [
|
||||||
|
'horizon.framework.conf.resource-type-registry.service',
|
||||||
|
'designatedashboard.basePath'
|
||||||
|
];
|
||||||
|
|
||||||
|
function run(registry, basePath) {
|
||||||
|
//registry.setDefaultSummaryTemplateUrl(basePath + 'table/default-drawer.html');
|
||||||
|
}
|
||||||
|
|
||||||
|
})();
|
@ -0,0 +1,66 @@
|
|||||||
|
/**
|
||||||
|
* (c) Copyright 2016 Hewlett Packard Enterprise Development LP
|
||||||
|
*
|
||||||
|
* Licensed 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc overview
|
||||||
|
* @ngname designatedashboard.resources.os-designate-floatingip.actions
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Provides all of the actions for DNS Floating IPs.
|
||||||
|
*/
|
||||||
|
angular.module('designatedashboard.resources.os-designate-floatingip.actions', [
|
||||||
|
'horizon.framework.conf',
|
||||||
|
'horizon.app.core'
|
||||||
|
])
|
||||||
|
.run(run);
|
||||||
|
|
||||||
|
run.$inject = [
|
||||||
|
'horizon.framework.conf.resource-type-registry.service',
|
||||||
|
'designatedashboard.resources.os-designate-floatingip.resourceType',
|
||||||
|
'designatedashboard.resources.os-designate-floatingip.actions.set',
|
||||||
|
'designatedashboard.resources.os-designate-floatingip.actions.unset'
|
||||||
|
];
|
||||||
|
|
||||||
|
function run(
|
||||||
|
registry,
|
||||||
|
resourceTypeString,
|
||||||
|
setAction,
|
||||||
|
unsetAction)
|
||||||
|
{
|
||||||
|
var resourceType = registry.getResourceType(resourceTypeString);
|
||||||
|
|
||||||
|
resourceType
|
||||||
|
.itemActions
|
||||||
|
.append({
|
||||||
|
id: 'setFloatingIp',
|
||||||
|
service: setAction,
|
||||||
|
template: {
|
||||||
|
text: gettext('Set')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.append({
|
||||||
|
id: 'unsetFloatingIp',
|
||||||
|
service: unsetAction,
|
||||||
|
template: {
|
||||||
|
text: gettext('Unset')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
})();
|
@ -0,0 +1,170 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* (c) Copyright 2016 Hewlett Packard Enterprise Development Company LP
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use self 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
angular
|
||||||
|
.module('designatedashboard.resources.os-designate-floatingip.actions')
|
||||||
|
.factory('designatedashboard.resources.os-designate-floatingip.actions.set', action);
|
||||||
|
|
||||||
|
action.$inject = [
|
||||||
|
'$q',
|
||||||
|
'designatedashboard.resources.os-designate-floatingip.api',
|
||||||
|
'designatedashboard.resources.os-designate-floatingip.resourceType',
|
||||||
|
'designatedashboard.resources.util',
|
||||||
|
'horizon.app.core.openstack-service-api.serviceCatalog',
|
||||||
|
'horizon.framework.widgets.form.ModalFormService',
|
||||||
|
'horizon.framework.widgets.toast.service',
|
||||||
|
'horizon.framework.widgets.modal-wait-spinner.service'
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngDoc factory
|
||||||
|
* @name designatedashboard.resources.os-designate-floatingip.actions.set
|
||||||
|
*
|
||||||
|
* @Description
|
||||||
|
* Brings up the Set Floating IP modal.
|
||||||
|
*/
|
||||||
|
function action($q,
|
||||||
|
api,
|
||||||
|
resourceTypeName,
|
||||||
|
util,
|
||||||
|
serviceCatalog,
|
||||||
|
schemaFormModalService,
|
||||||
|
toast,
|
||||||
|
waitSpinner) {
|
||||||
|
var dnsServiceEnabled;
|
||||||
|
var title = null; // Set once perform is called
|
||||||
|
var formConfig = {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"ptrdname": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": /^.+\.$/
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"ttl": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 2147483647
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"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": "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"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
var message = {
|
||||||
|
success: gettext('Domain name PTR %s was successfully set.')
|
||||||
|
};
|
||||||
|
|
||||||
|
var service = {
|
||||||
|
initScope: initScope,
|
||||||
|
allowed: allowed,
|
||||||
|
perform: perform
|
||||||
|
};
|
||||||
|
|
||||||
|
return service;
|
||||||
|
|
||||||
|
/////////////////
|
||||||
|
|
||||||
|
function initScope() {
|
||||||
|
dnsServiceEnabled = serviceCatalog.ifTypeEnabled('dns');
|
||||||
|
}
|
||||||
|
|
||||||
|
function allowed(item) {
|
||||||
|
return $q.all([
|
||||||
|
// TODO (tyr) designate currently has no floating ips policy rules
|
||||||
|
dnsServiceEnabled,
|
||||||
|
util.notPending(item)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function perform(item) {
|
||||||
|
// Initialize the per-item title for use now and during submit
|
||||||
|
title = gettext("Set Domain Name PTR for ") + item.address;
|
||||||
|
formConfig.title = title;
|
||||||
|
|
||||||
|
// Get a form model based on the current item
|
||||||
|
formConfig.model = util.getModel(formConfig.form, item);
|
||||||
|
|
||||||
|
// Initialize default data
|
||||||
|
formConfig.model.ttl = formConfig.model.ttl || 3600;
|
||||||
|
|
||||||
|
// Remember the ID for use during submit
|
||||||
|
formConfig.model.floatingIpId = item.id;
|
||||||
|
|
||||||
|
return schemaFormModalService.open(formConfig).then(onSubmit, onCancel);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onSubmit(context) {
|
||||||
|
var model = angular.copy(context.model);
|
||||||
|
var floatingIpId = formConfig.model.floatingIpId;
|
||||||
|
|
||||||
|
waitSpinner.showModalSpinner(title);
|
||||||
|
return api.set(floatingIpId, model).then(onSuccess, onFailure);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onCancel() {
|
||||||
|
waitSpinner.hideModalSpinner();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onSuccess(response) {
|
||||||
|
waitSpinner.hideModalSpinner();
|
||||||
|
var floatingIp = response.data;
|
||||||
|
toast.add('success', interpolate(message.success, [floatingIp.ptrdname]));
|
||||||
|
|
||||||
|
// To make the result of this action generically useful, reformat the return
|
||||||
|
// from the deleteModal into a standard form
|
||||||
|
return {
|
||||||
|
created: [],
|
||||||
|
updated: [{type: resourceTypeName, id: floatingIp.id}],
|
||||||
|
deleted: [],
|
||||||
|
failed: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function onFailure() {
|
||||||
|
waitSpinner.hideModalSpinner();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
@ -0,0 +1,139 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* (c) Copyright 2016 Hewlett Packard Enterprise Development Company LP
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use self 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
angular
|
||||||
|
.module('designatedashboard.resources.os-designate-floatingip.actions')
|
||||||
|
.factory('designatedashboard.resources.os-designate-floatingip.actions.unset', action);
|
||||||
|
|
||||||
|
action.$inject = [
|
||||||
|
'$q',
|
||||||
|
'designatedashboard.resources.os-designate-floatingip.api',
|
||||||
|
'designatedashboard.resources.os-designate-floatingip.resourceType',
|
||||||
|
'designatedashboard.resources.util',
|
||||||
|
'horizon.app.core.openstack-service-api.serviceCatalog',
|
||||||
|
'horizon.framework.util.q.extensions',
|
||||||
|
'horizon.framework.widgets.form.ModalFormService',
|
||||||
|
'horizon.framework.widgets.toast.service',
|
||||||
|
'horizon.framework.widgets.modal-wait-spinner.service'
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngDoc factory
|
||||||
|
* @name designatedashboard.resources.os-designate-floatingip.actions.unset
|
||||||
|
*
|
||||||
|
* @Description
|
||||||
|
* Brings up the Unset Floating IP modal.
|
||||||
|
*/
|
||||||
|
function action($q,
|
||||||
|
api,
|
||||||
|
resourceTypeName,
|
||||||
|
util,
|
||||||
|
serviceCatalog,
|
||||||
|
$qExtensions,
|
||||||
|
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
|
||||||
|
|
||||||
|
// Unset it just a simple case of "set", but with ptrdname of 'null'
|
||||||
|
var formConfig = {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"form": [
|
||||||
|
],
|
||||||
|
"model": {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var message = {
|
||||||
|
success: gettext('Domain name PTR successfully unset.')
|
||||||
|
};
|
||||||
|
|
||||||
|
var service = {
|
||||||
|
initScope: initScope,
|
||||||
|
allowed: allowed,
|
||||||
|
perform: perform
|
||||||
|
};
|
||||||
|
|
||||||
|
return service;
|
||||||
|
|
||||||
|
/////////////////
|
||||||
|
|
||||||
|
function initScope() {
|
||||||
|
dnsServiceEnabled = serviceCatalog.ifTypeEnabled('dns');
|
||||||
|
}
|
||||||
|
|
||||||
|
function allowed(item) {
|
||||||
|
return $q.all([
|
||||||
|
// TODO (tyr) designate currently has no floating ip policy rules
|
||||||
|
dnsServiceEnabled,
|
||||||
|
domainNameSet(item),
|
||||||
|
util.notPending(item)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function domainNameSet(item) {
|
||||||
|
return $qExtensions.booleanAsPromise(
|
||||||
|
angular.isString(item.ptrdname)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function perform(item) {
|
||||||
|
title = gettext("Unset Domain Name PTR for ") + item.address;
|
||||||
|
// Store the zone ID so it can be used on submit
|
||||||
|
formConfig.model.floatingIpId = item.id;
|
||||||
|
formConfig.title = title;
|
||||||
|
return schemaFormModalService.open(formConfig).then(onSubmit, onCancel);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onSubmit(context) {
|
||||||
|
waitSpinner.showModalSpinner(title);
|
||||||
|
currentFloatingIpId = context.model.floatingIpId;
|
||||||
|
return api.unset(currentFloatingIpId).then(onSuccess, onFailure);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onCancel() {
|
||||||
|
waitSpinner.hideModalSpinner();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onSuccess(response) {
|
||||||
|
waitSpinner.hideModalSpinner();
|
||||||
|
toast.add('success', message.success);
|
||||||
|
|
||||||
|
// To make the result of this action generically useful, reformat the return
|
||||||
|
// from the deleteModal into a standard form
|
||||||
|
return {
|
||||||
|
created: [],
|
||||||
|
updated: [{type: resourceTypeName, id: currentFloatingIpId}],
|
||||||
|
deleted: [],
|
||||||
|
failed: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function onFailure() {
|
||||||
|
waitSpinner.hideModalSpinner();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
@ -0,0 +1,121 @@
|
|||||||
|
/**
|
||||||
|
* (c) Copyright 2016 Hewlett Packard Enterprise Development LP
|
||||||
|
*
|
||||||
|
* Licensed 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.
|
||||||
|
*/
|
||||||
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
angular
|
||||||
|
.module('designatedashboard.resources.os-designate-floatingip')
|
||||||
|
.factory('designatedashboard.resources.os-designate-floatingip.api', apiService);
|
||||||
|
|
||||||
|
apiService.$inject = [
|
||||||
|
'designatedashboard.apiPassthroughUrl',
|
||||||
|
'horizon.framework.util.http.service',
|
||||||
|
'horizon.framework.widgets.toast.service'
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc service
|
||||||
|
* @param {Object} httpService
|
||||||
|
* @param {Object} toastService
|
||||||
|
* @name apiService
|
||||||
|
* @description Provides direct access to Designate Floating IP APIs.
|
||||||
|
* @returns {Object} The service
|
||||||
|
*/
|
||||||
|
function apiService(apiPassthroughUrl, httpService, toastService) {
|
||||||
|
var service = {
|
||||||
|
list: list,
|
||||||
|
get: get,
|
||||||
|
set: set,
|
||||||
|
unset: unset
|
||||||
|
};
|
||||||
|
|
||||||
|
return service;
|
||||||
|
|
||||||
|
///////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name list
|
||||||
|
* @description
|
||||||
|
* Get a list of DNS floating ips.
|
||||||
|
*
|
||||||
|
* The listing result is an object with property "items." Each item is
|
||||||
|
* a floating IP PTR record.
|
||||||
|
*
|
||||||
|
* @param {Object} params
|
||||||
|
* Query parameters. Optional.
|
||||||
|
*
|
||||||
|
* @returns {Object} The result of the API call
|
||||||
|
*/
|
||||||
|
function list(params) {
|
||||||
|
var config = params ? {'params': params} : {};
|
||||||
|
return httpService.get(apiPassthroughUrl + 'v2/reverse/floatingips', config)
|
||||||
|
.error(function () {
|
||||||
|
toastService.add('error', gettext('Unable to retrieve the floating ip PTRs.'));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function get(id, params) {
|
||||||
|
var config = params ? {'params': params} : {};
|
||||||
|
return httpService.get(apiPassthroughUrl + 'v2/reverse/floatingips/' + id, config)
|
||||||
|
.error(function () {
|
||||||
|
toastService.add('error', gettext('Unable to get the floating ip PTR ' + id));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name set
|
||||||
|
* @description
|
||||||
|
* Set a floating ip PTR record
|
||||||
|
*
|
||||||
|
* @param {string} floatingIpID - ID of PTR record to unset
|
||||||
|
* @param {Object} data
|
||||||
|
* Specifies the PTR information to set
|
||||||
|
*
|
||||||
|
* @returns {Object} The updated DNS floating IP object
|
||||||
|
*/
|
||||||
|
function set(floatingIpID, data) {
|
||||||
|
// The update API will not accept extra data. Restrict the input to only the allowed
|
||||||
|
// fields
|
||||||
|
var apiData = {
|
||||||
|
ptrdname: data.ptrdname,
|
||||||
|
description: data.description,
|
||||||
|
ttl: data.ttl
|
||||||
|
};
|
||||||
|
return httpService.patch(apiPassthroughUrl + 'v2/reverse/floatingips/' + floatingIpID, apiData)
|
||||||
|
.error(function () {
|
||||||
|
toastService.add('error', gettext('Unable to set the floating IP PTR record.'));
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name unset
|
||||||
|
* @description
|
||||||
|
* Unset a floating ip PTR record
|
||||||
|
*
|
||||||
|
* @param {string} floatingIpID - ID of PTR record to unset
|
||||||
|
*
|
||||||
|
* @returns {Object} The updated DNS floating IP object
|
||||||
|
*/
|
||||||
|
function unset(floatingIpID) {
|
||||||
|
// Unset is just a special case of 'set'
|
||||||
|
return set(floatingIpID, {
|
||||||
|
ptrdname: null,
|
||||||
|
description: null,
|
||||||
|
ttl: null
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}());
|
@ -0,0 +1,66 @@
|
|||||||
|
/**
|
||||||
|
* (c) Copyright 2016 Hewlett Packard Enterprise Development LP
|
||||||
|
*
|
||||||
|
* Licensed 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc overview
|
||||||
|
* @ngname designatedashboard.resources.os-designate-floatingip.details
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Provides details features for floating IPs.
|
||||||
|
*/
|
||||||
|
angular.module('designatedashboard.resources.os-designate-floatingip.details',
|
||||||
|
['horizon.framework.conf', 'horizon.app.core'])
|
||||||
|
.run(run);
|
||||||
|
|
||||||
|
run.$inject = [
|
||||||
|
'designatedashboard.resources.os-designate-floatingip.resourceType',
|
||||||
|
'designatedashboard.resources.os-designate-floatingip.api',
|
||||||
|
'designatedashboard.resources.os-designate-floatingip.basePath',
|
||||||
|
'horizon.framework.conf.resource-type-registry.service'
|
||||||
|
];
|
||||||
|
|
||||||
|
function run(
|
||||||
|
resourceTypeName,
|
||||||
|
api,
|
||||||
|
basePath,
|
||||||
|
registry
|
||||||
|
) {
|
||||||
|
var resourceType = registry.getResourceType(resourceTypeName);
|
||||||
|
resourceType
|
||||||
|
.setLoadFunction(loadFunction)
|
||||||
|
.setSummaryTemplateUrl(basePath + 'details/drawer.html')
|
||||||
|
.setItemNameFunction(itemNameFunction);
|
||||||
|
|
||||||
|
resourceType.detailsViews
|
||||||
|
.prepend({
|
||||||
|
id: 'floatingIpDetailsOverview',
|
||||||
|
name: gettext('Overview'),
|
||||||
|
template: basePath + 'details/overview.html'
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
function loadFunction(identifier) {
|
||||||
|
return api.get(identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
function itemNameFunction(floatingIp) {
|
||||||
|
return floatingIp.address;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
})();
|
@ -0,0 +1,10 @@
|
|||||||
|
<hz-resource-property-list
|
||||||
|
ng-if="item"
|
||||||
|
resource-type-name="OS::Designate::FloatingIp"
|
||||||
|
item="item"
|
||||||
|
cls="dl-horizontal"
|
||||||
|
property-groups="[
|
||||||
|
['description'],
|
||||||
|
['id']
|
||||||
|
]">
|
||||||
|
</hz-resource-property-list>
|
@ -0,0 +1,46 @@
|
|||||||
|
/**
|
||||||
|
* (c) Copyright 2016 Hewlett Packard Enterprise Development LP
|
||||||
|
*
|
||||||
|
* Licensed 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.
|
||||||
|
*/
|
||||||
|
(function() {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
angular
|
||||||
|
.module('designatedashboard.resources.os-designate-floatingip.details')
|
||||||
|
.controller('designatedashboard.resources.os-designate-floatingip.details.overviewController', controller);
|
||||||
|
|
||||||
|
controller.$inject = [
|
||||||
|
'designatedashboard.resources.os-designate-floatingip.resourceType',
|
||||||
|
'horizon.framework.conf.resource-type-registry.service',
|
||||||
|
'$scope'
|
||||||
|
];
|
||||||
|
|
||||||
|
function controller(
|
||||||
|
resourceTypeCode,
|
||||||
|
registry,
|
||||||
|
$scope
|
||||||
|
) {
|
||||||
|
var ctrl = this;
|
||||||
|
|
||||||
|
ctrl.item;
|
||||||
|
ctrl.resourceType = registry.getResourceType(resourceTypeCode);
|
||||||
|
|
||||||
|
$scope.context.loadPromise.then(onGetResponse);
|
||||||
|
|
||||||
|
function onGetResponse(response) {
|
||||||
|
ctrl.item = response.data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
})();
|
@ -0,0 +1,11 @@
|
|||||||
|
<div ng-controller="designatedashboard.resources.os-designate-floatingip.details.overviewController as ctrl">
|
||||||
|
<hz-resource-property-list
|
||||||
|
ng-if="ctrl.item"
|
||||||
|
resource-type-name="OS::Designate::FloatingIp"
|
||||||
|
item="ctrl.item"
|
||||||
|
cls="dl-horizontal"
|
||||||
|
property-groups="[
|
||||||
|
['ptrdname', 'description', 'id', 'ttl', 'status', 'action']
|
||||||
|
]">
|
||||||
|
</hz-resource-property-list>
|
||||||
|
</div>
|
@ -0,0 +1,154 @@
|
|||||||
|
/**
|
||||||
|
* (c) Copyright 2016 Hewlett Packard Enterprise Development LP
|
||||||
|
*
|
||||||
|
* Licensed 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc overview
|
||||||
|
* @ngname designatedashboard.resources.os-designate-floatingip
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Provides all of the services and widgets required
|
||||||
|
* to support and display DNS (designate) floating ip related content.
|
||||||
|
*/
|
||||||
|
angular
|
||||||
|
.module('designatedashboard.resources.os-designate-floatingip', [
|
||||||
|
'ngRoute',
|
||||||
|
'designatedashboard.resources.os-designate-floatingip.actions',
|
||||||
|
'designatedashboard.resources.os-designate-floatingip.details'
|
||||||
|
])
|
||||||
|
.constant(
|
||||||
|
'designatedashboard.resources.os-designate-floatingip.resourceType',
|
||||||
|
'OS::Designate::FloatingIp')
|
||||||
|
.config(config)
|
||||||
|
.run(run);
|
||||||
|
|
||||||
|
config.$inject = [ '$provide', '$windowProvider' ];
|
||||||
|
|
||||||
|
function config($provide, $windowProvider) {
|
||||||
|
var path = $windowProvider.$get().STATIC_URL + 'designatedashboard/resources/os-designate-floatingip/';
|
||||||
|
$provide.constant('designatedashboard.resources.os-designate-floatingip.basePath', path);
|
||||||
|
}
|
||||||
|
|
||||||
|
run.$inject = [
|
||||||
|
'horizon.framework.conf.resource-type-registry.service',
|
||||||
|
'designatedashboard.resources.os-designate-floatingip.api',
|
||||||
|
'designatedashboard.resources.os-designate-floatingip.resourceType',
|
||||||
|
'designatedashboard.resources.util'
|
||||||
|
];
|
||||||
|
|
||||||
|
function run(
|
||||||
|
registry,
|
||||||
|
api,
|
||||||
|
resourceTypeString,
|
||||||
|
util)
|
||||||
|
{
|
||||||
|
var resourceType = registry.getResourceType(resourceTypeString);
|
||||||
|
resourceType
|
||||||
|
.setNames(gettext('Floating IP'), gettext('Floating IPs'))
|
||||||
|
.setListFunction(listFloatingIps)
|
||||||
|
.setProperty('id', {
|
||||||
|
label: gettext('ID')
|
||||||
|
})
|
||||||
|
.setProperty('ptrdname', {
|
||||||
|
label: gettext('PTR Domain Name'),
|
||||||
|
filters: ['noName']
|
||||||
|
})
|
||||||
|
.setProperty('description', {
|
||||||
|
label: gettext('Description'),
|
||||||
|
filters: ['noName']
|
||||||
|
})
|
||||||
|
.setProperty('ttl', {
|
||||||
|
label: gettext('Time To Live'),
|
||||||
|
filters: ['noValue']
|
||||||
|
})
|
||||||
|
.setProperty('address', {
|
||||||
|
label: gettext('Address'),
|
||||||
|
filters: ['noName']
|
||||||
|
})
|
||||||
|
.setProperty('status', {
|
||||||
|
label: gettext('Status'),
|
||||||
|
filters: ['lowercase', 'noName'],
|
||||||
|
values: util.statusMap()
|
||||||
|
})
|
||||||
|
.setProperty('action', {
|
||||||
|
label: gettext('Action'),
|
||||||
|
filters: ['lowercase', 'noName'],
|
||||||
|
values: util.actionMap()
|
||||||
|
});
|
||||||
|
|
||||||
|
resourceType
|
||||||
|
.tableColumns
|
||||||
|
.append({
|
||||||
|
id: 'address',
|
||||||
|
priority: 1,
|
||||||
|
sortDefault: true,
|
||||||
|
template: '<a ng-href="{$ \'project/ngdetails/OS::Designate::FloatingIp/\' + item.id $}">{$ item.address $}</a>'
|
||||||
|
})
|
||||||
|
.append({
|
||||||
|
id: 'ptrdname',
|
||||||
|
filters: ['noValue'],
|
||||||
|
priority: 1,
|
||||||
|
})
|
||||||
|
.append({
|
||||||
|
id: 'status',
|
||||||
|
filters: ['lowercase'],
|
||||||
|
values: util.statusMap(),
|
||||||
|
priority: 2
|
||||||
|
});
|
||||||
|
|
||||||
|
resourceType
|
||||||
|
.filterFacets
|
||||||
|
.append({
|
||||||
|
label: gettext('Address'),
|
||||||
|
name: 'address',
|
||||||
|
isServer: false,
|
||||||
|
singleton: true,
|
||||||
|
persistent: false
|
||||||
|
})
|
||||||
|
.append({
|
||||||
|
label: gettext('PTR Domain Name'),
|
||||||
|
name: 'ptrdname',
|
||||||
|
isServer: false,
|
||||||
|
singleton: true,
|
||||||
|
persistent: false
|
||||||
|
})
|
||||||
|
.append({
|
||||||
|
label: gettext('Status'),
|
||||||
|
name: 'status',
|
||||||
|
isServer: false,
|
||||||
|
singleton: true,
|
||||||
|
persistent: false,
|
||||||
|
options: [
|
||||||
|
{label: gettext('Active'), key: 'active'},
|
||||||
|
{label: gettext('Pending'), key: 'pending'}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
function listFloatingIps() {
|
||||||
|
return api.list().then(function onList(response) {
|
||||||
|
// listFunctions are expected to return data in "items"
|
||||||
|
response.data.items = response.data.floatingips;
|
||||||
|
|
||||||
|
util.addTimestampIds(response.data.items);
|
||||||
|
|
||||||
|
return response;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
})();
|
@ -0,0 +1,79 @@
|
|||||||
|
/**
|
||||||
|
* (c) Copyright 2016 Hewlett Packard Enterprise Development LP
|
||||||
|
*
|
||||||
|
* Licensed 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc overview
|
||||||
|
* @ngname designatedashboard.resources.os-designate-recordset.actions
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Provides all of the actions for DNS Recordsets.
|
||||||
|
*/
|
||||||
|
angular.module('designatedashboard.resources.os-designate-recordset.actions', [
|
||||||
|
'horizon.framework.conf',
|
||||||
|
'horizon.app.core'
|
||||||
|
])
|
||||||
|
.run(run);
|
||||||
|
|
||||||
|
run.$inject = [
|
||||||
|
'horizon.framework.conf.resource-type-registry.service',
|
||||||
|
'designatedashboard.resources.os-designate-recordset.resourceType',
|
||||||
|
'designatedashboard.resources.os-designate-recordset.actions.create',
|
||||||
|
'designatedashboard.resources.os-designate-recordset.actions.delete',
|
||||||
|
'designatedashboard.resources.os-designate-recordset.actions.update'
|
||||||
|
];
|
||||||
|
|
||||||
|
function run(registry,
|
||||||
|
resourceTypeString,
|
||||||
|
createAction,
|
||||||
|
deleteAction,
|
||||||
|
updateAction) {
|
||||||
|
var resourceType = registry.getResourceType(resourceTypeString);
|
||||||
|
|
||||||
|
resourceType
|
||||||
|
.itemActions
|
||||||
|
.append({
|
||||||
|
id: 'updateRecordset',
|
||||||
|
service: updateAction,
|
||||||
|
template: {
|
||||||
|
text: gettext('Update')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.append({
|
||||||
|
id: 'deleteRecordset',
|
||||||
|
service: deleteAction,
|
||||||
|
template: {
|
||||||
|
text: gettext('Delete'),
|
||||||
|
type: 'delete'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Append a record set view to the zones actions
|
||||||
|
var zoneResourceType = registry.getResourceType("OS::Designate::Zone");
|
||||||
|
zoneResourceType
|
||||||
|
.itemActions
|
||||||
|
.append({
|
||||||
|
id: 'createRecordset',
|
||||||
|
service: createAction,
|
||||||
|
template: {
|
||||||
|
text: gettext('Create Record Set')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
})();
|
@ -0,0 +1,165 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* (c) Copyright 2016 Hewlett Packard Enterprise Development Company LP
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use self 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
angular
|
||||||
|
.module('designatedashboard.resources.os-designate-recordset.actions')
|
||||||
|
.factory('designatedashboard.resources.os-designate-recordset.actions.common-forms', service);
|
||||||
|
|
||||||
|
service.$inject = [
|
||||||
|
'designatedashboard.resources.os-designate-recordset.editableTypes',
|
||||||
|
'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.
|
||||||
|
*
|
||||||
|
* @returns {object} A schema form config
|
||||||
|
*/
|
||||||
|
function service(editableTypes, typeMap) {
|
||||||
|
var service = {
|
||||||
|
getCreateFormConfig: getCreateFormConfig,
|
||||||
|
getUpdateFormConfig: getUpdateFormConfig
|
||||||
|
};
|
||||||
|
|
||||||
|
return service;
|
||||||
|
|
||||||
|
/////////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the create form config
|
||||||
|
* @returns {{schema, form, model}|*}
|
||||||
|
*/
|
||||||
|
function getCreateFormConfig() {
|
||||||
|
return getCreateUpdateFormConfig(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the update form config
|
||||||
|
* @returns {{schema, form, model}|*}
|
||||||
|
*/
|
||||||
|
function getUpdateFormConfig() {
|
||||||
|
return getCreateUpdateFormConfig(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the create/update form. The two forms are identical except for
|
||||||
|
* during update, some fields are read-only.
|
||||||
|
*
|
||||||
|
* @param readonly - sets readonly value on form fields that change between update and create
|
||||||
|
* @returns {object} a schema form config, including default model
|
||||||
|
*/
|
||||||
|
function getCreateUpdateFormConfig(readonly) {
|
||||||
|
return {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": /^.+\.$/
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": editableTypes
|
||||||
|
},
|
||||||
|
"ttl": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 1,
|
||||||
|
"maximum": 2147483647
|
||||||
|
},
|
||||||
|
"records": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"record": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"minItems": 1,
|
||||||
|
"uniqueItems": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"form": [
|
||||||
|
{
|
||||||
|
"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]
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
"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": "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[].record",
|
||||||
|
"title": gettext("Record")
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"model": {
|
||||||
|
"type": "A",
|
||||||
|
"ttl": 3600
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
@ -0,0 +1,132 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* (c) Copyright 2016 Hewlett Packard Enterprise Development Company LP
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use self 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
angular
|
||||||
|
.module('designatedashboard.resources.os-designate-recordset.actions')
|
||||||
|
.factory('designatedashboard.resources.os-designate-recordset.actions.create', action);
|
||||||
|
|
||||||
|
action.$inject = [
|
||||||
|
'$q',
|
||||||
|
'designatedashboard.resources.os-designate-recordset.actions.common-forms',
|
||||||
|
'designatedashboard.resources.os-designate-recordset.api',
|
||||||
|
'designatedashboard.resources.os-designate-recordset.resourceType',
|
||||||
|
'horizon.app.core.openstack-service-api.policy',
|
||||||
|
'horizon.app.core.openstack-service-api.serviceCatalog',
|
||||||
|
'horizon.framework.conf.resource-type-registry.service',
|
||||||
|
'horizon.framework.widgets.form.ModalFormService',
|
||||||
|
'horizon.framework.widgets.toast.service',
|
||||||
|
'horizon.framework.widgets.modal-wait-spinner.service'
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngDoc factory
|
||||||
|
* @name designatedashboard.resources.os-designate-recordset.actions.create
|
||||||
|
*
|
||||||
|
* @Description
|
||||||
|
* Brings up the Create Record Set modal.
|
||||||
|
*/
|
||||||
|
function action($q,
|
||||||
|
forms,
|
||||||
|
api,
|
||||||
|
resourceTypeName,
|
||||||
|
policy,
|
||||||
|
serviceCatalog,
|
||||||
|
registry,
|
||||||
|
schemaFormModalService,
|
||||||
|
toast,
|
||||||
|
waitSpinner) {
|
||||||
|
var createRecordSetPolicy, dnsServiceEnabled;
|
||||||
|
var title = gettext("Create Record Set");
|
||||||
|
var message = {
|
||||||
|
success: gettext('Record Set %s was successfully created.')
|
||||||
|
};
|
||||||
|
|
||||||
|
var service = {
|
||||||
|
initScope: initScope,
|
||||||
|
allowed: allowed,
|
||||||
|
perform: perform
|
||||||
|
};
|
||||||
|
|
||||||
|
return service;
|
||||||
|
|
||||||
|
/////////////////
|
||||||
|
|
||||||
|
function initScope() {
|
||||||
|
createRecordSetPolicy = policy.ifAllowed({rules: [['dns', 'create_recordset']]});
|
||||||
|
dnsServiceEnabled = serviceCatalog.ifTypeEnabled('dns');
|
||||||
|
}
|
||||||
|
|
||||||
|
function allowed(item) {
|
||||||
|
return $q.all([
|
||||||
|
createRecordSetPolicy,
|
||||||
|
dnsServiceEnabled
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function perform(item) {
|
||||||
|
var formConfig = forms.getCreateFormConfig();
|
||||||
|
|
||||||
|
// Store the zone ID so it can be used on submit
|
||||||
|
formConfig.model.zoneId = item.id;
|
||||||
|
|
||||||
|
formConfig.title = title;
|
||||||
|
return schemaFormModalService.open(formConfig).then(onSubmit, onCancel);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onSubmit(context) {
|
||||||
|
var model = angular.copy(context.model);
|
||||||
|
var zoneId = model.zoneId;
|
||||||
|
delete model.zoneId;
|
||||||
|
|
||||||
|
// schema form doesn't appear to support populating arrays directly
|
||||||
|
// Map the records objects to simple array of records
|
||||||
|
var records = context.model.records.map(function (item) {
|
||||||
|
return item.record;
|
||||||
|
});
|
||||||
|
model.records = records;
|
||||||
|
|
||||||
|
waitSpinner.showModalSpinner(gettext('Creating Record Set'));
|
||||||
|
return api.create(zoneId, model).then(onSuccess, onFailure);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onCancel() {
|
||||||
|
waitSpinner.hideModalSpinner();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onSuccess(response) {
|
||||||
|
waitSpinner.hideModalSpinner();
|
||||||
|
var zone = response.data;
|
||||||
|
toast.add('success', interpolate(message.success, [zone.name]));
|
||||||
|
|
||||||
|
// To make the result of this action generically useful, reformat the return
|
||||||
|
// from the deleteModal into a standard form
|
||||||
|
return {
|
||||||
|
created: [{type: resourceTypeName, id: zone.id}],
|
||||||
|
updated: [],
|
||||||
|
deleted: [],
|
||||||
|
failed: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function onFailure() {
|
||||||
|
waitSpinner.hideModalSpinner();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
@ -0,0 +1,182 @@
|
|||||||
|
/**
|
||||||
|
* (c) Copyright 2016 Hewlett Packard Enterprise Development LP
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use self 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
angular
|
||||||
|
.module('designatedashboard.resources.os-designate-recordset.actions')
|
||||||
|
.factory('designatedashboard.resources.os-designate-recordset.actions.delete', action);
|
||||||
|
|
||||||
|
action.$inject = [
|
||||||
|
'$q',
|
||||||
|
'designatedashboard.resources.os-designate-recordset.api',
|
||||||
|
'designatedashboard.resources.os-designate-recordset.editableTypes',
|
||||||
|
'designatedashboard.resources.os-designate-recordset.resourceType',
|
||||||
|
'horizon.app.core.openstack-service-api.policy',
|
||||||
|
'horizon.framework.util.actions.action-result.service',
|
||||||
|
'horizon.framework.util.i18n.gettext',
|
||||||
|
'horizon.framework.util.q.extensions',
|
||||||
|
'horizon.framework.widgets.modal.deleteModalService',
|
||||||
|
'horizon.framework.widgets.toast.service'
|
||||||
|
];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @ngdoc factory
|
||||||
|
* @name designatedashboard.resources.os-designate-recordset.actions.delete
|
||||||
|
*
|
||||||
|
* @Description
|
||||||
|
* Brings up the delete recordset confirmation modal dialog.
|
||||||
|
|
||||||
|
* On submit, delete given recordset.
|
||||||
|
* On cancel, do nothing.
|
||||||
|
*/
|
||||||
|
function action(
|
||||||
|
$q,
|
||||||
|
recordsetApi,
|
||||||
|
editableTypes,
|
||||||
|
resourceType,
|
||||||
|
policy,
|
||||||
|
actionResultService,
|
||||||
|
gettext,
|
||||||
|
$qExtensions,
|
||||||
|
deleteModal,
|
||||||
|
toast
|
||||||
|
) {
|
||||||
|
var scope, context, deletePromise;
|
||||||
|
var notAllowedMessage = gettext("You are not allowed to delete record sets: %s");
|
||||||
|
var allowedRecordsets = [];
|
||||||
|
|
||||||
|
var service = {
|
||||||
|
initScope: initScope,
|
||||||
|
allowed: allowed,
|
||||||
|
perform: perform
|
||||||
|
};
|
||||||
|
|
||||||
|
return service;
|
||||||
|
|
||||||
|
//////////////
|
||||||
|
|
||||||
|
function initScope(newScope) {
|
||||||
|
scope = newScope;
|
||||||
|
context = { };
|
||||||
|
deletePromise = policy.ifAllowed({rules: [['dns', 'delete_recordset']]});
|
||||||
|
}
|
||||||
|
|
||||||
|
function perform(items) {
|
||||||
|
var recordsets = angular.isArray(items) ? items : [items];
|
||||||
|
context.labels = labelize(recordsets.length);
|
||||||
|
context.deleteEntity = deleteRecordSet;
|
||||||
|
return $qExtensions.allSettled(recordsets.map(checkPermission)).then(afterCheck);
|
||||||
|
}
|
||||||
|
|
||||||
|
function allowed(recordset) {
|
||||||
|
// only row actions pass in recordset
|
||||||
|
// otherwise, assume it is a batch action
|
||||||
|
if (recordset) {
|
||||||
|
return $q.all([
|
||||||
|
deletePromise,
|
||||||
|
editableRecordType(recordset)
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
return policy.ifAllowed({ rules: [['dns', 'delete_recordset']] });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkPermission(recordset) {
|
||||||
|
return {promise: allowed(recordset), context: recordset};
|
||||||
|
}
|
||||||
|
|
||||||
|
function afterCheck(result) {
|
||||||
|
var outcome = $q.reject(); // Reject the promise by default
|
||||||
|
if (result.fail.length > 0) {
|
||||||
|
toast.add('error', getMessage(notAllowedMessage, result.fail));
|
||||||
|
outcome = $q.reject(result.fail);
|
||||||
|
}
|
||||||
|
if (result.pass.length > 0) {
|
||||||
|
// 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)
|
||||||
|
outcome = deleteModal.open(scope, allowedRecordsets, context).then(createResult);
|
||||||
|
}
|
||||||
|
return outcome;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createResult(deleteModalResult) {
|
||||||
|
// To make the result of this action generically useful, reformat the return
|
||||||
|
// from the deleteModal into a standard form
|
||||||
|
var actionResult = actionResultService.getActionResult();
|
||||||
|
deleteModalResult.pass.forEach(function markDeleted(item) {
|
||||||
|
actionResult.deleted(resourceType, getEntity(item).id);
|
||||||
|
});
|
||||||
|
deleteModalResult.fail.forEach(function markFailed(item) {
|
||||||
|
actionResult.failed(resourceType, getEntity(item).id);
|
||||||
|
});
|
||||||
|
return actionResult.result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function labelize(count) {
|
||||||
|
return {
|
||||||
|
|
||||||
|
title: ngettext(
|
||||||
|
'Confirm Delete Record Set',
|
||||||
|
'Confirm Delete Record Sets', count),
|
||||||
|
|
||||||
|
message: ngettext(
|
||||||
|
'You have selected "%s". Deleted record set is not recoverable.',
|
||||||
|
'You have selected "%s". Deleted record sets are not recoverable.', count),
|
||||||
|
|
||||||
|
submit: ngettext(
|
||||||
|
'Delete Record Set',
|
||||||
|
'Delete Record Sets', count),
|
||||||
|
|
||||||
|
success: ngettext(
|
||||||
|
'Deleted Record Set: %s.',
|
||||||
|
'Deleted Record Sets: %s.', count),
|
||||||
|
|
||||||
|
error: ngettext(
|
||||||
|
'Unable to delete Record Set: %s.',
|
||||||
|
'Unable to delete Record Sets: %s.', count)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function editableRecordType(recordset) {
|
||||||
|
return $qExtensions.booleanAsPromise(
|
||||||
|
editableTypes.indexOf(recordset.type) > -1
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteRecordSet(recordSetId) {
|
||||||
|
var recordSet = allowedRecordsets.find(function(element) {
|
||||||
|
return element.id === recordSetId;
|
||||||
|
})
|
||||||
|
return recordsetApi.deleteRecordSet(recordSet.zone_id, recordSet.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMessage(message, entities) {
|
||||||
|
return interpolate(message, [entities.map(getName).join(", ")]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getName(result) {
|
||||||
|
return getEntity(result).name;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getEntity(result) {
|
||||||
|
return result.context;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
@ -0,0 +1,159 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* (c) Copyright 2016 Hewlett Packard Enterprise Development Company LP
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use self 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
angular
|
||||||
|
.module('designatedashboard.resources.os-designate-recordset.actions')
|
||||||
|
.factory('designatedashboard.resources.os-designate-recordset.actions.update', action);
|
||||||
|
|
||||||
|
action.$inject = [
|
||||||
|
'$q',
|
||||||
|
'designatedashboard.resources.util',
|
||||||
|
'designatedashboard.resources.os-designate-recordset.actions.common-forms',
|
||||||
|
'designatedashboard.resources.os-designate-recordset.api',
|
||||||
|
'designatedashboard.resources.os-designate-recordset.editableTypes',
|
||||||
|
'designatedashboard.resources.os-designate-recordset.resourceType',
|
||||||
|
'horizon.app.core.openstack-service-api.policy',
|
||||||
|
'horizon.app.core.openstack-service-api.serviceCatalog',
|
||||||
|
'horizon.framework.util.q.extensions',
|
||||||
|
'horizon.framework.widgets.form.ModalFormService',
|
||||||
|
'horizon.framework.widgets.toast.service',
|
||||||
|
'horizon.framework.widgets.modal-wait-spinner.service'
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngDoc factory
|
||||||
|
* @name designatedashboard.resources.os-designate-recordset.actions.update
|
||||||
|
*
|
||||||
|
* @Description
|
||||||
|
* Brings up the Update modal.
|
||||||
|
*/
|
||||||
|
function action($q,
|
||||||
|
util,
|
||||||
|
forms,
|
||||||
|
api,
|
||||||
|
editableTypes,
|
||||||
|
resourceTypeName,
|
||||||
|
policy,
|
||||||
|
serviceCatalog,
|
||||||
|
$qExtensions,
|
||||||
|
schemaFormModalService,
|
||||||
|
toast,
|
||||||
|
waitSpinner) {
|
||||||
|
var updateRecordSetPolicy, dnsServiceEnabled;
|
||||||
|
var title = gettext("Update Record Set");
|
||||||
|
var message = {
|
||||||
|
success: gettext('Record Set %s was successfully updated.')
|
||||||
|
};
|
||||||
|
|
||||||
|
var service = {
|
||||||
|
initScope: initScope,
|
||||||
|
allowed: allowed,
|
||||||
|
perform: perform
|
||||||
|
};
|
||||||
|
|
||||||
|
return service;
|
||||||
|
|
||||||
|
/////////////////
|
||||||
|
|
||||||
|
function initScope() {
|
||||||
|
updateRecordSetPolicy = policy.ifAllowed({rules: [['dns', 'update_recordset']]});
|
||||||
|
dnsServiceEnabled = serviceCatalog.ifTypeEnabled('dns');
|
||||||
|
}
|
||||||
|
|
||||||
|
function allowed(recordset) {
|
||||||
|
// only supports row action (exactly 1 recordset)
|
||||||
|
if (recordset) {
|
||||||
|
return $q.all([
|
||||||
|
updateRecordSetPolicy,
|
||||||
|
util.notDeleted(recordset),
|
||||||
|
util.notPending(recordset),
|
||||||
|
editableRecordType(recordset)
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function editableRecordType(recordset) {
|
||||||
|
return $qExtensions.booleanAsPromise(
|
||||||
|
editableTypes.indexOf(recordset.type) > -1
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function perform(item) {
|
||||||
|
var formConfig = forms.getUpdateFormConfig();
|
||||||
|
formConfig.title = title;
|
||||||
|
formConfig.model = util.getModel(formConfig.form, item);
|
||||||
|
|
||||||
|
// Append the id and zoneId so it can be used on submit
|
||||||
|
formConfig.model.id = item.id;
|
||||||
|
formConfig.model.zoneId = item.zone_id;
|
||||||
|
|
||||||
|
// schema form doesn't appear to support populating the records array directly
|
||||||
|
// Map the records objects to record objects
|
||||||
|
if (item.hasOwnProperty("records")) {
|
||||||
|
var records = item.records.map(function (item) {
|
||||||
|
return {"record": item}
|
||||||
|
});
|
||||||
|
formConfig.model.records = records;
|
||||||
|
}
|
||||||
|
return schemaFormModalService.open(formConfig).then(onSubmit, onCancel);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onSubmit(context) {
|
||||||
|
var model = angular.copy(context.model);
|
||||||
|
// schema form doesn't appear to support populating the records array directly
|
||||||
|
// Map the records objects to simple array of records
|
||||||
|
if (context.model.hasOwnProperty("records")) {
|
||||||
|
var records = context.model.records.map(function (item) {
|
||||||
|
return item.record;
|
||||||
|
});
|
||||||
|
model.records = records;
|
||||||
|
}
|
||||||
|
|
||||||
|
waitSpinner.showModalSpinner(gettext('Updating Record Set'));
|
||||||
|
|
||||||
|
return api.update(model.zoneId, model.id, model).then(onSuccess, onFailure);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onCancel() {
|
||||||
|
waitSpinner.hideModalSpinner();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onSuccess(response) {
|
||||||
|
waitSpinner.hideModalSpinner();
|
||||||
|
var recordset = response.data;
|
||||||
|
toast.add('success', interpolate(message.success, [recordset.name]));
|
||||||
|
|
||||||
|
// To make the result of this action generically useful, reformat the return
|
||||||
|
// from the deleteModal into a standard form
|
||||||
|
return {
|
||||||
|
created: [],
|
||||||
|
updated: [{type: resourceTypeName, id: recordset.id}],
|
||||||
|
deleted: [],
|
||||||
|
failed: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function onFailure() {
|
||||||
|
waitSpinner.hideModalSpinner();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
@ -0,0 +1,136 @@
|
|||||||
|
/**
|
||||||
|
* (c) Copyright 2016 Hewlett Packard Enterprise Development LP
|
||||||
|
*
|
||||||
|
* Licensed 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.
|
||||||
|
*/
|
||||||
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
angular
|
||||||
|
.module('designatedashboard.resources.os-designate-recordset')
|
||||||
|
.factory('designatedashboard.resources.os-designate-recordset.api', apiService);
|
||||||
|
|
||||||
|
apiService.$inject = [
|
||||||
|
'$q',
|
||||||
|
'designatedashboard.apiPassthroughUrl',
|
||||||
|
'horizon.framework.util.http.service',
|
||||||
|
'horizon.framework.widgets.toast.service'
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc service
|
||||||
|
* @param {Object} httpService
|
||||||
|
* @param {Object} toastService
|
||||||
|
* @name apiService
|
||||||
|
* @description Provides direct access to Designate Record Set APIs.
|
||||||
|
* @returns {Object} The service
|
||||||
|
*/
|
||||||
|
function apiService($q, apiPassthroughUrl, httpService, toastService) {
|
||||||
|
var service = {
|
||||||
|
get: get,
|
||||||
|
list: list,
|
||||||
|
deleteRecordSet: deleteRecordSet,
|
||||||
|
create: create,
|
||||||
|
update: update
|
||||||
|
};
|
||||||
|
|
||||||
|
return service;
|
||||||
|
|
||||||
|
///////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name list
|
||||||
|
* @description
|
||||||
|
* Get a list of record sets.
|
||||||
|
*
|
||||||
|
* The listing result is an object with property "items." Each item is
|
||||||
|
* a record set.
|
||||||
|
*
|
||||||
|
* @param {Object} params
|
||||||
|
* Query parameters. Optional.
|
||||||
|
*
|
||||||
|
* @returns {Object} The result of the API call
|
||||||
|
*/
|
||||||
|
function list(zoneId, params) {
|
||||||
|
return httpService.get(apiPassthroughUrl + 'v2/zones/' + zoneId + '/recordsets/', params)
|
||||||
|
.error(function () {
|
||||||
|
toastService.add('error', gettext('Unable to retrieve the record sets.'));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name get
|
||||||
|
* @description
|
||||||
|
* Get a single record set by ID.
|
||||||
|
*
|
||||||
|
* @param {string} zoneId
|
||||||
|
* Specifies the id of the zone containing the record set to request.
|
||||||
|
*
|
||||||
|
* @param {string} recordSetId
|
||||||
|
* Specifies the id of the record set to request.
|
||||||
|
*
|
||||||
|
* @returns {Object} The result of the API call
|
||||||
|
*/
|
||||||
|
function get(zoneId, recordSetId) {
|
||||||
|
// Unfortunately routed-details-view is not happy when load fails, which is
|
||||||
|
// 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 + '/')
|
||||||
|
.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
|
||||||
|
* @param {string} zoneId
|
||||||
|
* The id of the zone containing the recordset
|
||||||
|
*
|
||||||
|
* @param {string} recordSetId
|
||||||
|
* The id of the recordset within the zone
|
||||||
|
*
|
||||||
|
* @returns {*}
|
||||||
|
*/
|
||||||
|
function deleteRecordSet(zoneId, recordSetId) {
|
||||||
|
return httpService.delete(apiPassthroughUrl + 'v2/zones/' + zoneId + '/recordsets/' + recordSetId + '/')
|
||||||
|
.error(function () {
|
||||||
|
toastService.add('error', gettext('Unable to delete the record set.'));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function create(zoneId, data) {
|
||||||
|
return httpService.post(apiPassthroughUrl + 'v2/zones/' + zoneId + '/recordsets/', data)
|
||||||
|
.error(function () {
|
||||||
|
toastService.add('error', gettext('Unable to create the record set.'));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function update(zoneId, recordSetId, data) {
|
||||||
|
// The update API will not accept extra data. Restrict the input to only the allowed
|
||||||
|
// fields
|
||||||
|
var apiData = {
|
||||||
|
ttl: data.ttl,
|
||||||
|
description: data.description,
|
||||||
|
records: data.records
|
||||||
|
};
|
||||||
|
return httpService.put(apiPassthroughUrl + 'v2/zones/' + zoneId + '/recordsets/' + recordSetId, apiData)
|
||||||
|
.error(function () {
|
||||||
|
toastService.add('error', gettext('Unable to update the record set.'));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}());
|
@ -0,0 +1,109 @@
|
|||||||
|
/**
|
||||||
|
* (c) Copyright 2016 Hewlett Packard Enterprise Development LP
|
||||||
|
*
|
||||||
|
* Licensed 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc overview
|
||||||
|
* @ngname designatedashboard.resources.os-designate-recordset.details
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Provides details features for record sets.
|
||||||
|
*/
|
||||||
|
angular.module('designatedashboard.resources.os-designate-recordset.details',
|
||||||
|
['horizon.framework.conf', 'horizon.app.core'])
|
||||||
|
.run(run);
|
||||||
|
|
||||||
|
run.$inject = [
|
||||||
|
'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',
|
||||||
|
];
|
||||||
|
|
||||||
|
function run(
|
||||||
|
recordSetResourceType,
|
||||||
|
recordSetApi,
|
||||||
|
basePath,
|
||||||
|
registry
|
||||||
|
) {
|
||||||
|
var resourceType = registry.getResourceType(recordSetResourceType);
|
||||||
|
resourceType
|
||||||
|
.setLoadFunction(loadFunction)
|
||||||
|
.setPathGenerator(pathGenerator)
|
||||||
|
.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
|
||||||
|
*/
|
||||||
|
function loadFunction(identifier) {
|
||||||
|
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.
|
||||||
|
*
|
||||||
|
* @param item
|
||||||
|
* A record set
|
||||||
|
*
|
||||||
|
* @returns {string} In format "<zone_id>/<recordset_id>"
|
||||||
|
*/
|
||||||
|
function pathGenerator(item) {
|
||||||
|
return item.zone_id + '/' + item.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a path, extract the zone and record set ids
|
||||||
|
*
|
||||||
|
* @param path
|
||||||
|
* created by pathGenerator
|
||||||
|
*
|
||||||
|
* @returns {{zoneId: *, recordSetId: *}}
|
||||||
|
* The identifier to pass to the load function needed to uniquely identify
|
||||||
|
* a record set.
|
||||||
|
*/
|
||||||
|
function pathParser(path) {
|
||||||
|
var split = path.split('/');
|
||||||
|
return {
|
||||||
|
zoneId: split[0],
|
||||||
|
recordSetId: split[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resourceType.detailsViews
|
||||||
|
.prepend({
|
||||||
|
id: 'recordsetDetailsOverview',
|
||||||
|
name: gettext('Overview'),
|
||||||
|
template: basePath + 'details/overview.html',
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
// Append a record set view to the zones resource view
|
||||||
|
var zoneResourceType = registry.getResourceType("OS::Designate::Zone");
|
||||||
|
zoneResourceType.detailsViews
|
||||||
|
.append({
|
||||||
|
id: 'zoneRecordSets',
|
||||||
|
name: gettext('Record Sets'),
|
||||||
|
template: basePath + 'details/zone-recordsets.html',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
})();
|
@ -0,0 +1,10 @@
|
|||||||
|
<hz-resource-property-list
|
||||||
|
ng-if="item"
|
||||||
|
resource-type-name="OS::Designate::RecordSet"
|
||||||
|
item="item"
|
||||||
|
cls="dl-horizontal"
|
||||||
|
property-groups="[
|
||||||
|
['records', 'notes', 'description'],
|
||||||
|
['id']
|
||||||
|
]">
|
||||||
|
</hz-resource-property-list>
|
@ -0,0 +1,46 @@
|
|||||||
|
/**
|
||||||
|
* (c) Copyright 2016 Hewlett Packard Enterprise Development LP
|
||||||
|
*
|
||||||
|
* Licensed 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.
|
||||||
|
*/
|
||||||
|
(function() {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
angular
|
||||||
|
.module('designatedashboard.resources.os-designate-recordset')
|
||||||
|
.controller('designatedashboard.resources.os-designate-recordset.detailController', controller);
|
||||||
|
|
||||||
|
controller.$inject = [
|
||||||
|
'designatedashboard.resources.os-designate-recordset.resourceType',
|
||||||
|
'horizon.framework.conf.resource-type-registry.service',
|
||||||
|
'$scope'
|
||||||
|
];
|
||||||
|
|
||||||
|
function controller(
|
||||||
|
resourceTypeCode,
|
||||||
|
registry,
|
||||||
|
$scope
|
||||||
|
) {
|
||||||
|
var ctrl = this;
|
||||||
|
|
||||||
|
ctrl.item = {};
|
||||||
|
ctrl.resourceType = registry.getResourceType(resourceTypeCode);
|
||||||
|
|
||||||
|
$scope.context.loadPromise.then(onGetResponse);
|
||||||
|
|
||||||
|
function onGetResponse(response) {
|
||||||
|
ctrl.item = response.data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
})();
|
@ -0,0 +1,45 @@
|
|||||||
|
<div ng-controller="designatedashboard.resources.os-designate-recordset.detailController as ctrl">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6 detail">
|
||||||
|
<h3 translate>Details</h3>
|
||||||
|
<hr>
|
||||||
|
<hz-resource-property-list
|
||||||
|
ng-if="ctrl.item"
|
||||||
|
resource-type-name="OS::Designate::RecordSet"
|
||||||
|
item="ctrl.item"
|
||||||
|
cls="dl-horizontal"
|
||||||
|
property-groups="[
|
||||||
|
['id', 'type', 'name', 'records', 'notes', 'description', 'ttl', 'version', 'action', 'status']
|
||||||
|
]">
|
||||||
|
</hz-resource-property-list>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 detail">
|
||||||
|
<h3 translate>Associations</h3>
|
||||||
|
<hr>
|
||||||
|
<hz-resource-property-list
|
||||||
|
ng-if="ctrl.item"
|
||||||
|
resource-type-name="OS::Designate::RecordSet"
|
||||||
|
item="ctrl.item"
|
||||||
|
cls="dl-horizontal"
|
||||||
|
property-groups="[
|
||||||
|
['zone_id', 'zone_name', 'project_id']
|
||||||
|
]">
|
||||||
|
</hz-resource-property-list>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6 detail">
|
||||||
|
<h3 translate>Modification Times</h3>
|
||||||
|
<hr>
|
||||||
|
<hz-resource-property-list
|
||||||
|
ng-if="ctrl.item"
|
||||||
|
resource-type-name="OS::Designate::RecordSet"
|
||||||
|
item="ctrl.item"
|
||||||
|
cls="dl-horizontal"
|
||||||
|
property-groups="[
|
||||||
|
['created_at', 'updated_at']
|
||||||
|
]">
|
||||||
|
</hz-resource-property-list>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -0,0 +1,39 @@
|
|||||||
|
/**
|
||||||
|
* (c) Copyright 2016 Hewlett Packard Enterprise Development LP
|
||||||
|
*
|
||||||
|
* Licensed 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.
|
||||||
|
*/
|
||||||
|
(function() {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
angular
|
||||||
|
.module('designatedashboard.resources.os-designate-recordset')
|
||||||
|
.controller('designatedashboard.resources.os-designate-recordset.zoneRecordSetsController', controller);
|
||||||
|
|
||||||
|
controller.$inject = [
|
||||||
|
'$scope',
|
||||||
|
'designatedashboard.resources.os-designate-recordset.resourceType'
|
||||||
|
];
|
||||||
|
|
||||||
|
function controller(
|
||||||
|
$scope,
|
||||||
|
resourceTypeName
|
||||||
|
) {
|
||||||
|
var ctrl = this;
|
||||||
|
|
||||||
|
ctrl.item = {};
|
||||||
|
ctrl.resourceTypeName = resourceTypeName;
|
||||||
|
ctrl.extraListParams = { zoneId: $scope.context.identifier };
|
||||||
|
}
|
||||||
|
|
||||||
|
})();
|
@ -0,0 +1,8 @@
|
|||||||
|
<div
|
||||||
|
ng-controller="designatedashboard.resources.os-designate-recordset.zoneRecordSetsController as ctrl">
|
||||||
|
<hz-resource-table
|
||||||
|
resource-type-name="{$ ctrl.resourceTypeName $}"
|
||||||
|
list-function-extra-params="ctrl.extraListParams"
|
||||||
|
track-by="_timestampId">
|
||||||
|
</hz-resource-table>
|
||||||
|
</div>
|
@ -0,0 +1,238 @@
|
|||||||
|
/**
|
||||||
|
* (c) Copyright 2016 Hewlett Packard Enterprise Development LP
|
||||||
|
*
|
||||||
|
* Licensed 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc overview
|
||||||
|
* @ngname designatedashboard.resources.os-designate-recordset
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Provides all of the services and widgets required
|
||||||
|
* to support and display DNS (designate) record set related content.
|
||||||
|
*/
|
||||||
|
angular
|
||||||
|
.module('designatedashboard.resources.os-designate-recordset', [
|
||||||
|
'ngRoute',
|
||||||
|
'designatedashboard.resources.os-designate-recordset.actions',
|
||||||
|
'designatedashboard.resources.os-designate-recordset.details'
|
||||||
|
])
|
||||||
|
.constant(
|
||||||
|
'designatedashboard.resources.os-designate-recordset.resourceType',
|
||||||
|
'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('SPR - 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')
|
||||||
|
})
|
||||||
|
.constant(
|
||||||
|
'designatedashboard.resources.os-designate-recordset.editableTypes',
|
||||||
|
[
|
||||||
|
"A",
|
||||||
|
"AAAA",
|
||||||
|
"CNAME",
|
||||||
|
"MX",
|
||||||
|
"PTR",
|
||||||
|
"SPF",
|
||||||
|
"SRV",
|
||||||
|
"SSHFP",
|
||||||
|
"TXT"
|
||||||
|
])
|
||||||
|
.config(config)
|
||||||
|
.run(run);
|
||||||
|
|
||||||
|
config.$inject = ['$provide', '$windowProvider'];
|
||||||
|
|
||||||
|
function config($provide, $windowProvider) {
|
||||||
|
var path = $windowProvider.$get().STATIC_URL + 'designatedashboard/resources/os-designate-recordset/';
|
||||||
|
$provide.constant('designatedashboard.resources.os-designate-recordset.basePath', path);
|
||||||
|
}
|
||||||
|
|
||||||
|
run.$inject = [
|
||||||
|
'horizon.framework.conf.resource-type-registry.service',
|
||||||
|
'designatedashboard.resources.os-designate-recordset.api',
|
||||||
|
'designatedashboard.resources.os-designate-recordset.resourceType',
|
||||||
|
'designatedashboard.resources.os-designate-recordset.typeMap',
|
||||||
|
'designatedashboard.resources.util'
|
||||||
|
];
|
||||||
|
|
||||||
|
function run(registry,
|
||||||
|
recordSetApi,
|
||||||
|
resourceTypeString,
|
||||||
|
typeMap,
|
||||||
|
util) {
|
||||||
|
var resourceType = registry.getResourceType(resourceTypeString);
|
||||||
|
resourceType
|
||||||
|
.setNames(gettext('DNS Record Set'), gettext('DNS Record Sets'))
|
||||||
|
.setListFunction(list)
|
||||||
|
.setProperty('id', {
|
||||||
|
label: gettext('ID')
|
||||||
|
})
|
||||||
|
.setProperty('zone_id', {
|
||||||
|
label: gettext('Zone ID'),
|
||||||
|
filters: ['noValue']
|
||||||
|
})
|
||||||
|
.setProperty('zone_name', {
|
||||||
|
label: gettext('Zone Name'),
|
||||||
|
filters: ['noName']
|
||||||
|
})
|
||||||
|
.setProperty('project_id', {
|
||||||
|
label: gettext('Project ID'),
|
||||||
|
filters: ['noValue']
|
||||||
|
})
|
||||||
|
.setProperty('name', {
|
||||||
|
label: gettext('Name'),
|
||||||
|
filters: ['noName']
|
||||||
|
})
|
||||||
|
.setProperty('description', {
|
||||||
|
label: gettext('Description'),
|
||||||
|
filters: ['noName']
|
||||||
|
})
|
||||||
|
.setProperty('type', {
|
||||||
|
label: gettext('Type'),
|
||||||
|
filters: ['uppercase'],
|
||||||
|
values: typeMap
|
||||||
|
})
|
||||||
|
.setProperty('ttl', {
|
||||||
|
label: gettext('Time To Live'),
|
||||||
|
filters: ['noValue']
|
||||||
|
})
|
||||||
|
.setProperty('records', {
|
||||||
|
label: gettext('Records'),
|
||||||
|
filters: ['noValue']
|
||||||
|
})
|
||||||
|
.setProperty('notes', {
|
||||||
|
label: gettext('Notes'),
|
||||||
|
filters: ['noName']
|
||||||
|
})
|
||||||
|
.setProperty('status', {
|
||||||
|
label: gettext('Status'),
|
||||||
|
filters: ['lowercase', 'noName'],
|
||||||
|
values: util.statusMap()
|
||||||
|
})
|
||||||
|
.setProperty('action', {
|
||||||
|
label: gettext('Action'),
|
||||||
|
filters: ['lowercase', 'noName'],
|
||||||
|
values: util.actionMap()
|
||||||
|
})
|
||||||
|
.setProperty('version', {
|
||||||
|
label: gettext('Version'),
|
||||||
|
filters: ['noValue']
|
||||||
|
})
|
||||||
|
.setProperty('created_at', {
|
||||||
|
label: gettext('Created At'),
|
||||||
|
filters: ['noValue']
|
||||||
|
})
|
||||||
|
.setProperty('updated_at', {
|
||||||
|
label: gettext('Updated At'),
|
||||||
|
filters: ['noValue']
|
||||||
|
});
|
||||||
|
|
||||||
|
resourceType
|
||||||
|
.tableColumns
|
||||||
|
.append({
|
||||||
|
id: 'name',
|
||||||
|
priority: 1,
|
||||||
|
sortDefault: true,
|
||||||
|
filters: ['noName'],
|
||||||
|
// For link format, see pathGenerator in details.module.js
|
||||||
|
template: '<a ng-href="{$ \'project/ngdetails/OS::Designate::RecordSet/\' + item.zone_id + \'/\' + item.id $}">{$ item.name $}</a>'
|
||||||
|
})
|
||||||
|
.append({
|
||||||
|
id: 'type',
|
||||||
|
priority: 2,
|
||||||
|
filters: ['uppercase'],
|
||||||
|
values: typeMap
|
||||||
|
})
|
||||||
|
.append({
|
||||||
|
id: 'records',
|
||||||
|
priority: 2,
|
||||||
|
filters: ['noValue']
|
||||||
|
})
|
||||||
|
.append({
|
||||||
|
id: 'status',
|
||||||
|
filters: ['lowercase'],
|
||||||
|
values: util.statusMap(),
|
||||||
|
priority: 2
|
||||||
|
});
|
||||||
|
|
||||||
|
resourceType
|
||||||
|
.filterFacets
|
||||||
|
.append({
|
||||||
|
label: gettext('Type'),
|
||||||
|
name: 'type',
|
||||||
|
isServer: false,
|
||||||
|
singleton: true,
|
||||||
|
persistent: false,
|
||||||
|
options: Object.keys(typeMap).map(function toOptionLabel(key) {
|
||||||
|
return {
|
||||||
|
label: typeMap[key],
|
||||||
|
key: key
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.append({
|
||||||
|
label: gettext('Name'),
|
||||||
|
name: 'name',
|
||||||
|
isServer: false,
|
||||||
|
singleton: true,
|
||||||
|
persistent: false
|
||||||
|
})
|
||||||
|
.append({
|
||||||
|
label: gettext('Status'),
|
||||||
|
name: 'status',
|
||||||
|
isServer: false,
|
||||||
|
singleton: true,
|
||||||
|
persistent: false,
|
||||||
|
options: [
|
||||||
|
{label: gettext('Active'), key: 'active'},
|
||||||
|
{label: gettext('Pending'), key: 'pending'}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* list all recordsets within a zone. Requires "zoneId" in the params. All other
|
||||||
|
* params will be passed unmodified as URL params to the API.
|
||||||
|
*
|
||||||
|
* @param params
|
||||||
|
* zoneId (required) list recordsets within the zone
|
||||||
|
*
|
||||||
|
* @returns {*|Object}
|
||||||
|
*/
|
||||||
|
function list(params) {
|
||||||
|
return recordSetApi.list(params.zoneId, params).then(function onList(response) {
|
||||||
|
// listFunctions are expected to return data in "items"
|
||||||
|
response.data.items = response.data.recordsets;
|
||||||
|
|
||||||
|
util.addTimestampIds(response.data.items);
|
||||||
|
|
||||||
|
return response;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
})();
|
@ -0,0 +1,76 @@
|
|||||||
|
/**
|
||||||
|
* (c) Copyright 2016 Hewlett Packard Enterprise Development LP
|
||||||
|
*
|
||||||
|
* Licensed 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc overview
|
||||||
|
* @ngname designatedashboard.resources.os-designate-zone.actions
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Provides all of the actions for DNS Zones.
|
||||||
|
*/
|
||||||
|
angular.module('designatedashboard.resources.os-designate-zone.actions', [
|
||||||
|
'horizon.framework.conf',
|
||||||
|
'horizon.app.core'
|
||||||
|
])
|
||||||
|
.run(run);
|
||||||
|
|
||||||
|
run.$inject = [
|
||||||
|
'horizon.framework.conf.resource-type-registry.service',
|
||||||
|
'designatedashboard.resources.os-designate-zone.resourceType',
|
||||||
|
'designatedashboard.resources.os-designate-zone.actions.create',
|
||||||
|
'designatedashboard.resources.os-designate-zone.actions.delete',
|
||||||
|
'designatedashboard.resources.os-designate-zone.actions.update'
|
||||||
|
];
|
||||||
|
|
||||||
|
function run(registry,
|
||||||
|
resourceTypeString,
|
||||||
|
createAction,
|
||||||
|
deleteAction,
|
||||||
|
updateAction) {
|
||||||
|
var resourceType = registry.getResourceType(resourceTypeString);
|
||||||
|
resourceType
|
||||||
|
.globalActions
|
||||||
|
.append({
|
||||||
|
id: 'create',
|
||||||
|
service: createAction,
|
||||||
|
template: {
|
||||||
|
text: gettext('Create Zone')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
resourceType
|
||||||
|
.itemActions
|
||||||
|
.append({
|
||||||
|
id: 'update',
|
||||||
|
service: updateAction,
|
||||||
|
template: {
|
||||||
|
text: gettext('Update')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.append({
|
||||||
|
id: 'delete',
|
||||||
|
service: deleteAction,
|
||||||
|
template: {
|
||||||
|
text: gettext('Delete'),
|
||||||
|
type: 'delete'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
})();
|
@ -0,0 +1,184 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* (c) Copyright 2016 Hewlett Packard Enterprise Development Company LP
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use self 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
angular
|
||||||
|
.module('designatedashboard.resources.os-designate-zone.actions')
|
||||||
|
.factory('designatedashboard.resources.os-designate-zone.actions.common-forms', service);
|
||||||
|
|
||||||
|
service.$inject = [
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* @returns {object} A schema form config
|
||||||
|
*/
|
||||||
|
function service() {
|
||||||
|
var service = {
|
||||||
|
getCreateFormConfig: getCreateFormConfig,
|
||||||
|
getUpdateFormConfig: getUpdateFormConfig
|
||||||
|
};
|
||||||
|
|
||||||
|
return service;
|
||||||
|
|
||||||
|
/////////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the create zone form config
|
||||||
|
* @returns {{schema, form, model}|*}
|
||||||
|
*/
|
||||||
|
function getCreateFormConfig() {
|
||||||
|
return getCreateUpdateFormConfig(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the update zone form config
|
||||||
|
* @returns {{schema, form, model}|*}
|
||||||
|
*/
|
||||||
|
function getUpdateFormConfig() {
|
||||||
|
return getCreateUpdateFormConfig(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the create/update zone form. The two forms are identical except for
|
||||||
|
* during update, some fields are read-only.
|
||||||
|
*
|
||||||
|
* @param readonly - sets readonly value on form fields that change between update and create
|
||||||
|
* @returns {object} a schema form config, including default model
|
||||||
|
*/
|
||||||
|
function getCreateUpdateFormConfig(readonly) {
|
||||||
|
return {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": /^.+\.$/
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"email": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "email",
|
||||||
|
"pattern": /^[^@]+@[^@]+$/
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"PRIMARY",
|
||||||
|
"SECONDARY"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"ttl": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 1,
|
||||||
|
"maximum": 2147483647
|
||||||
|
},
|
||||||
|
"masters": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"address": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"minItems": 1,
|
||||||
|
"uniqueItems": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"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": "description",
|
||||||
|
"type": "textarea",
|
||||||
|
"title": gettext("Description"),
|
||||||
|
"description": gettext("Details about the zone.")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "email",
|
||||||
|
"title": gettext("Email Address"),
|
||||||
|
"placeholder": "owner@example.com",
|
||||||
|
"description": gettext("Email address to contact the zone owner."),
|
||||||
|
"validationMessage": gettext("Email address must contain a single '@' character"),
|
||||||
|
"type": "text",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "ttl",
|
||||||
|
"title": gettext("TTL"),
|
||||||
|
"description": gettext("Time To Live in seconds."),
|
||||||
|
"type": "number",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "type",
|
||||||
|
"readonly": readonly,
|
||||||
|
"title": gettext("Type"),
|
||||||
|
"description": gettext("Select the type of zone"),
|
||||||
|
"type": "select",
|
||||||
|
"titleMap": [
|
||||||
|
{
|
||||||
|
"value": "PRIMARY",
|
||||||
|
"name": gettext("Primary")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"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[].address",
|
||||||
|
"title": gettext("IP Address")
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"model": {
|
||||||
|
"type": "PRIMARY",
|
||||||
|
"ttl": 3600
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
@ -0,0 +1 @@
|
|||||||
|
<h1>CREATE TEMPLATE</h1>
|
@ -0,0 +1,126 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* (c) Copyright 2016 Hewlett Packard Enterprise Development Company LP
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use self 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
angular
|
||||||
|
.module('designatedashboard.resources.os-designate-zone.actions')
|
||||||
|
.factory('designatedashboard.resources.os-designate-zone.actions.create', action);
|
||||||
|
|
||||||
|
action.$inject = [
|
||||||
|
'$q',
|
||||||
|
'designatedashboard.resources.os-designate-zone.actions.common-forms',
|
||||||
|
'designatedashboard.resources.os-designate-zone.api',
|
||||||
|
'designatedashboard.resources.os-designate-zone.resourceType',
|
||||||
|
'horizon.app.core.openstack-service-api.policy',
|
||||||
|
'horizon.app.core.openstack-service-api.serviceCatalog',
|
||||||
|
'horizon.framework.widgets.form.ModalFormService',
|
||||||
|
'horizon.framework.widgets.toast.service',
|
||||||
|
'horizon.framework.widgets.modal-wait-spinner.service'
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngDoc factory
|
||||||
|
* @name designatedashboard.resources.os-designate-zone.actions.create
|
||||||
|
*
|
||||||
|
* @Description
|
||||||
|
* Brings up the Create Zone modal.
|
||||||
|
*/
|
||||||
|
function action($q,
|
||||||
|
forms,
|
||||||
|
api,
|
||||||
|
resourceTypeName,
|
||||||
|
policy,
|
||||||
|
serviceCatalog,
|
||||||
|
schemaFormModalService,
|
||||||
|
toast,
|
||||||
|
waitSpinner) {
|
||||||
|
var createZonePolicy, dnsServiceEnabled;
|
||||||
|
var title = gettext("Create Zone");
|
||||||
|
var message = {
|
||||||
|
success: gettext('Zone %s was successfully created.')
|
||||||
|
};
|
||||||
|
|
||||||
|
var service = {
|
||||||
|
initScope: initScope,
|
||||||
|
allowed: allowed,
|
||||||
|
perform: perform
|
||||||
|
};
|
||||||
|
|
||||||
|
return service;
|
||||||
|
|
||||||
|
/////////////////
|
||||||
|
|
||||||
|
function initScope() {
|
||||||
|
createZonePolicy = policy.ifAllowed({rules: [['dns', 'create_zone']]});
|
||||||
|
dnsServiceEnabled = serviceCatalog.ifTypeEnabled('dns');
|
||||||
|
}
|
||||||
|
|
||||||
|
function allowed() {
|
||||||
|
return $q.all([
|
||||||
|
createZonePolicy,
|
||||||
|
dnsServiceEnabled
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function perform() {
|
||||||
|
var formConfig = forms.getCreateFormConfig();
|
||||||
|
formConfig.title = title;
|
||||||
|
return schemaFormModalService.open(formConfig).then(onSubmit, onCancel);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onSubmit(context) {
|
||||||
|
var zoneModel = angular.copy(context.model);
|
||||||
|
// schema form doesn't appear to support populating the masters array directly
|
||||||
|
// Map the masters objects to simple array of addresses
|
||||||
|
if (context.model.hasOwnProperty("masters")) {
|
||||||
|
var masters = context.model.masters.map(function (item) {
|
||||||
|
return item.address;
|
||||||
|
});
|
||||||
|
zoneModel.masters = masters;
|
||||||
|
}
|
||||||
|
|
||||||
|
waitSpinner.showModalSpinner(gettext('Creating Zone'));
|
||||||
|
|
||||||
|
return api.create(zoneModel).then(onSuccess, onFailure);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onCancel() {
|
||||||
|
waitSpinner.hideModalSpinner();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onSuccess(response) {
|
||||||
|
waitSpinner.hideModalSpinner();
|
||||||
|
var zone = response.data;
|
||||||
|
toast.add('success', interpolate(message.success, [zone.name]));
|
||||||
|
|
||||||
|
// To make the result of this action generically useful, reformat the return
|
||||||
|
// from the deleteModal into a standard form
|
||||||
|
return {
|
||||||
|
created: [{type: resourceTypeName, id: zone.id}],
|
||||||
|
updated: [],
|
||||||
|
deleted: [],
|
||||||
|
failed: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function onFailure() {
|
||||||
|
waitSpinner.hideModalSpinner();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
@ -0,0 +1,169 @@
|
|||||||
|
/**
|
||||||
|
* (c) Copyright 2016 Hewlett Packard Enterprise Development LP
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use self 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
angular
|
||||||
|
.module('designatedashboard.resources.os-designate-zone.actions')
|
||||||
|
.factory('designatedashboard.resources.os-designate-zone.actions.delete', action);
|
||||||
|
|
||||||
|
action.$inject = [
|
||||||
|
'$q',
|
||||||
|
'designatedashboard.resources.os-designate-zone.api',
|
||||||
|
'designatedashboard.resources.util',
|
||||||
|
'horizon.app.core.openstack-service-api.policy',
|
||||||
|
'horizon.framework.util.actions.action-result.service',
|
||||||
|
'horizon.framework.util.i18n.gettext',
|
||||||
|
'horizon.framework.util.q.extensions',
|
||||||
|
'horizon.framework.widgets.modal.deleteModalService',
|
||||||
|
'horizon.framework.widgets.toast.service',
|
||||||
|
'designatedashboard.resources.os-designate-zone.resourceType'
|
||||||
|
];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @ngdoc factory
|
||||||
|
* @name designatedashboard.resources.os-designate-zone.actions.delete
|
||||||
|
*
|
||||||
|
* @Description
|
||||||
|
* Brings up the delete zone confirmation modal dialog.
|
||||||
|
|
||||||
|
* On submit, delete given zone.
|
||||||
|
* On cancel, do nothing.
|
||||||
|
*/
|
||||||
|
function action(
|
||||||
|
$q,
|
||||||
|
zoneApi,
|
||||||
|
util,
|
||||||
|
policy,
|
||||||
|
actionResultService,
|
||||||
|
gettext,
|
||||||
|
$qExtensions,
|
||||||
|
deleteModal,
|
||||||
|
toast,
|
||||||
|
resourceType
|
||||||
|
) {
|
||||||
|
var scope, context, deleteZonePromise;
|
||||||
|
var notAllowedMessage = gettext("You are not allowed to delete zones: %s");
|
||||||
|
|
||||||
|
var service = {
|
||||||
|
initScope: initScope,
|
||||||
|
allowed: allowed,
|
||||||
|
perform: perform
|
||||||
|
};
|
||||||
|
|
||||||
|
return service;
|
||||||
|
|
||||||
|
//////////////
|
||||||
|
|
||||||
|
function initScope(newScope) {
|
||||||
|
scope = newScope;
|
||||||
|
context = { };
|
||||||
|
deleteZonePromise = policy.ifAllowed({rules: [['dns', 'delete_zone']]});
|
||||||
|
}
|
||||||
|
|
||||||
|
function perform(items) {
|
||||||
|
var zones = angular.isArray(items) ? items : [items];
|
||||||
|
context.labels = labelize(zones.length);
|
||||||
|
context.deleteEntity = deleteZone;
|
||||||
|
return $qExtensions.allSettled(zones.map(checkPermission)).then(afterCheck);
|
||||||
|
}
|
||||||
|
|
||||||
|
function allowed(zone) {
|
||||||
|
// only row actions pass in zone
|
||||||
|
// otherwise, assume it is a batch action
|
||||||
|
if (zone) {
|
||||||
|
return $q.all([
|
||||||
|
deleteZonePromise,
|
||||||
|
util.notDeleted(zone),
|
||||||
|
util.notPending(zone)
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
return policy.ifAllowed({ rules: [['dns', 'delete_zone']] });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkPermission(zone) {
|
||||||
|
return {promise: allowed(zone), context: zone};
|
||||||
|
}
|
||||||
|
|
||||||
|
function afterCheck(result) {
|
||||||
|
var outcome = $q.reject(); // Reject the promise by default
|
||||||
|
if (result.fail.length > 0) {
|
||||||
|
toast.add('error', getMessage(notAllowedMessage, result.fail));
|
||||||
|
outcome = $q.reject(result.fail);
|
||||||
|
}
|
||||||
|
if (result.pass.length > 0) {
|
||||||
|
outcome = deleteModal.open(scope, result.pass.map(getEntity), context).then(createResult);
|
||||||
|
}
|
||||||
|
return outcome;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createResult(deleteModalResult) {
|
||||||
|
// To make the result of this action generically useful, reformat the return
|
||||||
|
// from the deleteModal into a standard form
|
||||||
|
var actionResult = actionResultService.getActionResult();
|
||||||
|
deleteModalResult.pass.forEach(function markDeleted(item) {
|
||||||
|
actionResult.deleted(resourceType, getEntity(item).id);
|
||||||
|
});
|
||||||
|
deleteModalResult.fail.forEach(function markFailed(item) {
|
||||||
|
actionResult.failed(resourceType, getEntity(item).id);
|
||||||
|
});
|
||||||
|
return actionResult.result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function labelize(count) {
|
||||||
|
return {
|
||||||
|
|
||||||
|
title: ngettext(
|
||||||
|
'Confirm Delete Zone',
|
||||||
|
'Confirm Delete Zones', count),
|
||||||
|
|
||||||
|
message: ngettext(
|
||||||
|
'You have selected "%s". Deleted zone is not recoverable.',
|
||||||
|
'You have selected "%s". Deleted zones are not recoverable.', count),
|
||||||
|
|
||||||
|
submit: ngettext(
|
||||||
|
'Delete Zone',
|
||||||
|
'Delete Zones', count),
|
||||||
|
|
||||||
|
success: ngettext(
|
||||||
|
'Deleted Zone: %s.',
|
||||||
|
'Deleted Zones: %s.', count),
|
||||||
|
|
||||||
|
error: ngettext(
|
||||||
|
'Unable to delete Zone: %s.',
|
||||||
|
'Unable to delete Zones: %s.', count)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteZone(zone) {
|
||||||
|
return zoneApi.deleteZone(zone, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMessage(message, entities) {
|
||||||
|
return interpolate(message, [entities.map(getName).join(", ")]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getName(result) {
|
||||||
|
return getEntity(result).name;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getEntity(result) {
|
||||||
|
return result.context;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
@ -0,0 +1,147 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* (c) Copyright 2016 Hewlett Packard Enterprise Development Company LP
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use self 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
angular
|
||||||
|
.module('designatedashboard.resources.os-designate-zone.actions')
|
||||||
|
.factory('designatedashboard.resources.os-designate-zone.actions.update', action);
|
||||||
|
|
||||||
|
action.$inject = [
|
||||||
|
'$q',
|
||||||
|
'designatedashboard.resources.os-designate-zone.actions.common-forms',
|
||||||
|
'designatedashboard.resources.os-designate-zone.api',
|
||||||
|
'designatedashboard.resources.os-designate-zone.resourceType',
|
||||||
|
'designatedashboard.resources.util',
|
||||||
|
'horizon.app.core.openstack-service-api.policy',
|
||||||
|
'horizon.app.core.openstack-service-api.serviceCatalog',
|
||||||
|
'horizon.framework.widgets.form.ModalFormService',
|
||||||
|
'horizon.framework.widgets.toast.service',
|
||||||
|
'horizon.framework.widgets.modal-wait-spinner.service'
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngDoc factory
|
||||||
|
* @name designatedashboard.resources.os-designate-zone.actions.update
|
||||||
|
*
|
||||||
|
* @Description
|
||||||
|
* Brings up the Update Zone modal.
|
||||||
|
*/
|
||||||
|
function action($q,
|
||||||
|
forms,
|
||||||
|
api,
|
||||||
|
resourceTypeName,
|
||||||
|
util,
|
||||||
|
policy,
|
||||||
|
serviceCatalog,
|
||||||
|
schemaFormModalService,
|
||||||
|
toast,
|
||||||
|
waitSpinner) {
|
||||||
|
var updateZonePolicy, dnsServiceEnabled;
|
||||||
|
var title = gettext("Update Zone");
|
||||||
|
var message = {
|
||||||
|
success: gettext('Zone %s was successfully updated.')
|
||||||
|
};
|
||||||
|
|
||||||
|
var service = {
|
||||||
|
initScope: initScope,
|
||||||
|
allowed: allowed,
|
||||||
|
perform: perform
|
||||||
|
};
|
||||||
|
|
||||||
|
return service;
|
||||||
|
|
||||||
|
/////////////////
|
||||||
|
|
||||||
|
function initScope() {
|
||||||
|
updateZonePolicy = policy.ifAllowed({rules: [['dns', 'update_zone']]});
|
||||||
|
dnsServiceEnabled = serviceCatalog.ifTypeEnabled('dns');
|
||||||
|
}
|
||||||
|
|
||||||
|
function allowed(zone) {
|
||||||
|
// only supports row action (exactly 1 zone)
|
||||||
|
if (zone) {
|
||||||
|
return $q.all([
|
||||||
|
updateZonePolicy,
|
||||||
|
util.notDeleted(zone),
|
||||||
|
util.notPending(zone)
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function perform(item) {
|
||||||
|
var formConfig = forms.getUpdateFormConfig();
|
||||||
|
formConfig.title = title;
|
||||||
|
formConfig.model = util.getModel(formConfig.form, item);
|
||||||
|
|
||||||
|
// Append the id so it can be used on submit
|
||||||
|
formConfig.model.id = item.id;
|
||||||
|
|
||||||
|
// schema form doesn't appear to support populating the masters array directly
|
||||||
|
// Map the masters objects to address objects
|
||||||
|
if (item.hasOwnProperty("masters")) {
|
||||||
|
var masters = item.masters.map(function (item) {
|
||||||
|
return { "address": item }
|
||||||
|
})
|
||||||
|
formConfig.masters = masters;
|
||||||
|
}
|
||||||
|
return schemaFormModalService.open(formConfig).then(onSubmit, onCancel);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onSubmit(context) {
|
||||||
|
var zoneModel = angular.copy(context.model);
|
||||||
|
// schema form doesn't appear to support populating the masters array directly
|
||||||
|
// Map the masters objects to simple array of addresses
|
||||||
|
if (context.model.hasOwnProperty("masters")) {
|
||||||
|
var masters = context.model.masters.map(function (item) {
|
||||||
|
return item.address;
|
||||||
|
})
|
||||||
|
zoneModel.masters = masters;
|
||||||
|
}
|
||||||
|
|
||||||
|
waitSpinner.showModalSpinner(gettext('Updating Zone'));
|
||||||
|
|
||||||
|
return api.update(zoneModel.id, zoneModel).then(onSuccess, onFailure);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onCancel() {
|
||||||
|
waitSpinner.hideModalSpinner();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onSuccess(response) {
|
||||||
|
waitSpinner.hideModalSpinner();
|
||||||
|
var zone = response.data;
|
||||||
|
toast.add('success', interpolate(message.success, [zone.name]));
|
||||||
|
|
||||||
|
// To make the result of this action generically useful, reformat the return
|
||||||
|
// from the deleteModal into a standard form
|
||||||
|
return {
|
||||||
|
created: [],
|
||||||
|
updated: [{type: resourceTypeName, id: zone.id}],
|
||||||
|
deleted: [],
|
||||||
|
failed: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function onFailure() {
|
||||||
|
waitSpinner.hideModalSpinner();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
@ -0,0 +1,152 @@
|
|||||||
|
/**
|
||||||
|
* (c) Copyright 2016 Hewlett Packard Enterprise Development LP
|
||||||
|
*
|
||||||
|
* Licensed 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.
|
||||||
|
*/
|
||||||
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
angular
|
||||||
|
.module('designatedashboard.resources.os-designate-zone')
|
||||||
|
.factory('designatedashboard.resources.os-designate-zone.api', apiService);
|
||||||
|
|
||||||
|
apiService.$inject = [
|
||||||
|
'designatedashboard.apiPassthroughUrl',
|
||||||
|
'horizon.framework.util.http.service',
|
||||||
|
'horizon.framework.widgets.toast.service'
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc service
|
||||||
|
* @param {Object} httpService
|
||||||
|
* @param {Object} toastService
|
||||||
|
* @name apiService
|
||||||
|
* @description Provides direct access to Designate Zone APIs.
|
||||||
|
* @returns {Object} The service
|
||||||
|
*/
|
||||||
|
function apiService(apiPassthroughUrl, httpService, toastService) {
|
||||||
|
var service = {
|
||||||
|
get: get,
|
||||||
|
list: list,
|
||||||
|
deleteZone: deleteZone,
|
||||||
|
create: create,
|
||||||
|
update: update
|
||||||
|
};
|
||||||
|
|
||||||
|
return service;
|
||||||
|
|
||||||
|
///////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name list
|
||||||
|
* @description
|
||||||
|
* Get a list of zones.
|
||||||
|
*
|
||||||
|
* The listing result is an object with property "items." Each item is
|
||||||
|
* a zone.
|
||||||
|
*
|
||||||
|
* @param {Object} params
|
||||||
|
* Query parameters. Optional.
|
||||||
|
*
|
||||||
|
* @returns {Object} The result of the API call
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
function list(params) {
|
||||||
|
var config = params ? {'params': params} : {};
|
||||||
|
return httpService.get('/api/designate/zones/', config)
|
||||||
|
.error(function () {
|
||||||
|
toastService.add('error', gettext('Unable to retrieve the zone.'));
|
||||||
|
});
|
||||||
|
}*/
|
||||||
|
function list(params) {
|
||||||
|
var config = params ? {'params': params} : {};
|
||||||
|
return httpService.get(apiPassthroughUrl + 'v2/zones/', config)
|
||||||
|
.error(function () {
|
||||||
|
toastService.add('error', gettext('Unable to retrieve the zone.'));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name get
|
||||||
|
* @description
|
||||||
|
* Get a single zone by ID.
|
||||||
|
*
|
||||||
|
* @param {string} id
|
||||||
|
* Specifies the id of the zone to request.
|
||||||
|
*
|
||||||
|
* @returns {Object} The result of the API call
|
||||||
|
*/
|
||||||
|
function get(id) {
|
||||||
|
return httpService.get(apiPassthroughUrl + 'v2/zones/' + id + '/')
|
||||||
|
.error(function () {
|
||||||
|
toastService.add('error', gettext('Unable to retrieve the zone.'));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name deleteZone
|
||||||
|
* @description
|
||||||
|
* Delete a single zone by ID
|
||||||
|
* @param id
|
||||||
|
* @returns {*}
|
||||||
|
*/
|
||||||
|
function deleteZone(id) {
|
||||||
|
return httpService.delete(apiPassthroughUrl + 'v2/zones/' + id + '/')
|
||||||
|
.error(function () {
|
||||||
|
toastService.add('error', gettext('Unable to delete the zone.'));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name create
|
||||||
|
* @description
|
||||||
|
* Create a zone
|
||||||
|
*
|
||||||
|
* @param {Object} data
|
||||||
|
* Specifies the zone information to create
|
||||||
|
*
|
||||||
|
* @returns {Object} The created zone object
|
||||||
|
*/
|
||||||
|
function create(data) {
|
||||||
|
return httpService.post(apiPassthroughUrl + 'v2/zones/', data)
|
||||||
|
.error(function() {
|
||||||
|
toastService.add('error', gettext('Unable to create the zone.'));
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name create
|
||||||
|
* @description
|
||||||
|
* Update a zone
|
||||||
|
*
|
||||||
|
* @param {Object} id - zone id
|
||||||
|
* @param {Object} data to pass directly to zone update API
|
||||||
|
* Specifies the zone information to update
|
||||||
|
*
|
||||||
|
* @returns {Object} The updated zone object
|
||||||
|
*/
|
||||||
|
function update(id, data) {
|
||||||
|
// The update API will not accept extra data. Restrict the input to only the allowed
|
||||||
|
// fields
|
||||||
|
var apiData = {
|
||||||
|
email: data.email,
|
||||||
|
ttl: data.ttl,
|
||||||
|
description: data.description
|
||||||
|
};
|
||||||
|
return httpService.patch(apiPassthroughUrl + 'v2/zones/' + id + '/', apiData )
|
||||||
|
.error(function() {
|
||||||
|
toastService.add('error', gettext('Unable to update the zone.'));
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}());
|
@ -0,0 +1,61 @@
|
|||||||
|
/**
|
||||||
|
* (c) Copyright 2016 Hewlett Packard Enterprise Development LP
|
||||||
|
*
|
||||||
|
* Licensed 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc overview
|
||||||
|
* @ngname designatedashboard.resources.os-designate-zone.details
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Provides details features for zones.
|
||||||
|
*/
|
||||||
|
angular.module('designatedashboard.resources.os-designate-zone.details',
|
||||||
|
['horizon.framework.conf', 'horizon.app.core'])
|
||||||
|
.run(run);
|
||||||
|
|
||||||
|
run.$inject = [
|
||||||
|
'designatedashboard.resources.os-designate-zone.resourceType',
|
||||||
|
'designatedashboard.resources.os-designate-zone.api',
|
||||||
|
'designatedashboard.resources.os-designate-zone.basePath',
|
||||||
|
'horizon.framework.conf.resource-type-registry.service'
|
||||||
|
];
|
||||||
|
|
||||||
|
function run(
|
||||||
|
zoneResourceType,
|
||||||
|
zoneApi,
|
||||||
|
basePath,
|
||||||
|
registry
|
||||||
|
) {
|
||||||
|
var resourceType = registry.getResourceType(zoneResourceType);
|
||||||
|
resourceType
|
||||||
|
.setLoadFunction(loadFunction)
|
||||||
|
.setSummaryTemplateUrl(basePath + 'details/drawer.html');
|
||||||
|
|
||||||
|
resourceType.detailsViews
|
||||||
|
.prepend({
|
||||||
|
id: 'zoneDetailsOverview',
|
||||||
|
name: gettext('Overview'),
|
||||||
|
template: basePath + 'details/overview.html',
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
function loadFunction(identifier) {
|
||||||
|
return zoneApi.get(identifier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
})();
|
@ -0,0 +1,10 @@
|
|||||||
|
<hz-resource-property-list
|
||||||
|
ng-if="item"
|
||||||
|
resource-type-name="OS::Designate::Zone"
|
||||||
|
item="item"
|
||||||
|
cls="dl-horizontal"
|
||||||
|
property-groups="[
|
||||||
|
['description', 'email'],
|
||||||
|
['id', 'pool_id', 'project_id']
|
||||||
|
]">
|
||||||
|
</hz-resource-property-list>
|
@ -0,0 +1,46 @@
|
|||||||
|
/**
|
||||||
|
* (c) Copyright 2016 Hewlett Packard Enterprise Development LP
|
||||||
|
*
|
||||||
|
* Licensed 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.
|
||||||
|
*/
|
||||||
|
(function() {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
angular
|
||||||
|
.module('designatedashboard.resources.os-designate-zone')
|
||||||
|
.controller('designatedashboard.resources.os-designate-zone.detailController', controller);
|
||||||
|
|
||||||
|
controller.$inject = [
|
||||||
|
'designatedashboard.resources.os-designate-zone.resourceType',
|
||||||
|
'horizon.framework.conf.resource-type-registry.service',
|
||||||
|
'$scope'
|
||||||
|
];
|
||||||
|
|
||||||
|
function controller(
|
||||||
|
resourceTypeCode,
|
||||||
|
registry,
|
||||||
|
$scope
|
||||||
|
) {
|
||||||
|
var ctrl = this;
|
||||||
|
|
||||||
|
ctrl.item;
|
||||||
|
ctrl.resourceType = registry.getResourceType(resourceTypeCode);
|
||||||
|
|
||||||
|
$scope.context.loadPromise.then(onGetResponse);
|
||||||
|
|
||||||
|
function onGetResponse(response) {
|
||||||
|
ctrl.item = response.data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
})();
|
@ -0,0 +1,58 @@
|
|||||||
|
<div ng-controller="designatedashboard.resources.os-designate-zone.detailController as ctrl">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6 detail">
|
||||||
|
<h3 translate>Details</h3>
|
||||||
|
<hr>
|
||||||
|
<hz-resource-property-list
|
||||||
|
ng-if="ctrl.item"
|
||||||
|
resource-type-name="OS::Designate::Zone"
|
||||||
|
item="ctrl.item"
|
||||||
|
cls="dl-horizontal"
|
||||||
|
property-groups="[
|
||||||
|
['id', 'description', 'type', 'status', 'action', 'email', 'serial', 'ttl', 'version']
|
||||||
|
]">
|
||||||
|
</hz-resource-property-list>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 detail">
|
||||||
|
<h3 translate>Attributes</h3>
|
||||||
|
<hr>
|
||||||
|
<hz-resource-property-list
|
||||||
|
ng-if="ctrl.item"
|
||||||
|
resource-type-name="OS::Designate::Zone"
|
||||||
|
item="ctrl.item"
|
||||||
|
cls="dl-horizontal"
|
||||||
|
property-groups="[
|
||||||
|
['attributes']
|
||||||
|
]">
|
||||||
|
</hz-resource-property-list>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6 detail">
|
||||||
|
<h3 translate>Modification Times</h3>
|
||||||
|
<hr>
|
||||||
|
<hz-resource-property-list
|
||||||
|
ng-if="ctrl.item"
|
||||||
|
resource-type-name="OS::Designate::Zone"
|
||||||
|
item="ctrl.item"
|
||||||
|
cls="dl-horizontal"
|
||||||
|
property-groups="[
|
||||||
|
['created_at', 'updated_at', 'transferred_at']
|
||||||
|
]">
|
||||||
|
</hz-resource-property-list>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 detail">
|
||||||
|
<h3 translate>Associations</h3>
|
||||||
|
<hr>
|
||||||
|
<hz-resource-property-list
|
||||||
|
ng-if="ctrl.item"
|
||||||
|
resource-type-name="OS::Designate::Zone"
|
||||||
|
item="ctrl.item"
|
||||||
|
cls="dl-horizontal"
|
||||||
|
property-groups="[
|
||||||
|
['pool_id', 'project_id', 'masters']
|
||||||
|
]">
|
||||||
|
</hz-resource-property-list>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -0,0 +1,202 @@
|
|||||||
|
/**
|
||||||
|
* (c) Copyright 2016 Hewlett Packard Enterprise Development LP
|
||||||
|
*
|
||||||
|
* Licensed 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc overview
|
||||||
|
* @ngname designatedashboard.resources.os-designate-zone
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Provides all of the services and widgets required
|
||||||
|
* to support and display DNS (designate) zone related content.
|
||||||
|
*/
|
||||||
|
angular
|
||||||
|
.module('designatedashboard.resources.os-designate-zone', [
|
||||||
|
'ngRoute',
|
||||||
|
'designatedashboard.resources.os-designate-zone.actions',
|
||||||
|
'designatedashboard.resources.os-designate-zone.details'
|
||||||
|
])
|
||||||
|
.constant(
|
||||||
|
'designatedashboard.resources.os-designate-zone.resourceType',
|
||||||
|
'OS::Designate::Zone')
|
||||||
|
.config(config)
|
||||||
|
.run(run);
|
||||||
|
|
||||||
|
config.$inject = ['$provide', '$windowProvider'];
|
||||||
|
|
||||||
|
function config($provide, $windowProvider) {
|
||||||
|
var path = $windowProvider.$get().STATIC_URL + 'designatedashboard/resources/os-designate-zone/';
|
||||||
|
$provide.constant('designatedashboard.resources.os-designate-zone.basePath', path);
|
||||||
|
}
|
||||||
|
|
||||||
|
run.$inject = [
|
||||||
|
'horizon.framework.conf.resource-type-registry.service',
|
||||||
|
'designatedashboard.resources.os-designate-zone.api',
|
||||||
|
'designatedashboard.resources.os-designate-zone.resourceType',
|
||||||
|
'designatedashboard.resources.util'
|
||||||
|
];
|
||||||
|
|
||||||
|
function run(registry,
|
||||||
|
zoneApi,
|
||||||
|
resourceTypeString,
|
||||||
|
util) {
|
||||||
|
var resourceType = registry.getResourceType(resourceTypeString);
|
||||||
|
resourceType
|
||||||
|
.setNames(gettext('DNS Zone'), gettext('DNS Zones'))
|
||||||
|
.setListFunction(listZones)
|
||||||
|
.setProperty('action', {
|
||||||
|
label: gettext('Action'),
|
||||||
|
filters: ['lowercase', 'noName'],
|
||||||
|
values: util.actionMap()
|
||||||
|
})
|
||||||
|
.setProperty('attributes', {
|
||||||
|
label: gettext('Attributes')
|
||||||
|
})
|
||||||
|
.setProperty('created_at', {
|
||||||
|
label: gettext('Created At'),
|
||||||
|
filters: ['noValue']
|
||||||
|
})
|
||||||
|
.setProperty('description', {
|
||||||
|
label: gettext('Description'),
|
||||||
|
filters: ['noName']
|
||||||
|
})
|
||||||
|
.setProperty('email', {
|
||||||
|
label: gettext('Email'),
|
||||||
|
filters: ['noName']
|
||||||
|
})
|
||||||
|
.setProperty('id', {
|
||||||
|
label: gettext('ID')
|
||||||
|
})
|
||||||
|
.setProperty('masters', {
|
||||||
|
label: gettext('Masters'),
|
||||||
|
filters: ['noValue']
|
||||||
|
})
|
||||||
|
.setProperty('name', {
|
||||||
|
label: gettext('Name'),
|
||||||
|
filters: ['noName']
|
||||||
|
})
|
||||||
|
.setProperty('pool_id', {
|
||||||
|
label: gettext('Pool ID')
|
||||||
|
})
|
||||||
|
.setProperty('project_id', {
|
||||||
|
label: gettext('Project ID')
|
||||||
|
})
|
||||||
|
.setProperty('serial', {
|
||||||
|
label: gettext('Serial'),
|
||||||
|
filters: ['noValue']
|
||||||
|
})
|
||||||
|
.setProperty('status', {
|
||||||
|
label: gettext('Status'),
|
||||||
|
filters: ['lowercase', 'noName'],
|
||||||
|
values: util.statusMap()
|
||||||
|
})
|
||||||
|
.setProperty('transferred_at', {
|
||||||
|
label: gettext('Transferred At'),
|
||||||
|
filters: ['noValue']
|
||||||
|
})
|
||||||
|
.setProperty('ttl', {
|
||||||
|
label: gettext('Time To Live'),
|
||||||
|
filters: ['noValue']
|
||||||
|
})
|
||||||
|
.setProperty('type', {
|
||||||
|
label: gettext('Type'),
|
||||||
|
filters: ['lowercase', 'noName'],
|
||||||
|
values: typeMap()
|
||||||
|
})
|
||||||
|
.setProperty('updated_at', {
|
||||||
|
label: gettext('Updated At'),
|
||||||
|
filters: ['noValue']
|
||||||
|
})
|
||||||
|
.setProperty('version', {
|
||||||
|
label: gettext('Version'),
|
||||||
|
filters: ['noValue']
|
||||||
|
});
|
||||||
|
|
||||||
|
resourceType
|
||||||
|
.tableColumns
|
||||||
|
.append({
|
||||||
|
id: 'name',
|
||||||
|
priority: 1,
|
||||||
|
sortDefault: true,
|
||||||
|
template: '<a ng-href="{$ \'project/ngdetails/OS::Designate::Zone/\' + item.id $}">{$ item.name $}</a>'
|
||||||
|
})
|
||||||
|
.append({
|
||||||
|
id: 'type',
|
||||||
|
filters: ['lowercase'],
|
||||||
|
values: typeMap(),
|
||||||
|
priority: 2
|
||||||
|
})
|
||||||
|
.append({
|
||||||
|
id: 'status',
|
||||||
|
filters: ['lowercase'],
|
||||||
|
values: util.statusMap(),
|
||||||
|
priority: 2
|
||||||
|
});
|
||||||
|
|
||||||
|
resourceType
|
||||||
|
.filterFacets
|
||||||
|
.append({
|
||||||
|
label: gettext('Name'),
|
||||||
|
name: 'name',
|
||||||
|
isServer: false,
|
||||||
|
singleton: true,
|
||||||
|
persistent: false
|
||||||
|
})
|
||||||
|
.append({
|
||||||
|
label: gettext('Type'),
|
||||||
|
name: 'type',
|
||||||
|
isServer: false,
|
||||||
|
singleton: true,
|
||||||
|
persistent: false,
|
||||||
|
options: [
|
||||||
|
{label: gettext('Primary'), key: 'primary'},
|
||||||
|
{label: gettext('Secondary'), key: 'secondary'}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
.append({
|
||||||
|
label: gettext('Status'),
|
||||||
|
name: 'status',
|
||||||
|
isServer: false,
|
||||||
|
singleton: true,
|
||||||
|
persistent: false,
|
||||||
|
options: [
|
||||||
|
{label: gettext('Active'), key: 'active'},
|
||||||
|
{label: gettext('Pending'), key: 'pending'}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
function typeMap() {
|
||||||
|
return {
|
||||||
|
'primary': gettext('Primary'),
|
||||||
|
'secondary': gettext('Secondary')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function listZones() {
|
||||||
|
return zoneApi.list().then(function onList(response) {
|
||||||
|
// listFunctions are expected to return data in "items"
|
||||||
|
response.data.items = response.data.zones;
|
||||||
|
|
||||||
|
util.addTimestampIds(response.data.items, 'updated_at');
|
||||||
|
|
||||||
|
return response;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
})();
|
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* (c) Copyright 2016 Hewlett-Packard Development Company, L.P.
|
||||||
|
*
|
||||||
|
* Licensed 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.
|
||||||
|
*/
|
||||||
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc overview
|
||||||
|
* @name designatedashboard.resources
|
||||||
|
* @description
|
||||||
|
*
|
||||||
|
* # designatedashboard.resources
|
||||||
|
*
|
||||||
|
* This module hosts registered resource types. This module file may
|
||||||
|
* contain individual registrations, or may have sub-modules that
|
||||||
|
* more fully contain registrations.
|
||||||
|
*/
|
||||||
|
angular
|
||||||
|
.module('designatedashboard.resources', [
|
||||||
|
'designatedashboard.resources.os-designate-recordset',
|
||||||
|
'designatedashboard.resources.os-designate-zone',
|
||||||
|
'designatedashboard.resources.os-designate-floatingip'
|
||||||
|
]);
|
||||||
|
})();
|
@ -0,0 +1,107 @@
|
|||||||
|
/**
|
||||||
|
* (c) Copyright 2016 Hewlett Packard Enterprise Development LP
|
||||||
|
*
|
||||||
|
* Licensed 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.
|
||||||
|
*/
|
||||||
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
angular
|
||||||
|
.module('designatedashboard.resources')
|
||||||
|
.factory('designatedashboard.resources.util', utilService);
|
||||||
|
|
||||||
|
utilService.$inject = [
|
||||||
|
'horizon.framework.util.q.extensions',
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
function utilService($qExtensions) {
|
||||||
|
var service = {
|
||||||
|
notDeleted: notDeleted,
|
||||||
|
notPending: notPending,
|
||||||
|
getModel: getModel,
|
||||||
|
actionMap: actionMap,
|
||||||
|
statusMap: statusMap,
|
||||||
|
addTimestampIds: addTimestampIds
|
||||||
|
};
|
||||||
|
|
||||||
|
return service;
|
||||||
|
|
||||||
|
///////////////
|
||||||
|
|
||||||
|
function notDeleted(resource) {
|
||||||
|
return $qExtensions.booleanAsPromise(resource.status !== 'DELETED');
|
||||||
|
}
|
||||||
|
|
||||||
|
function notPending(resource) {
|
||||||
|
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.
|
||||||
|
*
|
||||||
|
* @param form - an array of objects describing the form. Must have a 'key' attribute.
|
||||||
|
* @param item - the data to copy into the model
|
||||||
|
*/
|
||||||
|
function getModel(form, item) {
|
||||||
|
var result = {};
|
||||||
|
var value;
|
||||||
|
form.forEach(function iterateForm(formItem) {
|
||||||
|
value = item[formItem.key];
|
||||||
|
if (value) {
|
||||||
|
result[formItem.key] = item[formItem.key];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function actionMap() {
|
||||||
|
return {
|
||||||
|
'none': gettext('None'),
|
||||||
|
'create': gettext('Create')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function statusMap() {
|
||||||
|
return {
|
||||||
|
'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
|
||||||
|
* after row actions.
|
||||||
|
*
|
||||||
|
* If a timestamp field is not specified, the current time is used.
|
||||||
|
*
|
||||||
|
* @param items {object} - The items to add a _timestampId.
|
||||||
|
* @param idField {string} - (Optional) A field on the item to use as the id. Defaults to 'id'
|
||||||
|
* @param timestampField {string} - (Optional) A field on item to use as a timestamp. Defaults
|
||||||
|
* to current time.
|
||||||
|
*/
|
||||||
|
function addTimestampIds(items, idField, timestampField) {
|
||||||
|
var _idField = idField || 'id';
|
||||||
|
var timestamp = Date.now();
|
||||||
|
items.map(function annotateFloatingIp(item) {
|
||||||
|
if ( angular.isDefined(timestampField) ) {
|
||||||
|
timestamp = item[timestampField];
|
||||||
|
}
|
||||||
|
item._timestampId = item[_idField] + timestamp;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}());
|
@ -0,0 +1,4 @@
|
|||||||
|
<hz-resource-panel resource-type-name="OS::Designate::FloatingIp">
|
||||||
|
<hz-resource-table resource-type-name="OS::Designate::FloatingIp"
|
||||||
|
track-by="_timestampId"></hz-resource-table>
|
||||||
|
</hz-resource-panel>
|
4
designatedashboard/static/designatedashboard/zones.html
Normal file
4
designatedashboard/static/designatedashboard/zones.html
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<hz-resource-panel resource-type-name="OS::Designate::Zone">
|
||||||
|
<hz-resource-table resource-type-name="OS::Designate::Zone"
|
||||||
|
track-by="_timestampId"></hz-resource-table>
|
||||||
|
</hz-resource-panel>
|
Loading…
Reference in New Issue
Block a user