├── .eslintrc ├── .gitignore ├── .gitreview ├── .zuul.yaml ├── CONTRIBUTING.rst ├── HACKING.rst ├── LICENSE ├── README.rst ├── babel-django.cfg ├── bindep.txt ├── designatedashboard ├── __init__.py ├── api │ ├── __init__.py │ └── rest │ │ ├── __init__.py │ │ └── designate.py ├── dashboards │ ├── __init__.py │ └── project │ │ ├── __init__.py │ │ └── ngdns │ │ ├── __init__.py │ │ ├── reverse_dns │ │ ├── __init__.py │ │ ├── panel.py │ │ └── urls.py │ │ └── zones │ │ ├── __init__.py │ │ ├── panel.py │ │ └── urls.py ├── enabled │ ├── _1710_project_dns_panel_group.py │ ├── _1721_dns_zones_panel.py │ ├── _1722_dns_reversedns_panel.py │ └── __init__.py ├── local_settings.d │ └── _1799_dns_settings.py ├── locale │ ├── cs │ │ └── LC_MESSAGES │ │ │ └── django.po │ ├── de │ │ └── LC_MESSAGES │ │ │ └── django.po │ ├── en_GB │ │ └── LC_MESSAGES │ │ │ └── django.po │ ├── es │ │ └── LC_MESSAGES │ │ │ └── django.po │ ├── fr │ │ └── LC_MESSAGES │ │ │ └── django.po │ ├── id │ │ └── LC_MESSAGES │ │ │ └── django.po │ ├── ja │ │ └── LC_MESSAGES │ │ │ └── django.po │ ├── ko_KR │ │ └── LC_MESSAGES │ │ │ └── django.po │ ├── ne │ │ └── LC_MESSAGES │ │ │ └── django.po │ ├── pt_BR │ │ └── LC_MESSAGES │ │ │ └── django.po │ ├── ru │ │ └── LC_MESSAGES │ │ │ └── django.po │ ├── tr_TR │ │ └── LC_MESSAGES │ │ │ └── django.po │ └── zh_Hans │ │ └── LC_MESSAGES │ │ └── django.po ├── sdk_connection.py ├── static │ └── designatedashboard │ │ ├── designatedashboard.module.js │ │ ├── designatedashboard.scss │ │ ├── resources │ │ ├── os-designate-floatingip │ │ │ ├── actions │ │ │ │ ├── actions.module.js │ │ │ │ ├── set.service.js │ │ │ │ └── unset.service.js │ │ │ ├── api.service.js │ │ │ ├── details │ │ │ │ ├── details.module.js │ │ │ │ ├── drawer.html │ │ │ │ ├── overview.controller.js │ │ │ │ └── overview.html │ │ │ └── os-designate-floatingip.module.js │ │ ├── os-designate-recordset │ │ │ ├── actions │ │ │ │ ├── actions.module.js │ │ │ │ ├── common-forms.service.js │ │ │ │ ├── create.service.js │ │ │ │ ├── delete.service.js │ │ │ │ └── update.service.js │ │ │ ├── api.service.js │ │ │ ├── details │ │ │ │ ├── details.module.js │ │ │ │ ├── drawer.html │ │ │ │ ├── overview.controller.js │ │ │ │ ├── overview.html │ │ │ │ ├── zone-recordsets.controller.js │ │ │ │ └── zone-recordsets.html │ │ │ └── os-designate-recordset.module.js │ │ ├── os-designate-zone │ │ │ ├── actions │ │ │ │ ├── actions.module.js │ │ │ │ ├── actions.module.spec.js │ │ │ │ ├── common-forms.service.js │ │ │ │ ├── create.html │ │ │ │ ├── create.service.js │ │ │ │ ├── delete.service.js │ │ │ │ └── update.service.js │ │ │ ├── api.service.js │ │ │ ├── details │ │ │ │ ├── details.module.js │ │ │ │ ├── drawer.html │ │ │ │ ├── overview.controller.js │ │ │ │ └── overview.html │ │ │ └── os-designate-zone.module.js │ │ ├── resources.module.js │ │ └── util.service.js │ │ ├── reverse_dns.html │ │ └── zones.html └── tests │ ├── .secret_key_store │ ├── __init__.py │ ├── base.py │ └── settings.py ├── doc ├── requirements.txt └── source │ ├── conf.py │ ├── contributor │ └── index.rst │ ├── index.rst │ ├── install │ └── index.rst │ └── user │ └── index.rst ├── karma.conf.js ├── manage.py ├── package.json ├── releasenotes ├── notes │ ├── drop-py-2-7-ae8cade4a0ee1da8.yaml │ ├── drop-python-3-6-and-3-7-8d166b2f80b27277.yaml │ ├── drop-python-39.yaml │ ├── min-openstacksdk-b7e4661f8800bb9c.yaml │ ├── openstacksdk-11483491f9978bd1.yaml │ ├── remove-designateclient-e98963b8baa4aa4f.yaml │ ├── remove-oslo-log-078df11995380f36.yaml │ ├── remove-py38-1bc6676c8e5e880c.yaml │ └── removed-v1-dashboard-56d4697d57baef09.yaml └── source │ ├── 2023.1.rst │ ├── 2023.2.rst │ ├── 2024.1.rst │ ├── 2024.2.rst │ ├── 2025.1.rst │ ├── conf.py │ ├── index.rst │ ├── locale │ ├── cs │ │ └── LC_MESSAGES │ │ │ └── releasenotes.po │ ├── de │ │ └── LC_MESSAGES │ │ │ └── releasenotes.po │ ├── en_GB │ │ └── LC_MESSAGES │ │ │ └── releasenotes.po │ ├── fr │ │ └── LC_MESSAGES │ │ │ └── releasenotes.po │ ├── id │ │ └── LC_MESSAGES │ │ │ └── releasenotes.po │ ├── ja │ │ └── LC_MESSAGES │ │ │ └── releasenotes.po │ ├── ko_KR │ │ └── LC_MESSAGES │ │ │ └── releasenotes.po │ ├── ne │ │ └── LC_MESSAGES │ │ │ └── releasenotes.po │ ├── pt_BR │ │ └── LC_MESSAGES │ │ │ └── releasenotes.po │ ├── ru │ │ └── LC_MESSAGES │ │ │ └── releasenotes.po │ └── zh_CN │ │ └── LC_MESSAGES │ │ └── releasenotes.po │ ├── train.rst │ ├── unreleased.rst │ ├── ussuri.rst │ ├── victoria.rst │ ├── wallaby.rst │ ├── xena.rst │ ├── yoga.rst │ └── zed.rst ├── requirements.txt ├── setup.cfg ├── setup.py ├── test ├── test-requirements.txt ├── test-shim.js └── tox.ini /.eslintrc: -------------------------------------------------------------------------------- 1 | # Set up globals 2 | globals: 3 | angular: false 4 | 5 | extends: openstack 6 | 7 | # Most environment options are not explicitly enabled or disabled, only 8 | # included here for completeness' sake. They are commented out, because the 9 | # global updates.py script would otherwise override them during a global 10 | # requirements synchronization. 11 | # 12 | # Individual projects should choose which platforms they deploy to. 13 | 14 | env: 15 | # browser global variables. 16 | browser: true 17 | 18 | # Adds all of the Jasmine testing global variables for version 1.3 and 2.0. 19 | jasmine: true 20 | 21 | # Enable eslint-plugin-angular 22 | plugins: 23 | - angular 24 | 25 | # Below we adjust rules specific to horizon's usage of openstack's linting 26 | # rules, and its own plugin inclusions. 27 | rules: 28 | ############################################################################# 29 | # Disabled Rules from eslint-config-openstack 30 | ############################################################################# 31 | valid-jsdoc: 1 32 | brace-style: 1 33 | no-extra-parens: 1 34 | consistent-return: 1 35 | callback-return: 1 36 | guard-for-in: 1 37 | block-scoped-var: 1 38 | semi-spacing: 1 39 | no-redeclare: 1 40 | no-new: 1 41 | no-warning-comments: 0 42 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *.dat 3 | TAGS 4 | *.egg-info 5 | *.egg 6 | .eggs 7 | build 8 | .coverage 9 | .coverage.* 10 | .tox 11 | cover 12 | venv 13 | .venv 14 | *.sublime-workspace 15 | *.sqlite 16 | *.sqlite3 17 | var/* 18 | AUTHORS 19 | ChangeLog 20 | doc/source/api/* 21 | doc/build/* 22 | dist 23 | *.orig 24 | *.DS_Store 25 | *.idea 26 | .testrepository/* 27 | functionaltests/tempest.log 28 | functionaltests/.testrepository/ 29 | *.ipynb 30 | /.ipynb_checkpoints/* 31 | releasenotes/build 32 | node_modules 33 | npm-debug.log 34 | -------------------------------------------------------------------------------- /.gitreview: -------------------------------------------------------------------------------- 1 | [gerrit] 2 | host=review.opendev.org 3 | port=29418 4 | project=openstack/designate-dashboard.git 5 | -------------------------------------------------------------------------------- /.zuul.yaml: -------------------------------------------------------------------------------- 1 | - project: 2 | templates: 3 | - check-requirements 4 | - horizon-non-primary-django-jobs 5 | - horizon-nodejs-jobs 6 | - openstack-cover-jobs-horizon 7 | - openstack-python3-jobs-horizon 8 | - publish-openstack-docs-pti 9 | - release-notes-jobs-python3 10 | -------------------------------------------------------------------------------- /CONTRIBUTING.rst: -------------------------------------------------------------------------------- 1 | If you would like to contribute to the development of OpenStack, 2 | you must follow the steps in the "If you're a developer, start here" 3 | section of this page: 4 | 5 | https://wiki.openstack.org/wiki/How_To_Contribute 6 | 7 | Once those steps have been completed, changes to OpenStack 8 | should be submitted for review via the Gerrit tool, following 9 | the workflow documented at: 10 | 11 | https://docs.openstack.org/infra/manual/developers.html 12 | 13 | Pull requests submitted through GitHub will be ignored. 14 | 15 | Bugs should be filed on Launchpad, not GitHub: 16 | 17 | https://bugs.launchpad.net/designate-dashboard 18 | -------------------------------------------------------------------------------- /HACKING.rst: -------------------------------------------------------------------------------- 1 | designatedashboard Style Commandments 2 | ===================================== 3 | 4 | Read the OpenStack Style Commandments https://docs.openstack.org/hacking/latest/ 5 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | =================== 2 | Designate Dashboard 3 | =================== 4 | 5 | .. image:: https://governance.openstack.org/tc/badges/designate-dashboard.svg 6 | 7 | .. Change things from this point on 8 | 9 | Designate Horizon UI bits 10 | 11 | * Free software: Apache license 12 | 13 | Howto 14 | ----- 15 | 16 | 1. Package the designatedashboard by running:: 17 | 18 | python setup.py sdist 19 | 20 | This will create a python egg in the dist folder, which can be used to install 21 | on the horizon machine or within horizon's python virtual environment. 22 | 23 | -- or -- 24 | 25 | Install directly from source by running "python setup.py --install" 26 | 27 | Note: On some systems python may throw an error like 28 | 29 | 'Exception: Versioning for this project requires either an sdist tarball, or access 30 | to an upstream git repository' 31 | 32 | this seems to be a result of mismatched pbr versioning. A hacking workaround for development 33 | purposes is replacing the pbr call with a hard-coded version (e.g. '1.0.1') in 34 | designatedashboard/__init__.py. 35 | 36 | 2. Copy panel plugin files into your Horizon config. These files can be found in designatedashboard/enabled 37 | and should be copied to /usr/share/openstack-dashboard/openstack_dashboard/local/enabled or the 38 | equivalent directory for your openstack-dashboard install. 39 | 40 | 3. Copy default config file into your Horizon config. The file can be found in designatedashboard/local_settings.d 41 | and should be copied to /etc/openstack-dashboard/local_settings.d or the equivalent directory 42 | for your openstack-dashboard install. 43 | 44 | 3. Make sure your keystone catalog contains endpoints for service type 'dns'. If no such endpoints are 45 | found, the designatedashboard panels will not render. 46 | 47 | 4. (Optional) Copy the designate policy file into horizon's policy files folder. 48 | 49 | 50 | Test 51 | ---- 52 | 53 | * How to run JS tests: 54 | 55 | * Install npm and nodejs=4.8.4 56 | 57 | $ ``sudo apt-get install npm`` 58 | $ ``curl -sL https://deb.nodesource.com/setup_4.x | sudo -E bash -`` 59 | $ ``sudo apt-get install nodejs`` 60 | 61 | 1. ``npm install`` (to create virtual environment and install all dependencies in package.json) 62 | 2. ``npm run lint`` for eslint 63 | 3. ``npm run test`` for JS unit tests 64 | 65 | -------------------------------------------------------------------------------- /babel-django.cfg: -------------------------------------------------------------------------------- 1 | [python: **.py] 2 | [django: **/templates/**.html] 3 | -------------------------------------------------------------------------------- /bindep.txt: -------------------------------------------------------------------------------- 1 | # This is a cross-platform list tracking distribution packages needed for install and tests; 2 | # see https://docs.openstack.org/infra/bindep/ for additional information. 3 | 4 | libfontconfig1 [nodejs platform:dpkg] 5 | 6 | # PDF Docs package dependencies 7 | tex-gyre [doc platform:dpkg] 8 | -------------------------------------------------------------------------------- /designatedashboard/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 4 | # not use this file except in compliance with the License. You may obtain 5 | # a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations 13 | # under the License. 14 | 15 | import pbr.version 16 | 17 | 18 | __version__ = pbr.version.VersionInfo( 19 | 'designate-dashboard').version_string() 20 | -------------------------------------------------------------------------------- /designatedashboard/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/designate-dashboard/e9ce32addfdb257956cce7e6961ef3172f304a22/designatedashboard/api/__init__.py -------------------------------------------------------------------------------- /designatedashboard/api/rest/__init__.py: -------------------------------------------------------------------------------- 1 | # (c) Copyright Hewlett Packard Enterprise Development LP 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | """REST API for Horizon dashboard Javascript code. 15 | """ 16 | from . import designate # noqa 17 | -------------------------------------------------------------------------------- /designatedashboard/api/rest/designate.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023 Binero 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from designatedashboard.sdk_connection import get_sdk_connection 16 | from django.views import generic 17 | import logging 18 | 19 | from openstack_dashboard.api.rest import urls 20 | from openstack_dashboard.api.rest import utils as rest_utils 21 | 22 | 23 | LOG = logging.getLogger(__name__) 24 | 25 | 26 | def _sdk_object_to_list(object): 27 | """Converts an SDK generator object to a list of dictionaries. 28 | 29 | :param object: SDK generator object 30 | :returns: List of dictionaries 31 | """ 32 | result_list = [] 33 | for item in object: 34 | result_list.append(item.to_dict()) 35 | return result_list 36 | 37 | 38 | def create_zone(request): 39 | """Create zone.""" 40 | data = request.DATA 41 | 42 | conn = get_sdk_connection(request) 43 | build_kwargs = dict( 44 | name=data['name'], 45 | email=data['email'], 46 | type=data['type'], 47 | ) 48 | if data.get('description', None): 49 | build_kwargs['description'] = data['description'] 50 | if data.get('ttl', None): 51 | build_kwargs['ttl'] = data['ttl'] 52 | if data.get('masters', None): 53 | build_kwargs['masters'] = data['masters'] 54 | 55 | zone = conn.dns.create_zone(**build_kwargs) 56 | return zone.to_dict() 57 | 58 | 59 | def update_zone(request, **kwargs): 60 | """Update zone.""" 61 | data = request.DATA 62 | zone_id = kwargs.get('zone_id') 63 | 64 | conn = get_sdk_connection(request) 65 | build_kwargs = dict( 66 | email=data['email'], 67 | description=data['description'], 68 | ttl=data['ttl'], 69 | ) 70 | zone = conn.dns.update_zone( 71 | zone_id, **build_kwargs) 72 | return zone.to_dict() 73 | 74 | 75 | @urls.register 76 | class Zones(generic.View): 77 | """API for zones.""" 78 | 79 | url_regex = r'dns/v2/zones/$' 80 | 81 | @rest_utils.ajax() 82 | def get(self, request): 83 | """List zones for current project.""" 84 | conn = get_sdk_connection(request) 85 | zones = _sdk_object_to_list(conn.dns.zones()) 86 | return {'zones': zones} 87 | 88 | @rest_utils.ajax(data_required=True) 89 | def post(self, request): 90 | """Create zone.""" 91 | return create_zone(request) 92 | 93 | 94 | @urls.register 95 | class Zone(generic.View): 96 | """API for zone.""" 97 | url_regex = r'dns/v2/zones/(?P[^/]+)/$' 98 | 99 | @rest_utils.ajax() 100 | def get(self, request, zone_id): 101 | """Get zone.""" 102 | conn = get_sdk_connection(request) 103 | zone = conn.dns.find_zone(zone_id) 104 | return zone.to_dict() 105 | 106 | @rest_utils.ajax(data_required=True) 107 | def patch(self, request, zone_id): 108 | """Edit zone.""" 109 | kwargs = {'zone_id': zone_id} 110 | update_zone(request, **kwargs) 111 | 112 | @rest_utils.ajax() 113 | def delete(self, request, zone_id): 114 | """Delete zone.""" 115 | conn = get_sdk_connection(request) 116 | conn.dns.delete_zone(zone_id, ignore_missing=True) 117 | 118 | 119 | def create_recordset(request, **kwargs): 120 | """Create recordset.""" 121 | data = request.DATA 122 | zone_id = kwargs.get('zone_id') 123 | 124 | conn = get_sdk_connection(request) 125 | build_kwargs = dict( 126 | name=data['name'], 127 | type=data['type'], 128 | ttl=data['ttl'], 129 | records=data['records'], 130 | ) 131 | if data.get('description', None): 132 | build_kwargs['description'] = data['description'] 133 | 134 | rs = conn.dns.create_recordset( 135 | zone_id, **build_kwargs) 136 | return rs.to_dict() 137 | 138 | 139 | def update_recordset(request, **kwargs): 140 | """Update recordset.""" 141 | data = request.DATA 142 | zone_id = kwargs.get('zone_id') 143 | rs_id = kwargs.get('rs_id') 144 | 145 | conn = get_sdk_connection(request) 146 | 147 | build_kwargs = dict() 148 | if data.get('description', None): 149 | build_kwargs['description'] = data['description'] 150 | if data.get('ttl', None): 151 | build_kwargs['ttl'] = data['ttl'] 152 | if data.get('records', None): 153 | build_kwargs['records'] = data['records'] 154 | 155 | build_kwargs['zone_id'] = zone_id 156 | rs = conn.dns.update_recordset( 157 | rs_id, **build_kwargs) 158 | return rs.to_dict() 159 | 160 | 161 | def _populate_zone_id(items, zone_id): 162 | for item in items: 163 | item['zone_id'] = zone_id 164 | return items 165 | 166 | 167 | @urls.register 168 | class RecordSets(generic.View): 169 | """API for recordsets.""" 170 | url_regex = r'dns/v2/zones/(?P[^/]+)/recordsets/$' 171 | 172 | @rest_utils.ajax() 173 | def get(self, request, zone_id): 174 | """Get recordsets.""" 175 | conn = get_sdk_connection(request) 176 | rsets = _sdk_object_to_list(conn.dns.recordsets(zone_id)) 177 | return {'recordsets': _populate_zone_id(rsets, zone_id)} 178 | 179 | @rest_utils.ajax(data_required=True) 180 | def post(self, request, zone_id): 181 | """Create recordset.""" 182 | kwargs = {'zone_id': zone_id} 183 | return create_recordset(request, **kwargs) 184 | 185 | 186 | @urls.register 187 | class RecordSet(generic.View): 188 | """API for recordset.""" 189 | url_regex = r'dns/v2/zones/(?P[^/]+)/recordsets/(?P[^/]+)/$' # noqa 190 | 191 | @rest_utils.ajax() 192 | def get(self, request, zone_id, rs_id): 193 | """Get recordset.""" 194 | conn = get_sdk_connection(request) 195 | rs = conn.dns.get_recordset(rs_id, zone_id) 196 | rs_dict = rs.to_dict() 197 | rs_dict['zone_id'] = zone_id 198 | return rs_dict 199 | 200 | @rest_utils.ajax(data_required=True) 201 | def put(self, request, zone_id, rs_id): 202 | """Edit recordset.""" 203 | kwargs = {'zone_id': zone_id, 'rs_id': rs_id} 204 | update_recordset(request, **kwargs) 205 | 206 | @rest_utils.ajax() 207 | def delete(self, request, zone_id, rs_id): 208 | """Delete recordset.""" 209 | conn = get_sdk_connection(request) 210 | conn.dns.delete_recordset(rs_id, zone_id, ignore_missing=True) 211 | 212 | 213 | @urls.register 214 | class DnsFloatingIps(generic.View): 215 | """API for floatingips.""" 216 | url_regex = r'dns/v2/reverse/floatingips/$' 217 | 218 | @rest_utils.ajax() 219 | def get(self, request): 220 | """Get floatingips.""" 221 | conn = get_sdk_connection(request) 222 | fips = _sdk_object_to_list(conn.dns.floating_ips()) 223 | return {'floatingips': fips} 224 | 225 | 226 | def update_dns_floatingip(request, **kwargs): 227 | """Update recordset.""" 228 | data = request.DATA 229 | fip_id = kwargs.get('fip_id') 230 | 231 | conn = get_sdk_connection(request) 232 | 233 | build_kwargs = dict( 234 | ptrdname=data['ptrdname'], 235 | ) 236 | if data.get('description', None): 237 | build_kwargs['description'] = data['description'] 238 | if data.get('ttl', None): 239 | build_kwargs['ttl'] = data['ttl'] 240 | 241 | fip = conn.dns.update_floating_ip( 242 | fip_id, **build_kwargs) 243 | return fip.to_dict() 244 | 245 | 246 | @urls.register 247 | class DnsFloatingIp(generic.View): 248 | """API for dns floatingip.""" 249 | url_regex = r'dns/v2/reverse/floatingips/(?P[^/]+)/$' 250 | 251 | @rest_utils.ajax() 252 | def get(self, request, fip_id): 253 | """Get floatingip.""" 254 | conn = get_sdk_connection(request) 255 | fip = conn.dns.get_floating_ip(fip_id) 256 | return fip.to_dict() 257 | 258 | @rest_utils.ajax(data_required=True) 259 | def patch(self, request, fip_id): 260 | """Edit floatingip.""" 261 | kwargs = {'fip_id': fip_id} 262 | update_dns_floatingip(request, **kwargs) 263 | -------------------------------------------------------------------------------- /designatedashboard/dashboards/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/designate-dashboard/e9ce32addfdb257956cce7e6961ef3172f304a22/designatedashboard/dashboards/__init__.py -------------------------------------------------------------------------------- /designatedashboard/dashboards/project/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/designate-dashboard/e9ce32addfdb257956cce7e6961ef3172f304a22/designatedashboard/dashboards/project/__init__.py -------------------------------------------------------------------------------- /designatedashboard/dashboards/project/ngdns/__init__.py: -------------------------------------------------------------------------------- 1 | from designatedashboard.api import rest # noqa 2 | -------------------------------------------------------------------------------- /designatedashboard/dashboards/project/ngdns/reverse_dns/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/designate-dashboard/e9ce32addfdb257956cce7e6961ef3172f304a22/designatedashboard/dashboards/project/ngdns/reverse_dns/__init__.py -------------------------------------------------------------------------------- /designatedashboard/dashboards/project/ngdns/reverse_dns/panel.py: -------------------------------------------------------------------------------- 1 | # (c) Copyright 2015 Hewlett-Packard Development Company, L.P. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 4 | # not use this file except in compliance with the License. You may obtain 5 | # a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations 13 | # under the License. 14 | from django.utils.translation import gettext_lazy as _ 15 | 16 | import horizon 17 | from openstack_dashboard.dashboards.project import dashboard 18 | 19 | 20 | class ReverseDns(horizon.Panel): 21 | name = _("Reverse DNS") 22 | slug = 'reverse_dns' 23 | permissions = ('openstack.services.dns',) 24 | 25 | 26 | dashboard.Project.register(ReverseDns) 27 | -------------------------------------------------------------------------------- /designatedashboard/dashboards/project/ngdns/reverse_dns/urls.py: -------------------------------------------------------------------------------- 1 | # (c) Copyright 2015 Hewlett-Packard Development Company, L.P. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 4 | # not use this file except in compliance with the License. You may obtain 5 | # a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations 13 | # under the License. 14 | 15 | from django.urls import re_path 16 | from django.utils.translation import gettext_lazy as _ 17 | from horizon.browsers import views 18 | 19 | title = _("Reverse DNS") 20 | 21 | urlpatterns = [ 22 | re_path('', views.AngularIndexView.as_view(title=title), name='index'), 23 | ] 24 | -------------------------------------------------------------------------------- /designatedashboard/dashboards/project/ngdns/zones/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/designate-dashboard/e9ce32addfdb257956cce7e6961ef3172f304a22/designatedashboard/dashboards/project/ngdns/zones/__init__.py -------------------------------------------------------------------------------- /designatedashboard/dashboards/project/ngdns/zones/panel.py: -------------------------------------------------------------------------------- 1 | # (c) Copyright 2015 Hewlett-Packard Development Company, L.P. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 4 | # not use this file except in compliance with the License. You may obtain 5 | # a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations 13 | # under the License. 14 | from django.utils.translation import gettext_lazy as _ 15 | 16 | import horizon 17 | from openstack_dashboard.dashboards.project import dashboard 18 | 19 | 20 | class Zones(horizon.Panel): 21 | name = _("Zones") 22 | slug = 'dnszones' 23 | permissions = ('openstack.services.dns',) 24 | 25 | 26 | dashboard.Project.register(Zones) 27 | -------------------------------------------------------------------------------- /designatedashboard/dashboards/project/ngdns/zones/urls.py: -------------------------------------------------------------------------------- 1 | # (c) Copyright 2015 Hewlett-Packard Development Company, L.P. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 4 | # not use this file except in compliance with the License. You may obtain 5 | # a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations 13 | # under the License. 14 | 15 | from django.urls import re_path 16 | from django.utils.translation import gettext_lazy as _ 17 | from horizon.browsers import views 18 | 19 | title = _("Zones") 20 | 21 | urlpatterns = [ 22 | re_path('', views.AngularIndexView.as_view(title=title), name='index') 23 | ] 24 | -------------------------------------------------------------------------------- /designatedashboard/enabled/_1710_project_dns_panel_group.py: -------------------------------------------------------------------------------- 1 | # Copyright 2013 Hewlett-Packard Development Company, L.P. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 4 | # not use this file except in compliance with the License. You may obtain 5 | # a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations 13 | # under the License. 14 | 15 | # The name of the panel group to be added to HORIZON_CONFIG. Required. 16 | PANEL_GROUP = 'dns' 17 | # The display name of the PANEL_GROUP. Required. 18 | PANEL_GROUP_NAME = 'DNS' 19 | # The name of the dashboard the PANEL_GROUP associated with. Required. 20 | PANEL_GROUP_DASHBOARD = 'project' 21 | -------------------------------------------------------------------------------- /designatedashboard/enabled/_1721_dns_zones_panel.py: -------------------------------------------------------------------------------- 1 | # Copyright 2013 Hewlett-Packard Development Company, L.P. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 4 | # not use this file except in compliance with the License. You may obtain 5 | # a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations 13 | # under the License. 14 | 15 | # The name of the panel to be added to HORIZON_CONFIG. Required. 16 | PANEL = 'dnszones' 17 | # The name of the dashboard the PANEL associated with. Required. 18 | PANEL_DASHBOARD = 'project' 19 | # The name of the panel group the PANEL is associated with. 20 | PANEL_GROUP = 'dns' 21 | 22 | ADD_INSTALLED_APPS = ['designatedashboard'] 23 | 24 | # Python panel class of the PANEL to be added. 25 | ADD_PANEL = ( 26 | 'designatedashboard.dashboards.project.ngdns.zones.panel.Zones') 27 | 28 | ADD_ANGULAR_MODULES = ['designatedashboard'] 29 | 30 | ADD_SCSS_FILES = ['designatedashboard/designatedashboard.scss'] 31 | 32 | AUTO_DISCOVER_STATIC_FILES = True 33 | -------------------------------------------------------------------------------- /designatedashboard/enabled/_1722_dns_reversedns_panel.py: -------------------------------------------------------------------------------- 1 | # Copyright 2013 Hewlett-Packard Development Company, L.P. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 4 | # not use this file except in compliance with the License. You may obtain 5 | # a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations 13 | # under the License. 14 | 15 | # The name of the panel to be added to HORIZON_CONFIG. Required. 16 | PANEL = 'reverse_dns' 17 | # The name of the dashboard the PANEL associated with. Required. 18 | PANEL_DASHBOARD = 'project' 19 | # The name of the panel group the PANEL is associated with. 20 | PANEL_GROUP = 'dns' 21 | 22 | # Python panel class of the PANEL to be added. 23 | ADD_PANEL = ( 24 | 'designatedashboard.dashboards.project.ngdns.reverse_dns.panel.ReverseDns') 25 | 26 | ADD_ANGULAR_MODULES = ['designatedashboard'] 27 | 28 | ADD_SCSS_FILES = ['designatedashboard/designatedashboard.scss'] 29 | 30 | AUTO_DISCOVER_STATIC_FILES = True 31 | -------------------------------------------------------------------------------- /designatedashboard/enabled/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/designate-dashboard/e9ce32addfdb257956cce7e6961ef3172f304a22/designatedashboard/enabled/__init__.py -------------------------------------------------------------------------------- /designatedashboard/local_settings.d/_1799_dns_settings.py: -------------------------------------------------------------------------------- 1 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 2 | # not use this file except in compliance with the License. You may obtain 3 | # a copy of the License at 4 | # 5 | # http://www.apache.org/licenses/LICENSE-2.0 6 | # 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | # License for the specific language governing permissions and limitations 11 | # under the License. 12 | 13 | # This file is to be included for configuring application which relates 14 | # to dns(Designate) functions. 15 | from django.conf import settings 16 | 17 | settings.POLICY_FILES.update({ 18 | 'dns': 'designate_policy.yaml' 19 | }) 20 | 21 | settings.DEFAULT_POLICY_FILES.update({ 22 | 'dns': 'default_policies/designate.yaml' 23 | }) 24 | -------------------------------------------------------------------------------- /designatedashboard/locale/cs/LC_MESSAGES/django.po: -------------------------------------------------------------------------------- 1 | # Zbyněk Schwarz , 2017. #zanata 2 | msgid "" 3 | msgstr "" 4 | "Project-Id-Version: designate-dashboard VERSION\n" 5 | "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" 6 | "POT-Creation-Date: 2019-09-23 21:56+0000\n" 7 | "MIME-Version: 1.0\n" 8 | "Content-Type: text/plain; charset=UTF-8\n" 9 | "Content-Transfer-Encoding: 8bit\n" 10 | "PO-Revision-Date: 2017-11-17 05:49+0000\n" 11 | "Last-Translator: Zbyněk Schwarz \n" 12 | "Language-Team: Czech\n" 13 | "Language: cs\n" 14 | "X-Generator: Zanata 4.3.3\n" 15 | "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2\n" 16 | 17 | msgid "Reverse DNS" 18 | msgstr "Reverzní DNS" 19 | 20 | msgid "Zones" 21 | msgstr "Zóny" 22 | -------------------------------------------------------------------------------- /designatedashboard/locale/de/LC_MESSAGES/django.po: -------------------------------------------------------------------------------- 1 | # Frank Kloeker , 2016. #zanata 2 | # Frank Kloeker , 2018. #zanata 3 | msgid "" 4 | msgstr "" 5 | "Project-Id-Version: designate-dashboard VERSION\n" 6 | "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" 7 | "POT-Creation-Date: 2019-09-23 21:56+0000\n" 8 | "MIME-Version: 1.0\n" 9 | "Content-Type: text/plain; charset=UTF-8\n" 10 | "Content-Transfer-Encoding: 8bit\n" 11 | "PO-Revision-Date: 2018-07-29 10:32+0000\n" 12 | "Last-Translator: Frank Kloeker \n" 13 | "Language-Team: German\n" 14 | "Language: de\n" 15 | "X-Generator: Zanata 4.3.3\n" 16 | "Plural-Forms: nplurals=2; plural=(n != 1)\n" 17 | 18 | msgid "Reverse DNS" 19 | msgstr "Reverse DNS" 20 | 21 | msgid "Zones" 22 | msgstr "Zonen" 23 | -------------------------------------------------------------------------------- /designatedashboard/locale/en_GB/LC_MESSAGES/django.po: -------------------------------------------------------------------------------- 1 | # Andreas Jaeger , 2016. #zanata 2 | msgid "" 3 | msgstr "" 4 | "Project-Id-Version: designate-dashboard VERSION\n" 5 | "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" 6 | "POT-Creation-Date: 2019-09-23 21:56+0000\n" 7 | "MIME-Version: 1.0\n" 8 | "Content-Type: text/plain; charset=UTF-8\n" 9 | "Content-Transfer-Encoding: 8bit\n" 10 | "PO-Revision-Date: 2016-10-23 09:03+0000\n" 11 | "Last-Translator: Andreas Jaeger \n" 12 | "Language-Team: English (United Kingdom)\n" 13 | "Language: en_GB\n" 14 | "X-Generator: Zanata 4.3.3\n" 15 | "Plural-Forms: nplurals=2; plural=(n != 1)\n" 16 | 17 | msgid "Reverse DNS" 18 | msgstr "Reverse DNS" 19 | 20 | msgid "Zones" 21 | msgstr "Zones" 22 | -------------------------------------------------------------------------------- /designatedashboard/locale/es/LC_MESSAGES/django.po: -------------------------------------------------------------------------------- 1 | # Alberto Molina Coballes , 2017. #zanata 2 | msgid "" 3 | msgstr "" 4 | "Project-Id-Version: designate-dashboard VERSION\n" 5 | "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" 6 | "POT-Creation-Date: 2019-09-23 21:56+0000\n" 7 | "MIME-Version: 1.0\n" 8 | "Content-Type: text/plain; charset=UTF-8\n" 9 | "Content-Transfer-Encoding: 8bit\n" 10 | "PO-Revision-Date: 2017-02-22 06:47+0000\n" 11 | "Last-Translator: Alberto Molina Coballes \n" 12 | "Language-Team: Spanish\n" 13 | "Language: es\n" 14 | "X-Generator: Zanata 4.3.3\n" 15 | "Plural-Forms: nplurals=2; plural=(n != 1)\n" 16 | 17 | msgid "Reverse DNS" 18 | msgstr "DNS inverso" 19 | 20 | msgid "Zones" 21 | msgstr "Zonas" 22 | -------------------------------------------------------------------------------- /designatedashboard/locale/fr/LC_MESSAGES/django.po: -------------------------------------------------------------------------------- 1 | # Translations template for designate-dashboard. 2 | # Copyright (C) 2015 ORGANIZATION 3 | # This file is distributed under the same license as the designate-dashboard 4 | # project. 5 | # 6 | # Translators: 7 | # Lucas Mascaro , 2015 8 | # Gérald LONLAS , 2016. #zanata 9 | msgid "" 10 | msgstr "" 11 | "Project-Id-Version: designate-dashboard VERSION\n" 12 | "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" 13 | "POT-Creation-Date: 2019-09-23 21:56+0000\n" 14 | "MIME-Version: 1.0\n" 15 | "Content-Type: text/plain; charset=UTF-8\n" 16 | "Content-Transfer-Encoding: 8bit\n" 17 | "PO-Revision-Date: 2016-10-27 03:42+0000\n" 18 | "Last-Translator: Gérald LONLAS \n" 19 | "Language: fr\n" 20 | "Plural-Forms: nplurals=2; plural=(n > 1);\n" 21 | "Generated-By: Babel 2.0\n" 22 | "X-Generator: Zanata 4.3.3\n" 23 | "Language-Team: French\n" 24 | 25 | msgid "Reverse DNS" 26 | msgstr "Reverse DNS" 27 | 28 | msgid "Zones" 29 | msgstr "Zones" 30 | -------------------------------------------------------------------------------- /designatedashboard/locale/id/LC_MESSAGES/django.po: -------------------------------------------------------------------------------- 1 | # suhartono , 2016. #zanata 2 | msgid "" 3 | msgstr "" 4 | "Project-Id-Version: designate-dashboard VERSION\n" 5 | "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" 6 | "POT-Creation-Date: 2019-09-23 21:56+0000\n" 7 | "MIME-Version: 1.0\n" 8 | "Content-Type: text/plain; charset=UTF-8\n" 9 | "Content-Transfer-Encoding: 8bit\n" 10 | "PO-Revision-Date: 2016-10-13 01:36+0000\n" 11 | "Last-Translator: suhartono \n" 12 | "Language-Team: Indonesian\n" 13 | "Language: id\n" 14 | "X-Generator: Zanata 4.3.3\n" 15 | "Plural-Forms: nplurals=1; plural=0\n" 16 | 17 | msgid "Reverse DNS" 18 | msgstr "Reverse DNS " 19 | 20 | msgid "Zones" 21 | msgstr "Zones (zona)" 22 | -------------------------------------------------------------------------------- /designatedashboard/locale/ja/LC_MESSAGES/django.po: -------------------------------------------------------------------------------- 1 | # Yoshiki Eguchi , 2016. #zanata 2 | # Akihiro Motoki , 2018. #zanata 3 | msgid "" 4 | msgstr "" 5 | "Project-Id-Version: designate-dashboard VERSION\n" 6 | "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" 7 | "POT-Creation-Date: 2019-09-23 21:56+0000\n" 8 | "MIME-Version: 1.0\n" 9 | "Content-Type: text/plain; charset=UTF-8\n" 10 | "Content-Transfer-Encoding: 8bit\n" 11 | "PO-Revision-Date: 2018-02-08 08:47+0000\n" 12 | "Last-Translator: Akihiro Motoki \n" 13 | "Language-Team: Japanese\n" 14 | "Language: ja\n" 15 | "X-Generator: Zanata 4.3.3\n" 16 | "Plural-Forms: nplurals=1; plural=0\n" 17 | 18 | msgid "Reverse DNS" 19 | msgstr "リバース DNS" 20 | 21 | msgid "Zones" 22 | msgstr "ゾーン" 23 | -------------------------------------------------------------------------------- /designatedashboard/locale/ko_KR/LC_MESSAGES/django.po: -------------------------------------------------------------------------------- 1 | # Sungjin Kang , 2017. #zanata 2 | msgid "" 3 | msgstr "" 4 | "Project-Id-Version: designate-dashboard VERSION\n" 5 | "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" 6 | "POT-Creation-Date: 2019-09-23 21:56+0000\n" 7 | "MIME-Version: 1.0\n" 8 | "Content-Type: text/plain; charset=UTF-8\n" 9 | "Content-Transfer-Encoding: 8bit\n" 10 | "PO-Revision-Date: 2017-12-19 03:03+0000\n" 11 | "Last-Translator: Ian Y. Choi \n" 12 | "Language-Team: Korean (South Korea)\n" 13 | "Language: ko_KR\n" 14 | "X-Generator: Zanata 4.3.3\n" 15 | "Plural-Forms: nplurals=1; plural=0\n" 16 | 17 | msgid "Reverse DNS" 18 | msgstr "Reverse DNS" 19 | 20 | msgid "Zones" 21 | msgstr "존" 22 | -------------------------------------------------------------------------------- /designatedashboard/locale/ne/LC_MESSAGES/django.po: -------------------------------------------------------------------------------- 1 | # Surit Aryal , 2019. #zanata 2 | msgid "" 3 | msgstr "" 4 | "Project-Id-Version: designate-dashboard VERSION\n" 5 | "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" 6 | "POT-Creation-Date: 2019-09-23 21:56+0000\n" 7 | "MIME-Version: 1.0\n" 8 | "Content-Type: text/plain; charset=UTF-8\n" 9 | "Content-Transfer-Encoding: 8bit\n" 10 | "PO-Revision-Date: 2019-06-07 05:03+0000\n" 11 | "Last-Translator: Surit Aryal \n" 12 | "Language-Team: Nepali\n" 13 | "Language: ne\n" 14 | "X-Generator: Zanata 4.3.3\n" 15 | "Plural-Forms: nplurals=2; plural=(n != 1)\n" 16 | 17 | msgid "Reverse DNS" 18 | msgstr "Reverse DNS" 19 | 20 | msgid "Zones" 21 | msgstr "Zones" 22 | -------------------------------------------------------------------------------- /designatedashboard/locale/pt_BR/LC_MESSAGES/django.po: -------------------------------------------------------------------------------- 1 | # Marcio , 2017. #zanata 2 | msgid "" 3 | msgstr "" 4 | "Project-Id-Version: designate-dashboard VERSION\n" 5 | "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" 6 | "POT-Creation-Date: 2019-09-23 21:56+0000\n" 7 | "MIME-Version: 1.0\n" 8 | "Content-Type: text/plain; charset=UTF-8\n" 9 | "Content-Transfer-Encoding: 8bit\n" 10 | "PO-Revision-Date: 2017-03-15 07:16+0000\n" 11 | "Last-Translator: Marcio \n" 12 | "Language-Team: Portuguese (Brazil)\n" 13 | "Language: pt_BR\n" 14 | "X-Generator: Zanata 4.3.3\n" 15 | "Plural-Forms: nplurals=2; plural=(n != 1)\n" 16 | 17 | msgid "Reverse DNS" 18 | msgstr "DNS Reverso" 19 | 20 | msgid "Zones" 21 | msgstr "Zonas" 22 | -------------------------------------------------------------------------------- /designatedashboard/locale/ru/LC_MESSAGES/django.po: -------------------------------------------------------------------------------- 1 | # Translations template for designate-dashboard. 2 | # Copyright (C) 2015 ORGANIZATION 3 | # This file is distributed under the same license as the designate-dashboard 4 | # project. 5 | # 6 | # Translators: 7 | # Denis Gubanov , 2015 8 | # Ivan Startsev , 2016. #zanata 9 | msgid "" 10 | msgstr "" 11 | "Project-Id-Version: designate-dashboard VERSION\n" 12 | "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" 13 | "POT-Creation-Date: 2019-09-23 21:56+0000\n" 14 | "MIME-Version: 1.0\n" 15 | "Content-Type: text/plain; charset=UTF-8\n" 16 | "Content-Transfer-Encoding: 8bit\n" 17 | "PO-Revision-Date: 2016-10-05 02:21+0000\n" 18 | "Last-Translator: Ivan Startsev \n" 19 | "Language: ru\n" 20 | "Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" 21 | "%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n" 22 | "%100>=11 && n%100<=14)? 2 : 3);\n" 23 | "Generated-By: Babel 2.0\n" 24 | "X-Generator: Zanata 4.3.3\n" 25 | "Language-Team: Russian\n" 26 | 27 | msgid "Reverse DNS" 28 | msgstr "Обратный DNS" 29 | 30 | msgid "Zones" 31 | msgstr "Зоны" 32 | -------------------------------------------------------------------------------- /designatedashboard/locale/tr_TR/LC_MESSAGES/django.po: -------------------------------------------------------------------------------- 1 | # Translations template for designate-dashboard. 2 | # Copyright (C) 2015 ORGANIZATION 3 | # This file is distributed under the same license as the designate-dashboard 4 | # project. 5 | # 6 | # Translators: 7 | # Alper Çiftçi , 2015 8 | # işbaran akçayır , 2017. #zanata 9 | msgid "" 10 | msgstr "" 11 | "Project-Id-Version: designate-dashboard VERSION\n" 12 | "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" 13 | "POT-Creation-Date: 2019-09-23 21:56+0000\n" 14 | "MIME-Version: 1.0\n" 15 | "Content-Type: text/plain; charset=UTF-8\n" 16 | "Content-Transfer-Encoding: 8bit\n" 17 | "PO-Revision-Date: 2017-05-22 08:57+0000\n" 18 | "Last-Translator: Copied by Zanata \n" 19 | "Language: tr_TR\n" 20 | "Plural-Forms: nplurals=1; plural=0;\n" 21 | "Generated-By: Babel 2.0\n" 22 | "X-Generator: Zanata 4.3.3\n" 23 | "Language-Team: Turkish (Turkey)\n" 24 | 25 | msgid "Reverse DNS" 26 | msgstr "Ters DNS" 27 | 28 | msgid "Zones" 29 | msgstr "Bölgeler" 30 | -------------------------------------------------------------------------------- /designatedashboard/locale/zh_Hans/LC_MESSAGES/django.po: -------------------------------------------------------------------------------- 1 | # zzxwill , 2016. #zanata 2 | msgid "" 3 | msgstr "" 4 | "Project-Id-Version: designate-dashboard VERSION\n" 5 | "Report-Msgid-Bugs-To: https://bugs.launchpad.net/openstack-i18n/\n" 6 | "POT-Creation-Date: 2020-12-03 11:20+0000\n" 7 | "MIME-Version: 1.0\n" 8 | "Content-Type: text/plain; charset=UTF-8\n" 9 | "Content-Transfer-Encoding: 8bit\n" 10 | "PO-Revision-Date: 2016-09-27 06:48+0000\n" 11 | "Last-Translator: zzxwill \n" 12 | "Language-Team: Chinese (China)\n" 13 | "Language: zh_CN\n" 14 | "X-Generator: Zanata 4.3.3\n" 15 | "Plural-Forms: nplurals=1; plural=0\n" 16 | 17 | msgid "Reverse DNS" 18 | msgstr "反向解析域名" 19 | 20 | msgid "Zones" 21 | msgstr "区域" 22 | -------------------------------------------------------------------------------- /designatedashboard/sdk_connection.py: -------------------------------------------------------------------------------- 1 | # Copyright Red Hat 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 4 | # not use this file except in compliance with the License. You may obtain 5 | # a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations 13 | # under the License. 14 | from django.conf import settings 15 | 16 | import designatedashboard 17 | from openstack import config as occ 18 | from openstack import connection 19 | 20 | 21 | def get_sdk_connection(request): 22 | """Creates an SDK connection based on the request. 23 | 24 | :param request: Django request object 25 | :returns: SDK connection object 26 | """ 27 | # NOTE(mordred) Nothing says love like two inverted booleans 28 | # The config setting is NO_VERIFY which is, in fact, insecure. 29 | # get_one_cloud wants verify, so we pass 'not insecure' to verify. 30 | insecure = getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', False) 31 | cacert = getattr(settings, 'OPENSTACK_SSL_CACERT', None) 32 | # Pass interface to honor 'OPENSTACK_ENDPOINT_TYPE' 33 | interface = getattr(settings, 'OPENSTACK_ENDPOINT_TYPE', 'publicURL') 34 | # Pass load_yaml_config as this is a Django service with its own config 35 | # and we don't want to accidentally pick up a clouds.yaml file. We want to 36 | # use the settings we're passing in. 37 | cloud_config = occ.OpenStackConfig(load_yaml_config=False).get_one_cloud( 38 | verify=not insecure, 39 | cacert=cacert, 40 | interface=interface, 41 | region_name=request.user.services_region, 42 | auth_type='token', 43 | auth=dict( 44 | project_id=request.user.project_id, 45 | project_domain_id=request.user.domain_id, 46 | auth_token=request.user.token.unscoped_token, 47 | auth_url=request.user.endpoint), 48 | app_name='designate-dashboard', 49 | app_version=designatedashboard.__version__) 50 | return connection.from_config(cloud_config=cloud_config) 51 | -------------------------------------------------------------------------------- /designatedashboard/static/designatedashboard/designatedashboard.module.js: -------------------------------------------------------------------------------- 1 | /** 2 | * (c) Copyright 2015 Hewlett-Packard Development Company, L.P. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | * not use this file except in compliance with the License. You may obtain 6 | * a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | (function() { 18 | 'use strict'; 19 | 20 | /** 21 | * @ngdoc overview 22 | * @ngname designatedashboard 23 | * 24 | * @description 25 | * Provides the services and widgets required 26 | * to support and display the project search panel. 27 | */ 28 | angular 29 | .module('designatedashboard', [ 30 | 'ngRoute', 31 | 'designatedashboard.resources' 32 | ]) 33 | .constant( 34 | 'designatedashboard.apiPassthroughUrl', '/api/dns/') 35 | .config(config) 36 | .run(run); 37 | 38 | config.$inject = [ 39 | '$provide', 40 | '$routeProvider', 41 | '$windowProvider' 42 | ]; 43 | 44 | /** 45 | * @name designatedashboard.basePath 46 | * @description Base path for the project dashboard 47 | * 48 | * @param {function} $provide ng provide service 49 | * 50 | * @param {function} $routeProvider ng route service 51 | * 52 | * @param {function} $windowProvider NG window provider 53 | * 54 | * @returns {undefined} 55 | */ 56 | function config($provide, $routeProvider, $windowProvider) { 57 | var path = $windowProvider.$get().STATIC_URL + 'designatedashboard/'; 58 | $provide.constant('designatedashboard.basePath', path); 59 | 60 | $routeProvider 61 | .when('/project/dnszones/', { 62 | templateUrl: path + 'zones.html' 63 | }) 64 | .when('/project/reverse_dns/', { 65 | templateUrl: path + 'reverse_dns.html' 66 | }); 67 | } 68 | 69 | run.$inject = [ 70 | 'horizon.framework.conf.resource-type-registry.service', 71 | 'designatedashboard.basePath' 72 | ]; 73 | 74 | function run() { 75 | // function run(registry, basePath) { 76 | //registry.setDefaultSummaryTemplateUrl(basePath + 'table/default-drawer.html'); 77 | } 78 | 79 | })(); 80 | -------------------------------------------------------------------------------- /designatedashboard/static/designatedashboard/designatedashboard.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/designate-dashboard/e9ce32addfdb257956cce7e6961ef3172f304a22/designatedashboard/static/designatedashboard/designatedashboard.scss -------------------------------------------------------------------------------- /designatedashboard/static/designatedashboard/resources/os-designate-floatingip/actions/actions.module.js: -------------------------------------------------------------------------------- 1 | /** 2 | * (c) Copyright 2016 Hewlett Packard Enterprise Development LP 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | * not use this file except in compliance with the License. You may obtain 6 | * a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | (function() { 18 | 'use strict'; 19 | 20 | /** 21 | * @ngdoc overview 22 | * @ngname designatedashboard.resources.os-designate-floatingip.actions 23 | * 24 | * @description 25 | * Provides all of the actions for DNS Floating IPs. 26 | */ 27 | angular.module('designatedashboard.resources.os-designate-floatingip.actions', [ 28 | 'horizon.framework.conf', 29 | 'horizon.app.core' 30 | ]) 31 | .run(run); 32 | 33 | run.$inject = [ 34 | 'horizon.framework.conf.resource-type-registry.service', 35 | 'designatedashboard.resources.os-designate-floatingip.resourceType', 36 | 'designatedashboard.resources.os-designate-floatingip.actions.set', 37 | 'designatedashboard.resources.os-designate-floatingip.actions.unset' 38 | ]; 39 | 40 | function run(registry, resourceTypeString, setAction, unsetAction) { 41 | var resourceType = registry.getResourceType(resourceTypeString); 42 | 43 | resourceType 44 | .itemActions 45 | .append({ 46 | id: 'setFloatingIp', 47 | service: setAction, 48 | template: { 49 | text: gettext('Set') 50 | } 51 | }) 52 | .append({ 53 | id: 'unsetFloatingIp', 54 | service: unsetAction, 55 | template: { 56 | text: gettext('Unset') 57 | } 58 | }); 59 | } 60 | 61 | })(); 62 | -------------------------------------------------------------------------------- /designatedashboard/static/designatedashboard/resources/os-designate-floatingip/actions/set.service.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * (c) Copyright 2016 Hewlett Packard Enterprise Development Company LP 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 6 | * not use self file except in compliance with the License. You may obtain 7 | * a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | * License for the specific language governing permissions and limitations 15 | * under the License. 16 | */ 17 | 18 | (function () { 19 | 'use strict'; 20 | 21 | angular 22 | .module('designatedashboard.resources.os-designate-floatingip.actions') 23 | .factory('designatedashboard.resources.os-designate-floatingip.actions.set', action); 24 | 25 | action.$inject = [ 26 | '$q', 27 | 'designatedashboard.resources.os-designate-floatingip.api', 28 | 'designatedashboard.resources.os-designate-floatingip.resourceType', 29 | 'designatedashboard.resources.util', 30 | 'horizon.app.core.openstack-service-api.serviceCatalog', 31 | 'horizon.framework.widgets.form.ModalFormService', 32 | 'horizon.framework.widgets.toast.service', 33 | 'horizon.framework.widgets.modal-wait-spinner.service' 34 | ]; 35 | 36 | /* 37 | * @ngDoc factory 38 | * @name designatedashboard.resources.os-designate-floatingip.actions.set 39 | * 40 | * @Description 41 | * Brings up the Set Floating IP modal. 42 | */ 43 | function action($q, 44 | api, 45 | resourceTypeName, 46 | util, 47 | serviceCatalog, 48 | schemaFormModalService, 49 | toast, 50 | waitSpinner) { 51 | var dnsServiceEnabled; 52 | var title = null; // Set once perform is called 53 | var formConfig = { 54 | schema: { 55 | type: "object", 56 | properties: { 57 | ptrdname: { 58 | type: "string", 59 | pattern: /^.+\.$/ 60 | }, 61 | description: { 62 | type: "string" 63 | }, 64 | ttl: { 65 | type: "integer", 66 | minimum: 0, 67 | maximum: 2147483647 68 | } 69 | } 70 | }, 71 | form: [ 72 | { 73 | key: "ptrdname", 74 | title: gettext("Domain Name"), 75 | description: gettext("Domain name ending in '.'"), 76 | validationMessage: gettext("Domain must end with '.'"), 77 | placeholder: "smtp.example.com.", 78 | type: "text", 79 | required: true 80 | }, 81 | { 82 | key: "description", 83 | type: "textarea", 84 | title: gettext("Description"), 85 | description: gettext("Details about the PTR record.") 86 | }, 87 | { 88 | key: "ttl", 89 | title: gettext("TTL"), 90 | description: gettext("Time To Live in seconds."), 91 | type: "number" 92 | } 93 | ] 94 | }; 95 | 96 | var message = { 97 | success: gettext('Domain name PTR %s was successfully set.') 98 | }; 99 | 100 | var service = { 101 | initAction: initAction, 102 | allowed: allowed, 103 | perform: perform 104 | }; 105 | 106 | return service; 107 | 108 | ///////////////// 109 | 110 | function initAction() { 111 | dnsServiceEnabled = serviceCatalog.ifTypeEnabled('dns'); 112 | } 113 | 114 | function allowed(item) { 115 | return $q.all([ 116 | // TODO (tyr) designate currently has no floating ips policy rules 117 | dnsServiceEnabled, 118 | util.notPending(item) 119 | ]); 120 | } 121 | 122 | function perform(item) { 123 | // Initialize the per-item title for use now and during submit 124 | title = gettext("Set Domain Name PTR for ") + item.address; 125 | formConfig.title = title; 126 | 127 | // Get a form model based on the current item 128 | formConfig.model = util.getModel(formConfig.form, item); 129 | 130 | // Initialize default data 131 | formConfig.model.ttl = formConfig.model.ttl || 3600; 132 | 133 | // Remember the ID for use during submit 134 | formConfig.model.floatingIpId = item.id; 135 | 136 | return schemaFormModalService.open(formConfig).then(onSubmit, onCancel); 137 | } 138 | 139 | function onSubmit(context) { 140 | var model = angular.copy(context.model); 141 | var floatingIpId = formConfig.model.floatingIpId; 142 | 143 | waitSpinner.showModalSpinner(title); 144 | return api.set(floatingIpId, model).then(onSuccess, onFailure); 145 | } 146 | 147 | function onCancel() { 148 | waitSpinner.hideModalSpinner(); 149 | } 150 | 151 | function onSuccess(response) { 152 | waitSpinner.hideModalSpinner(); 153 | var floatingIp = response.data; 154 | toast.add('success', interpolate(message.success, [floatingIp.ptrdname])); 155 | 156 | // To make the result of this action generically useful, reformat the return 157 | // from the deleteModal into a standard form 158 | return { 159 | created: [], 160 | updated: [{type: resourceTypeName, id: floatingIp.id}], 161 | deleted: [], 162 | failed: [] 163 | }; 164 | } 165 | 166 | function onFailure() { 167 | waitSpinner.hideModalSpinner(); 168 | } 169 | } 170 | })(); 171 | -------------------------------------------------------------------------------- /designatedashboard/static/designatedashboard/resources/os-designate-floatingip/actions/unset.service.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * (c) Copyright 2016 Hewlett Packard Enterprise Development Company LP 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 6 | * not use self file except in compliance with the License. You may obtain 7 | * a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | * License for the specific language governing permissions and limitations 15 | * under the License. 16 | */ 17 | 18 | (function () { 19 | 'use strict'; 20 | 21 | angular 22 | .module('designatedashboard.resources.os-designate-floatingip.actions') 23 | .factory('designatedashboard.resources.os-designate-floatingip.actions.unset', action); 24 | 25 | action.$inject = [ 26 | '$q', 27 | 'designatedashboard.resources.os-designate-floatingip.api', 28 | 'designatedashboard.resources.os-designate-floatingip.resourceType', 29 | 'designatedashboard.resources.util', 30 | 'horizon.app.core.openstack-service-api.serviceCatalog', 31 | 'horizon.framework.util.q.extensions', 32 | 'horizon.framework.widgets.form.ModalFormService', 33 | 'horizon.framework.widgets.toast.service', 34 | 'horizon.framework.widgets.modal-wait-spinner.service' 35 | ]; 36 | 37 | /* 38 | * @ngDoc factory 39 | * @name designatedashboard.resources.os-designate-floatingip.actions.unset 40 | * 41 | * @Description 42 | * Brings up the Unset Floating IP modal. 43 | */ 44 | function action($q, 45 | api, 46 | resourceTypeName, 47 | util, 48 | serviceCatalog, 49 | $qExtensions, 50 | schemaFormModalService, 51 | toast, 52 | waitSpinner) { 53 | var title = null; // Set on perform 54 | // currentFloatingIpId is used to remember the ID we are modifying since 55 | // it isn't returned by the unset API call 56 | var dnsServiceEnabled, currentFloatingIpId; 57 | 58 | // Unset it just a simple case of "set", but with ptrdname of 'null' 59 | var formConfig = { 60 | schema: { 61 | type: "object", 62 | properties: { 63 | } 64 | }, 65 | form: [ 66 | ], 67 | model: { 68 | } 69 | }; 70 | 71 | var message = { 72 | success: gettext('Domain name PTR successfully unset.') 73 | }; 74 | 75 | var service = { 76 | initAction: initAction, 77 | allowed: allowed, 78 | perform: perform 79 | }; 80 | 81 | return service; 82 | 83 | ///////////////// 84 | 85 | function initAction() { 86 | dnsServiceEnabled = serviceCatalog.ifTypeEnabled('dns'); 87 | } 88 | 89 | function allowed(item) { 90 | return $q.all([ 91 | // TODO (tyr) designate currently has no floating ip policy rules 92 | dnsServiceEnabled, 93 | domainNameSet(item), 94 | util.notPending(item) 95 | ]); 96 | } 97 | 98 | function domainNameSet(item) { 99 | return $qExtensions.booleanAsPromise( 100 | angular.isString(item.ptrdname) 101 | ); 102 | } 103 | 104 | function perform(item) { 105 | title = gettext("Unset Domain Name PTR for ") + item.address; 106 | // Store the zone ID so it can be used on submit 107 | formConfig.model.floatingIpId = item.id; 108 | formConfig.title = title; 109 | return schemaFormModalService.open(formConfig).then(onSubmit, onCancel); 110 | } 111 | 112 | function onSubmit(context) { 113 | waitSpinner.showModalSpinner(title); 114 | currentFloatingIpId = context.model.floatingIpId; 115 | return api.unset(currentFloatingIpId).then(onSuccess, onFailure); 116 | } 117 | 118 | function onCancel() { 119 | waitSpinner.hideModalSpinner(); 120 | } 121 | 122 | function onSuccess() { 123 | waitSpinner.hideModalSpinner(); 124 | toast.add('success', message.success); 125 | 126 | // To make the result of this action generically useful, reformat the return 127 | // from the deleteModal into a standard form 128 | return { 129 | created: [], 130 | updated: [{type: resourceTypeName, id: currentFloatingIpId}], 131 | deleted: [], 132 | failed: [] 133 | }; 134 | } 135 | 136 | function onFailure() { 137 | waitSpinner.hideModalSpinner(); 138 | } 139 | } 140 | })(); 141 | -------------------------------------------------------------------------------- /designatedashboard/static/designatedashboard/resources/os-designate-floatingip/api.service.js: -------------------------------------------------------------------------------- 1 | /** 2 | * (c) Copyright 2016 Hewlett Packard Enterprise Development LP 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | (function () { 17 | 'use strict'; 18 | 19 | angular 20 | .module('designatedashboard.resources.os-designate-floatingip') 21 | .factory('designatedashboard.resources.os-designate-floatingip.api', apiService); 22 | 23 | apiService.$inject = [ 24 | 'designatedashboard.apiPassthroughUrl', 25 | 'horizon.framework.util.http.service', 26 | 'horizon.framework.widgets.toast.service' 27 | ]; 28 | 29 | /* 30 | * @ngdoc service 31 | * @param {Object} httpService 32 | * @param {Object} toastService 33 | * @name apiService 34 | * @description Provides direct access to Designate Floating IP APIs. 35 | * @returns {Object} The service 36 | */ 37 | function apiService(apiPassthroughUrl, httpService, toastService) { 38 | var service = { 39 | list: list, 40 | get: get, 41 | set: set, 42 | unset: unset 43 | }; 44 | 45 | return service; 46 | 47 | /////////////// 48 | 49 | /** 50 | * @name list 51 | * @description 52 | * Get a list of DNS floating ips. 53 | * 54 | * The listing result is an object with property "items." Each item is 55 | * a floating IP PTR record. 56 | * 57 | * @param {Object} params 58 | * Query parameters. Optional. 59 | * 60 | * @returns {Object} The result of the API call 61 | */ 62 | function list(params) { 63 | var config = params ? {params: params} : {}; 64 | return httpService.get(apiPassthroughUrl + 'v2/reverse/floatingips/', config) 65 | .catch(function () { 66 | toastService.add('error', gettext('Unable to retrieve the floating ip PTRs.')); 67 | }); 68 | } 69 | 70 | function get(id, params) { 71 | var config = params ? {params: params} : {}; 72 | return httpService.get(apiPassthroughUrl + 'v2/reverse/floatingips/' + id + '/', config) 73 | .catch(function () { 74 | toastService.add('error', gettext('Unable to get the floating ip PTR ' + id)); 75 | }); 76 | } 77 | 78 | /** 79 | * @name set 80 | * @description 81 | * Set a floating ip PTR record 82 | * 83 | * @param {string} floatingIpID - ID of PTR record to unset 84 | * @param {Object} data 85 | * Specifies the PTR information to set 86 | * 87 | * @returns {Object} The updated DNS floating IP object 88 | */ 89 | function set(floatingIpID, data) { 90 | // The update API will not accept extra data. Restrict the input to only the allowed 91 | // fields 92 | var apiData = { 93 | ptrdname: data.ptrdname, 94 | description: data.description, 95 | ttl: data.ttl 96 | }; 97 | return httpService.patch( 98 | apiPassthroughUrl + 'v2/reverse/floatingips/' + floatingIpID + '/', apiData) 99 | .catch(function () { 100 | toastService.add('error', gettext('Unable to set the floating IP PTR record.')); 101 | }); 102 | } 103 | 104 | /** 105 | * @name unset 106 | * @description 107 | * Unset a floating ip PTR record 108 | * 109 | * @param {string} floatingIpID - ID of PTR record to unset 110 | * 111 | * @returns {Object} The updated DNS floating IP object 112 | */ 113 | function unset(floatingIpID) { 114 | // Unset is just a special case of 'set' 115 | return set(floatingIpID, { 116 | ptrdname: null, 117 | description: null, 118 | ttl: null 119 | }); 120 | } 121 | } 122 | }()); 123 | -------------------------------------------------------------------------------- /designatedashboard/static/designatedashboard/resources/os-designate-floatingip/details/details.module.js: -------------------------------------------------------------------------------- 1 | /** 2 | * (c) Copyright 2016 Hewlett Packard Enterprise Development LP 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | * not use this file except in compliance with the License. You may obtain 6 | * a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | (function() { 18 | 'use strict'; 19 | 20 | /** 21 | * @ngdoc overview 22 | * @ngname designatedashboard.resources.os-designate-floatingip.details 23 | * 24 | * @description 25 | * Provides details features for floating IPs. 26 | */ 27 | angular.module('designatedashboard.resources.os-designate-floatingip.details', 28 | ['horizon.framework.conf', 'horizon.app.core']) 29 | .run(run); 30 | 31 | run.$inject = [ 32 | 'designatedashboard.resources.os-designate-floatingip.resourceType', 33 | 'designatedashboard.resources.os-designate-floatingip.api', 34 | 'designatedashboard.resources.os-designate-floatingip.basePath', 35 | 'horizon.framework.conf.resource-type-registry.service' 36 | ]; 37 | 38 | function run( 39 | resourceTypeName, 40 | api, 41 | basePath, 42 | registry 43 | ) { 44 | var resourceType = registry.getResourceType(resourceTypeName); 45 | resourceType 46 | .setLoadFunction(loadFunction) 47 | .setSummaryTemplateUrl(basePath + 'details/drawer.html') 48 | .setItemNameFunction(itemNameFunction); 49 | 50 | resourceType.detailsViews 51 | .prepend({ 52 | id: 'floatingIpDetailsOverview', 53 | name: gettext('Overview'), 54 | template: basePath + 'details/overview.html' 55 | }, 0); 56 | 57 | function loadFunction(identifier) { 58 | return api.get(identifier); 59 | } 60 | 61 | function itemNameFunction(floatingIp) { 62 | return floatingIp.address; 63 | } 64 | } 65 | 66 | })(); 67 | -------------------------------------------------------------------------------- /designatedashboard/static/designatedashboard/resources/os-designate-floatingip/details/drawer.html: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /designatedashboard/static/designatedashboard/resources/os-designate-floatingip/details/overview.controller.js: -------------------------------------------------------------------------------- 1 | /** 2 | * (c) Copyright 2016 Hewlett Packard Enterprise Development LP 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the 'License'); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an 'AS IS' BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | (function() { 17 | "use strict"; 18 | 19 | angular 20 | .module('designatedashboard.resources.os-designate-floatingip.details') 21 | .controller( 22 | 'designatedashboard.resources.os-designate-floatingip.details.overviewController', 23 | controller); 24 | 25 | controller.$inject = [ 26 | 'designatedashboard.resources.os-designate-floatingip.resourceType', 27 | 'horizon.framework.conf.resource-type-registry.service', 28 | '$scope' 29 | ]; 30 | 31 | function controller( 32 | resourceTypeCode, 33 | registry, 34 | $scope 35 | ) { 36 | var ctrl = this; 37 | 38 | ctrl.item = {}; 39 | ctrl.resourceType = registry.getResourceType(resourceTypeCode); 40 | 41 | $scope.context.loadPromise.then(onGetResponse); 42 | 43 | function onGetResponse(response) { 44 | ctrl.item = response.data; 45 | } 46 | } 47 | 48 | })(); 49 | -------------------------------------------------------------------------------- /designatedashboard/static/designatedashboard/resources/os-designate-floatingip/details/overview.html: -------------------------------------------------------------------------------- 1 |
2 | 10 | 11 |
-------------------------------------------------------------------------------- /designatedashboard/static/designatedashboard/resources/os-designate-floatingip/os-designate-floatingip.module.js: -------------------------------------------------------------------------------- 1 | /** 2 | * (c) Copyright 2016 Hewlett Packard Enterprise Development LP 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | * not use this file except in compliance with the License. You may obtain 6 | * a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | (function() { 18 | 'use strict'; 19 | 20 | /** 21 | * @ngdoc overview 22 | * @ngname designatedashboard.resources.os-designate-floatingip 23 | * 24 | * @description 25 | * Provides all of the services and widgets required 26 | * to support and display DNS (designate) floating ip related content. 27 | */ 28 | angular 29 | .module('designatedashboard.resources.os-designate-floatingip', [ 30 | 'ngRoute', 31 | 'designatedashboard.resources.os-designate-floatingip.actions', 32 | 'designatedashboard.resources.os-designate-floatingip.details' 33 | ]) 34 | .constant( 35 | 'designatedashboard.resources.os-designate-floatingip.resourceType', 36 | 'OS::Designate::FloatingIp') 37 | .config(config) 38 | .run(run); 39 | 40 | config.$inject = [ '$provide', '$windowProvider' ]; 41 | 42 | function config($provide, $windowProvider) { 43 | var path = $windowProvider.$get().STATIC_URL + 44 | 'designatedashboard/resources/os-designate-floatingip/'; 45 | $provide.constant('designatedashboard.resources.os-designate-floatingip.basePath', path); 46 | } 47 | 48 | run.$inject = [ 49 | 'horizon.app.core.detailRoute', 50 | 'horizon.framework.conf.resource-type-registry.service', 51 | 'designatedashboard.resources.os-designate-floatingip.api', 52 | 'designatedashboard.resources.os-designate-floatingip.resourceType', 53 | 'designatedashboard.resources.util' 54 | ]; 55 | 56 | function run(detailRoute, registry, api, resourceTypeString, util) { 57 | var resourceType = registry.getResourceType(resourceTypeString); 58 | resourceType 59 | .setNames(gettext('Floating IP'), gettext('Floating IPs')) 60 | .setDefaultIndexUrl('/project/reverse_dns/') 61 | .setListFunction(listFloatingIps) 62 | .setProperty('id', { 63 | label: gettext('ID') 64 | }) 65 | .setProperty('ptrdname', { 66 | label: gettext('PTR Domain Name'), 67 | filters: ['noName'] 68 | }) 69 | .setProperty('description', { 70 | label: gettext('PTR Description'), 71 | filters: ['noName'] 72 | }) 73 | .setProperty('ttl', { 74 | label: gettext('Time To Live'), 75 | filters: ['noValue'] 76 | }) 77 | .setProperty('address', { 78 | label: gettext('Address'), 79 | filters: ['noName'] 80 | }) 81 | .setProperty('status', { 82 | label: gettext('Status'), 83 | filters: ['lowercase', 'noName'], 84 | values: util.statusMap() 85 | }) 86 | .setProperty('action', { 87 | label: gettext('Action'), 88 | filters: ['lowercase', 'noName'], 89 | values: util.actionMap() 90 | }); 91 | 92 | resourceType 93 | .tableColumns 94 | .append({ 95 | id: 'address', 96 | priority: 1, 97 | sortDefault: true, 98 | template: '{$ item.address $}' 100 | }) 101 | .append({ 102 | id: 'ptrdname', 103 | filters: ['noValue'], 104 | priority: 1 105 | }) 106 | .append({ 107 | id: 'status', 108 | filters: ['lowercase'], 109 | values: util.statusMap(), 110 | priority: 2 111 | }); 112 | 113 | resourceType 114 | .filterFacets 115 | .append({ 116 | label: gettext('Address'), 117 | name: 'address', 118 | isServer: false, 119 | singleton: true, 120 | persistent: false 121 | }) 122 | .append({ 123 | label: gettext('PTR Domain Name'), 124 | name: 'ptrdname', 125 | isServer: false, 126 | singleton: true, 127 | persistent: false 128 | }) 129 | .append({ 130 | label: gettext('Status'), 131 | name: 'status', 132 | isServer: false, 133 | singleton: true, 134 | persistent: false, 135 | options: [ 136 | {label: gettext('Active'), key: 'active'}, 137 | {label: gettext('Pending'), key: 'pending'} 138 | ] 139 | }); 140 | 141 | function listFloatingIps() { 142 | return api.list().then(function onList(response) { 143 | // listFunctions are expected to return data in "items" 144 | response.data.items = response.data.floatingips; 145 | 146 | util.addTimestampIds(response.data.items); 147 | 148 | return response; 149 | }); 150 | } 151 | } 152 | 153 | })(); 154 | -------------------------------------------------------------------------------- /designatedashboard/static/designatedashboard/resources/os-designate-recordset/actions/actions.module.js: -------------------------------------------------------------------------------- 1 | /** 2 | * (c) Copyright 2016 Hewlett Packard Enterprise Development LP 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | * not use this file except in compliance with the License. You may obtain 6 | * a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | (function () { 18 | 'use strict'; 19 | 20 | /** 21 | * @ngdoc overview 22 | * @ngname designatedashboard.resources.os-designate-recordset.actions 23 | * 24 | * @description 25 | * Provides all of the actions for DNS Recordsets. 26 | */ 27 | angular.module('designatedashboard.resources.os-designate-recordset.actions', [ 28 | 'horizon.framework.conf', 29 | 'horizon.app.core' 30 | ]) 31 | .run(run); 32 | 33 | run.$inject = [ 34 | 'horizon.framework.conf.resource-type-registry.service', 35 | 'designatedashboard.resources.os-designate-recordset.resourceType', 36 | 'designatedashboard.resources.os-designate-recordset.actions.create', 37 | 'designatedashboard.resources.os-designate-recordset.actions.delete', 38 | 'designatedashboard.resources.os-designate-recordset.actions.update' 39 | ]; 40 | 41 | function run(registry, 42 | resourceTypeString, 43 | createAction, 44 | deleteAction, 45 | updateAction) { 46 | var resourceType = registry.getResourceType(resourceTypeString); 47 | 48 | resourceType 49 | .itemActions 50 | .append({ 51 | id: 'updateRecordset', 52 | service: updateAction, 53 | template: { 54 | text: gettext('Update') 55 | } 56 | }) 57 | .append({ 58 | id: 'deleteRecordset', 59 | service: deleteAction, 60 | template: { 61 | text: gettext('Delete'), 62 | type: 'delete' 63 | } 64 | }); 65 | 66 | // Append a record set view to the zones actions 67 | var zoneResourceType = registry.getResourceType("OS::Designate::Zone"); 68 | zoneResourceType 69 | .itemActions 70 | .append({ 71 | id: 'createRecordset', 72 | service: createAction, 73 | template: { 74 | text: gettext('Create Record Set') 75 | } 76 | }); 77 | } 78 | 79 | })(); 80 | -------------------------------------------------------------------------------- /designatedashboard/static/designatedashboard/resources/os-designate-recordset/actions/common-forms.service.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * (c) Copyright 2016 Hewlett Packard Enterprise Development Company LP 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 6 | * not use self file except in compliance with the License. You may obtain 7 | * a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | * License for the specific language governing permissions and limitations 15 | * under the License. 16 | */ 17 | 18 | (function () { 19 | 'use strict'; 20 | 21 | angular 22 | .module('designatedashboard.resources.os-designate-recordset.actions') 23 | .factory('designatedashboard.resources.os-designate-recordset.actions.common-forms', service); 24 | 25 | service.$inject = [ 26 | 'designatedashboard.resources.os-designate-recordset.editableTypes', 27 | 'designatedashboard.resources.os-designate-recordset.typeMap' 28 | ]; 29 | 30 | /* 31 | * Service to return a schema form config for action forms. Especially useful for forms 32 | * like create and update that differ only in the readonly state of certain form fields. 33 | * 34 | * @returns {object} A schema form config 35 | */ 36 | function service(editableTypes, typeMap) { 37 | var service = { 38 | getCreateFormConfig: getCreateFormConfig, 39 | getUpdateFormConfig: getUpdateFormConfig 40 | }; 41 | 42 | return service; 43 | 44 | ///////////////// 45 | 46 | /* 47 | * Returns the create form config 48 | * @returns {{schema, form, model}|*} 49 | */ 50 | function getCreateFormConfig() { 51 | return getCreateUpdateFormConfig(false); 52 | } 53 | 54 | /* 55 | * Return the update form config 56 | * @returns {{schema, form, model}|*} 57 | */ 58 | function getUpdateFormConfig() { 59 | return getCreateUpdateFormConfig(true); 60 | } 61 | 62 | /* 63 | * Return the create/update form. The two forms are identical except for 64 | * during update, some fields are read-only. 65 | * 66 | * @param readonly - sets readonly value on form fields that change between update and create 67 | * @returns {object} a schema form config, including default model 68 | */ 69 | function getCreateUpdateFormConfig(readonly) { 70 | return { 71 | schema: { 72 | type: "object", 73 | properties: { 74 | name: { 75 | type: "string", 76 | pattern: /^.+\.$/ 77 | }, 78 | description: { 79 | type: "string" 80 | }, 81 | type: { 82 | type: "string", 83 | enum: editableTypes 84 | }, 85 | ttl: { 86 | type: "integer", 87 | minimum: 1, 88 | maximum: 2147483647 89 | }, 90 | records: { 91 | type: "array", 92 | items: { 93 | type: "object", 94 | properties: { 95 | record: { 96 | type: "string" 97 | } 98 | } 99 | }, 100 | minItems: 1, 101 | uniqueItems: true 102 | } 103 | } 104 | }, 105 | form: [ 106 | { 107 | key: "type", 108 | readonly: readonly, 109 | title: gettext("Type"), 110 | description: gettext("Select the type of record set"), 111 | type: "select", 112 | titleMap: editableTypes.map(function toTitleMap(type) { 113 | return { 114 | value: type, 115 | name: typeMap[type] 116 | }; 117 | }), 118 | required: true 119 | }, 120 | { 121 | key: "name", 122 | readonly: readonly, 123 | type: "text", 124 | title: gettext("Name"), 125 | description: gettext("DNS name for the record set, ending in '.'"), 126 | validationMessage: gettext("DNS name must end with '.'"), 127 | placeholder: "www.example.com.", 128 | required: true 129 | }, 130 | { 131 | key: "description", 132 | type: "textarea", 133 | title: gettext("Description"), 134 | description: gettext("Details about the zone.") 135 | }, 136 | { 137 | key: "ttl", 138 | title: gettext("TTL"), 139 | description: gettext("Time To Live in seconds."), 140 | type: "number", 141 | required: true 142 | }, 143 | { 144 | key: "records", 145 | title: gettext("Records"), 146 | type: "array", 147 | description: gettext("Records for the record set."), 148 | add: gettext("Add Record"), 149 | items: [ 150 | { 151 | key: "records[].record", 152 | title: gettext("Record") 153 | } 154 | ], 155 | required: true 156 | } 157 | ], 158 | model: { 159 | type: "A", 160 | ttl: 3600 161 | } 162 | }; 163 | } 164 | } 165 | })(); 166 | -------------------------------------------------------------------------------- /designatedashboard/static/designatedashboard/resources/os-designate-recordset/actions/create.service.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * (c) Copyright 2016 Hewlett Packard Enterprise Development Company LP 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 6 | * not use self file except in compliance with the License. You may obtain 7 | * a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | * License for the specific language governing permissions and limitations 15 | * under the License. 16 | */ 17 | 18 | (function () { 19 | 'use strict'; 20 | 21 | angular 22 | .module('designatedashboard.resources.os-designate-recordset.actions') 23 | .factory('designatedashboard.resources.os-designate-recordset.actions.create', action); 24 | 25 | action.$inject = [ 26 | '$q', 27 | 'designatedashboard.resources.os-designate-recordset.actions.common-forms', 28 | 'designatedashboard.resources.os-designate-recordset.api', 29 | 'designatedashboard.resources.os-designate-recordset.resourceType', 30 | 'horizon.app.core.openstack-service-api.policy', 31 | 'horizon.app.core.openstack-service-api.serviceCatalog', 32 | 'horizon.framework.conf.resource-type-registry.service', 33 | 'horizon.framework.widgets.form.ModalFormService', 34 | 'horizon.framework.widgets.toast.service', 35 | 'horizon.framework.widgets.modal-wait-spinner.service' 36 | ]; 37 | 38 | /* 39 | * @ngDoc factory 40 | * @name designatedashboard.resources.os-designate-recordset.actions.create 41 | * 42 | * @Description 43 | * Brings up the Create Record Set modal. 44 | */ 45 | function action($q, 46 | forms, 47 | api, 48 | resourceTypeName, 49 | policy, 50 | serviceCatalog, 51 | registry, 52 | schemaFormModalService, 53 | toast, 54 | waitSpinner) { 55 | var createRecordSetPolicy, dnsServiceEnabled; 56 | var title = gettext("Create Record Set"); 57 | var message = { 58 | success: gettext('Record Set %s was successfully created.') 59 | }; 60 | 61 | var service = { 62 | initAction: initAction, 63 | allowed: allowed, 64 | perform: perform 65 | }; 66 | 67 | return service; 68 | 69 | ///////////////// 70 | 71 | function initAction() { 72 | createRecordSetPolicy = policy.ifAllowed({rules: [['dns', 'create_recordset']]}); 73 | dnsServiceEnabled = serviceCatalog.ifTypeEnabled('dns'); 74 | } 75 | 76 | function allowed() { 77 | return $q.all([ 78 | createRecordSetPolicy, 79 | dnsServiceEnabled 80 | ]); 81 | } 82 | 83 | function perform(item) { 84 | var formConfig = forms.getCreateFormConfig(); 85 | 86 | // Store the zone ID so it can be used on submit 87 | formConfig.model.zoneId = item.id; 88 | 89 | formConfig.title = title; 90 | return schemaFormModalService.open(formConfig).then(onSubmit, onCancel); 91 | } 92 | 93 | function onSubmit(context) { 94 | var model = angular.copy(context.model); 95 | var zoneId = model.zoneId; 96 | delete model.zoneId; 97 | 98 | // schema form doesn't appear to support populating arrays directly 99 | // Map the records objects to simple array of records 100 | var records = context.model.records.map(function (item) { 101 | return item.record; 102 | }); 103 | model.records = records; 104 | 105 | waitSpinner.showModalSpinner(gettext('Creating Record Set')); 106 | return api.create(zoneId, model).then(onSuccess, onFailure); 107 | } 108 | 109 | function onCancel() { 110 | waitSpinner.hideModalSpinner(); 111 | } 112 | 113 | function onSuccess(response) { 114 | waitSpinner.hideModalSpinner(); 115 | var zone = response.data; 116 | toast.add('success', interpolate(message.success, [zone.name])); 117 | 118 | // To make the result of this action generically useful, reformat the return 119 | // from the deleteModal into a standard form 120 | return { 121 | created: [{type: resourceTypeName, id: zone.id}], 122 | updated: [], 123 | deleted: [], 124 | failed: [] 125 | }; 126 | } 127 | 128 | function onFailure() { 129 | waitSpinner.hideModalSpinner(); 130 | } 131 | } 132 | })(); 133 | -------------------------------------------------------------------------------- /designatedashboard/static/designatedashboard/resources/os-designate-recordset/actions/delete.service.js: -------------------------------------------------------------------------------- 1 | /** 2 | * (c) Copyright 2016 Hewlett Packard Enterprise Development LP 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | * not use self file except in compliance with the License. You may obtain 6 | * a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | (function() { 18 | 'use strict'; 19 | 20 | angular 21 | .module('designatedashboard.resources.os-designate-recordset.actions') 22 | .factory('designatedashboard.resources.os-designate-recordset.actions.delete', action); 23 | 24 | action.$inject = [ 25 | '$q', 26 | 'designatedashboard.resources.os-designate-recordset.api', 27 | 'designatedashboard.resources.os-designate-recordset.editableTypes', 28 | 'designatedashboard.resources.os-designate-recordset.resourceType', 29 | 'horizon.app.core.openstack-service-api.policy', 30 | 'horizon.framework.util.actions.action-result.service', 31 | 'horizon.framework.util.i18n.gettext', 32 | 'horizon.framework.util.q.extensions', 33 | 'horizon.framework.widgets.modal.deleteModalService', 34 | 'horizon.framework.widgets.toast.service' 35 | ]; 36 | 37 | /* 38 | * @ngdoc factory 39 | * @name designatedashboard.resources.os-designate-recordset.actions.delete 40 | * 41 | * @Description 42 | * Brings up the delete recordset confirmation modal dialog. 43 | 44 | * On submit, delete given recordset. 45 | * On cancel, do nothing. 46 | */ 47 | function action( 48 | $q, 49 | recordsetApi, 50 | editableTypes, 51 | resourceType, 52 | policy, 53 | actionResultService, 54 | gettext, 55 | $qExtensions, 56 | deleteModal, 57 | toast 58 | ) { 59 | var context, deletePromise; 60 | var notAllowedMessage = gettext("You are not allowed to delete record sets: %s"); 61 | var allowedRecordsets = []; 62 | 63 | var service = { 64 | initAction: initAction, 65 | allowed: allowed, 66 | perform: perform 67 | }; 68 | 69 | return service; 70 | 71 | ////////////// 72 | 73 | function initAction() { 74 | context = { }; 75 | deletePromise = policy.ifAllowed({rules: [['dns', 'delete_recordset']]}); 76 | } 77 | 78 | function perform(items, scope) { 79 | var recordsets = angular.isArray(items) ? items : [items]; 80 | context.labels = labelize(recordsets.length); 81 | context.deleteEntity = deleteRecordSet; 82 | return $qExtensions 83 | .allSettled(recordsets.map(checkPermission)) 84 | .then(afterCheck.bind(this, scope)); 85 | } 86 | 87 | function allowed(recordset) { 88 | // only row actions pass in recordset 89 | // otherwise, assume it is a batch action 90 | if (recordset) { 91 | return $q.all([ 92 | deletePromise, 93 | editableRecordType(recordset) 94 | ]); 95 | } else { 96 | return policy.ifAllowed({ rules: [['dns', 'delete_recordset']] }); 97 | } 98 | } 99 | 100 | function checkPermission(recordset) { 101 | return {promise: allowed(recordset), context: recordset}; 102 | } 103 | 104 | function afterCheck(scope, result) { 105 | var outcome = $q.reject().catch(angular.noop); // Reject the promise by default 106 | if (result.fail.length > 0) { 107 | toast.add('error', getMessage(notAllowedMessage, result.fail)); 108 | outcome = $q.reject(result.fail).catch(angular.noop); 109 | } 110 | if (result.pass.length > 0) { 111 | // Remember the record sets we are allowed to delete so that on delete modal submit 112 | // we can map the recordset ID back to the full recordset. Then we can fetch the 113 | // corresponding zone ID 114 | allowedRecordsets = result.pass.map(getEntity); 115 | outcome = deleteModal.open(scope, allowedRecordsets, context).then(createResult); 116 | } 117 | return outcome; 118 | } 119 | 120 | function createResult(deleteModalResult) { 121 | // To make the result of this action generically useful, reformat the return 122 | // from the deleteModal into a standard form 123 | var actionResult = actionResultService.getActionResult(); 124 | deleteModalResult.pass.forEach(function markDeleted(item) { 125 | actionResult.deleted(resourceType, getEntity(item).id); 126 | }); 127 | deleteModalResult.fail.forEach(function markFailed(item) { 128 | actionResult.failed(resourceType, getEntity(item).id); 129 | }); 130 | return actionResult.result; 131 | } 132 | 133 | function labelize(count) { 134 | return { 135 | 136 | title: ngettext( 137 | 'Confirm Delete Record Set', 138 | 'Confirm Delete Record Sets', count), 139 | 140 | message: ngettext( 141 | 'You have selected "%s". Deleted record set is not recoverable.', 142 | 'You have selected "%s". Deleted record sets are not recoverable.', count), 143 | 144 | submit: ngettext( 145 | 'Delete Record Set', 146 | 'Delete Record Sets', count), 147 | 148 | success: ngettext( 149 | 'Deleted Record Set: %s.', 150 | 'Deleted Record Sets: %s.', count), 151 | 152 | error: ngettext( 153 | 'Unable to delete Record Set: %s.', 154 | 'Unable to delete Record Sets: %s.', count) 155 | }; 156 | } 157 | 158 | function editableRecordType(recordset) { 159 | return $qExtensions.booleanAsPromise( 160 | !(recordset.type === 'NS' && recordset.name === recordset.zone_name) && // not apex NS 161 | editableTypes.indexOf(recordset.type) > -1 162 | ); 163 | } 164 | 165 | function deleteRecordSet(recordSetId) { 166 | var recordSet = allowedRecordsets.find(function(element) { 167 | return element.id === recordSetId; 168 | }); 169 | return recordsetApi.deleteRecordSet(recordSet.zone_id, recordSet.id); 170 | } 171 | 172 | function getMessage(message, entities) { 173 | return interpolate(message, [entities.map(getName).join(", ")]); 174 | } 175 | 176 | function getName(result) { 177 | return getEntity(result).name; 178 | } 179 | 180 | function getEntity(result) { 181 | return result.context; 182 | } 183 | } 184 | })(); 185 | -------------------------------------------------------------------------------- /designatedashboard/static/designatedashboard/resources/os-designate-recordset/actions/update.service.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * (c) Copyright 2016 Hewlett Packard Enterprise Development Company LP 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 6 | * not use self file except in compliance with the License. You may obtain 7 | * a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | * License for the specific language governing permissions and limitations 15 | * under the License. 16 | */ 17 | 18 | (function () { 19 | 'use strict'; 20 | 21 | angular 22 | .module('designatedashboard.resources.os-designate-recordset.actions') 23 | .factory('designatedashboard.resources.os-designate-recordset.actions.update', action); 24 | 25 | action.$inject = [ 26 | '$q', 27 | 'designatedashboard.resources.util', 28 | 'designatedashboard.resources.os-designate-recordset.actions.common-forms', 29 | 'designatedashboard.resources.os-designate-recordset.api', 30 | 'designatedashboard.resources.os-designate-recordset.editableTypes', 31 | 'designatedashboard.resources.os-designate-recordset.resourceType', 32 | 'horizon.app.core.openstack-service-api.policy', 33 | 'horizon.app.core.openstack-service-api.serviceCatalog', 34 | 'horizon.framework.util.q.extensions', 35 | 'horizon.framework.widgets.form.ModalFormService', 36 | 'horizon.framework.widgets.toast.service', 37 | 'horizon.framework.widgets.modal-wait-spinner.service' 38 | ]; 39 | 40 | /* 41 | * @ngDoc factory 42 | * @name designatedashboard.resources.os-designate-recordset.actions.update 43 | * 44 | * @Description 45 | * Brings up the Update modal. 46 | */ 47 | function action($q, 48 | util, 49 | forms, 50 | api, 51 | editableTypes, 52 | resourceTypeName, 53 | policy, 54 | serviceCatalog, 55 | $qExtensions, 56 | schemaFormModalService, 57 | toast, 58 | waitSpinner) { 59 | var updateRecordSetPolicy; 60 | var title = gettext("Update Record Set"); 61 | var message = { 62 | success: gettext('Record Set %s was successfully updated.') 63 | }; 64 | 65 | var service = { 66 | initAction: initAction, 67 | allowed: allowed, 68 | perform: perform 69 | }; 70 | 71 | return service; 72 | 73 | ///////////////// 74 | 75 | function initAction() { 76 | updateRecordSetPolicy = policy.ifAllowed({rules: [['dns', 'update_recordset']]}); 77 | } 78 | 79 | function allowed(recordset) { 80 | // only supports row action (exactly 1 recordset) 81 | if (recordset) { 82 | return $q.all([ 83 | updateRecordSetPolicy, 84 | util.notDeleted(recordset), 85 | util.notPending(recordset), 86 | editableRecordType(recordset) 87 | ]); 88 | } else { 89 | return false; 90 | } 91 | } 92 | 93 | function editableRecordType(recordset) { 94 | return $qExtensions.booleanAsPromise( 95 | !(recordset.type === 'NS' && recordset.name === recordset.zone_name) && // not apex NS 96 | editableTypes.indexOf(recordset.type) > -1 97 | ); 98 | } 99 | 100 | function perform(item) { 101 | var formConfig = forms.getUpdateFormConfig(); 102 | formConfig.title = title; 103 | formConfig.model = util.getModel(formConfig.form, item); 104 | 105 | // Append the id and zoneId so it can be used on submit 106 | formConfig.model.id = item.id; 107 | formConfig.model.zoneId = item.zone_id; 108 | 109 | // schema form doesn't appear to support populating the records array directly 110 | // Map the records objects to record objects 111 | if (item.hasOwnProperty("records")) { 112 | var records = item.records.map(function (item) { 113 | return {record: item}; 114 | }); 115 | formConfig.model.records = records; 116 | } 117 | return schemaFormModalService.open(formConfig).then(onSubmit, onCancel); 118 | } 119 | 120 | function onSubmit(context) { 121 | var model = angular.copy(context.model); 122 | // schema form doesn't appear to support populating the records array directly 123 | // Map the records objects to simple array of records 124 | if (context.model.hasOwnProperty("records")) { 125 | var records = context.model.records.map(function (item) { 126 | return item.record; 127 | }); 128 | model.records = records; 129 | } 130 | 131 | waitSpinner.showModalSpinner(gettext('Updating Record Set')); 132 | 133 | return api.update(model.zoneId, model.id, model).then(onSuccess, onFailure); 134 | } 135 | 136 | function onCancel() { 137 | waitSpinner.hideModalSpinner(); 138 | } 139 | 140 | function onSuccess(response) { 141 | waitSpinner.hideModalSpinner(); 142 | var recordset = response.data; 143 | toast.add('success', interpolate(message.success, [recordset.name])); 144 | 145 | // To make the result of this action generically useful, reformat the return 146 | // from the deleteModal into a standard form 147 | return { 148 | created: [], 149 | updated: [{type: resourceTypeName, id: recordset.id}], 150 | deleted: [], 151 | failed: [] 152 | }; 153 | } 154 | 155 | function onFailure() { 156 | waitSpinner.hideModalSpinner(); 157 | } 158 | } 159 | })(); 160 | -------------------------------------------------------------------------------- /designatedashboard/static/designatedashboard/resources/os-designate-recordset/api.service.js: -------------------------------------------------------------------------------- 1 | /** 2 | * (c) Copyright 2016 Hewlett Packard Enterprise Development LP 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | (function () { 17 | 'use strict'; 18 | 19 | angular 20 | .module('designatedashboard.resources.os-designate-recordset') 21 | .factory('designatedashboard.resources.os-designate-recordset.api', apiService); 22 | 23 | apiService.$inject = [ 24 | '$q', 25 | 'designatedashboard.apiPassthroughUrl', 26 | 'horizon.framework.util.http.service', 27 | 'horizon.framework.widgets.toast.service' 28 | ]; 29 | 30 | /* 31 | * @ngdoc service 32 | * @param {Object} httpService 33 | * @param {Object} toastService 34 | * @name apiService 35 | * @description Provides direct access to Designate Record Set APIs. 36 | * @returns {Object} The service 37 | */ 38 | function apiService($q, apiPassthroughUrl, httpService, toastService) { 39 | var service = { 40 | get: get, 41 | list: list, 42 | deleteRecordSet: deleteRecordSet, 43 | create: create, 44 | update: update 45 | }; 46 | 47 | return service; 48 | 49 | /////////////// 50 | 51 | /* 52 | * @name list 53 | * @description 54 | * Get a list of record sets. 55 | * 56 | * The listing result is an object with property "items." Each item is 57 | * a record set. 58 | * 59 | * @param {Object} params 60 | * Query parameters. Optional. 61 | * 62 | * @returns {Object} The result of the API call 63 | */ 64 | function list(zoneId, params) { 65 | return httpService.get(apiPassthroughUrl + 'v2/zones/' + zoneId + '/recordsets/', params) 66 | .catch(function () { 67 | toastService.add('error', gettext('Unable to retrieve the record sets.')); 68 | }); 69 | } 70 | 71 | /* 72 | * @name get 73 | * @description 74 | * Get a single record set by ID. 75 | * 76 | * @param {string} zoneId 77 | * Specifies the id of the zone containing the record set to request. 78 | * 79 | * @param {string} recordSetId 80 | * Specifies the id of the record set to request. 81 | * 82 | * @returns {Object} The result of the API call 83 | */ 84 | function get(zoneId, recordSetId) { 85 | // Unfortunately routed-details-view is not happy when load fails, which is 86 | // common when then delete action removes a record set. Mask this failure by 87 | // always returning a successful promise instead of terminating the $http promise 88 | // in the .error handler. 89 | return httpService.get( 90 | apiPassthroughUrl + 'v2/zones/' + zoneId + '/recordsets/' + recordSetId + '/') 91 | .then(undefined, function onError() { 92 | toastService.add('error', gettext('Unable to retrieve the record set.')); 93 | return $q.when({}); 94 | }); 95 | } 96 | 97 | /* 98 | * @name delete 99 | * @description 100 | * Delete a single record set by ID 101 | * @param {string} zoneId 102 | * The id of the zone containing the recordset 103 | * 104 | * @param {string} recordSetId 105 | * The id of the recordset within the zone 106 | * 107 | * @returns {*} 108 | */ 109 | function deleteRecordSet(zoneId, recordSetId) { 110 | return httpService.delete( 111 | apiPassthroughUrl + 'v2/zones/' + zoneId + '/recordsets/' + recordSetId + '/') 112 | .catch(function () { 113 | toastService.add('error', gettext('Unable to delete the record set.')); 114 | }); 115 | } 116 | 117 | function create(zoneId, data) { 118 | return httpService.post(apiPassthroughUrl + 'v2/zones/' + zoneId + '/recordsets/', data) 119 | .catch(function () { 120 | toastService.add('error', gettext('Unable to create the record set.')); 121 | }); 122 | } 123 | 124 | function update(zoneId, recordSetId, data) { 125 | // The update API will not accept extra data. Restrict the input to only the allowed 126 | // fields 127 | var apiData = { 128 | ttl: data.ttl, 129 | description: data.description, 130 | records: data.records 131 | }; 132 | return httpService.put( 133 | apiPassthroughUrl + 'v2/zones/' + zoneId + '/recordsets/' + recordSetId + '/', apiData) 134 | .catch(function () { 135 | toastService.add('error', gettext('Unable to update the record set.')); 136 | }); 137 | } 138 | } 139 | }()); 140 | -------------------------------------------------------------------------------- /designatedashboard/static/designatedashboard/resources/os-designate-recordset/details/details.module.js: -------------------------------------------------------------------------------- 1 | /** 2 | * (c) Copyright 2016 Hewlett Packard Enterprise Development LP 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | * not use this file except in compliance with the License. You may obtain 6 | * a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | (function() { 18 | 'use strict'; 19 | 20 | /** 21 | * @ngdoc overview 22 | * @ngname designatedashboard.resources.os-designate-recordset.details 23 | * 24 | * @description 25 | * Provides details features for record sets. 26 | */ 27 | angular.module('designatedashboard.resources.os-designate-recordset.details', 28 | ['horizon.framework.conf', 'horizon.app.core']) 29 | .run(run); 30 | 31 | run.$inject = [ 32 | 'designatedashboard.resources.os-designate-recordset.resourceType', 33 | 'designatedashboard.resources.os-designate-recordset.api', 34 | 'designatedashboard.resources.os-designate-recordset.basePath', 35 | 'horizon.framework.conf.resource-type-registry.service' 36 | ]; 37 | 38 | function run( 39 | recordSetResourceType, 40 | recordSetApi, 41 | basePath, 42 | registry 43 | ) { 44 | var resourceType = registry.getResourceType(recordSetResourceType); 45 | resourceType 46 | .setLoadFunction(loadFunction) 47 | .setPathGenerator(pathGenerator) 48 | .setPathParser(pathParser) 49 | .setSummaryTemplateUrl(basePath + 'details/drawer.html'); 50 | 51 | /* 52 | * 53 | * @param identifier 54 | * The object returned by the pathParser containing the zone ID and record set ID to load 55 | */ 56 | function loadFunction(identifier) { 57 | return recordSetApi.get(identifier.zoneId, identifier.recordSetId); 58 | } 59 | 60 | /* 61 | * Because a record set is contained by a zone, we implement a custom 62 | * pathGenerator to encode the zone ID and record set ID for the generic 63 | * details panel. 64 | * 65 | * @param item 66 | * A record set 67 | * 68 | * @returns {string} In format "/" 69 | */ 70 | function pathGenerator(item) { 71 | return item.zone_id + '/' + item.id; 72 | } 73 | 74 | /* 75 | * Given a path, extract the zone and record set ids 76 | * 77 | * @param path 78 | * created by pathGenerator 79 | * 80 | * @returns {{zoneId: *, recordSetId: *}} 81 | * The identifier to pass to the load function needed to uniquely identify 82 | * a record set. 83 | */ 84 | function pathParser(path) { 85 | var split = path.split('/'); 86 | return { 87 | zoneId: split[0], 88 | recordSetId: split[1] 89 | }; 90 | } 91 | 92 | resourceType.detailsViews 93 | .prepend({ 94 | id: 'recordsetDetailsOverview', 95 | name: gettext('Overview'), 96 | template: basePath + 'details/overview.html' 97 | }, 0); 98 | 99 | // Append a record set view to the zones resource view 100 | var zoneResourceType = registry.getResourceType("OS::Designate::Zone"); 101 | zoneResourceType.detailsViews 102 | .append({ 103 | id: 'zoneRecordSets', 104 | name: gettext('Record Sets'), 105 | template: basePath + 'details/zone-recordsets.html' 106 | }); 107 | } 108 | 109 | })(); 110 | -------------------------------------------------------------------------------- /designatedashboard/static/designatedashboard/resources/os-designate-recordset/details/drawer.html: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /designatedashboard/static/designatedashboard/resources/os-designate-recordset/details/overview.controller.js: -------------------------------------------------------------------------------- 1 | /** 2 | * (c) Copyright 2016 Hewlett Packard Enterprise Development LP 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the 'License'); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an 'AS IS' BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | (function() { 17 | "use strict"; 18 | 19 | angular 20 | .module('designatedashboard.resources.os-designate-recordset') 21 | .controller('designatedashboard.resources.os-designate-recordset.detailController', controller); 22 | 23 | controller.$inject = [ 24 | 'designatedashboard.resources.os-designate-recordset.resourceType', 25 | 'horizon.framework.conf.resource-type-registry.service', 26 | '$scope' 27 | ]; 28 | 29 | function controller( 30 | resourceTypeCode, 31 | registry, 32 | $scope 33 | ) { 34 | var ctrl = this; 35 | 36 | ctrl.item = {}; 37 | ctrl.resourceType = registry.getResourceType(resourceTypeCode); 38 | 39 | $scope.context.loadPromise.then(onGetResponse); 40 | 41 | function onGetResponse(response) { 42 | ctrl.item = response.data; 43 | } 44 | } 45 | 46 | })(); 47 | -------------------------------------------------------------------------------- /designatedashboard/static/designatedashboard/resources/os-designate-recordset/details/overview.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |

Details

5 |
6 | 14 | 15 |
16 |
17 |

Associations

18 |
19 | 27 | 28 |
29 |
30 |
31 |
32 |

Modification Times

33 |
34 | 42 | 43 |
44 |
45 |
46 | -------------------------------------------------------------------------------- /designatedashboard/static/designatedashboard/resources/os-designate-recordset/details/zone-recordsets.controller.js: -------------------------------------------------------------------------------- 1 | /** 2 | * (c) Copyright 2016 Hewlett Packard Enterprise Development LP 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the 'License'); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an 'AS IS' BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | (function() { 17 | "use strict"; 18 | 19 | angular 20 | .module('designatedashboard.resources.os-designate-recordset') 21 | .controller( 22 | 'designatedashboard.resources.os-designate-recordset.zoneRecordSetsController', 23 | controller); 24 | 25 | controller.$inject = [ 26 | '$scope', 27 | 'designatedashboard.resources.os-designate-recordset.resourceType' 28 | ]; 29 | 30 | function controller( 31 | $scope, 32 | resourceTypeName 33 | ) { 34 | var ctrl = this; 35 | 36 | ctrl.item = {}; 37 | ctrl.resourceTypeName = resourceTypeName; 38 | ctrl.extraListParams = { zoneId: $scope.context.identifier }; 39 | } 40 | 41 | })(); 42 | -------------------------------------------------------------------------------- /designatedashboard/static/designatedashboard/resources/os-designate-recordset/details/zone-recordsets.html: -------------------------------------------------------------------------------- 1 |
3 | 7 | 8 |
-------------------------------------------------------------------------------- /designatedashboard/static/designatedashboard/resources/os-designate-recordset/os-designate-recordset.module.js: -------------------------------------------------------------------------------- 1 | /** 2 | * (c) Copyright 2016 Hewlett Packard Enterprise Development LP 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | * not use this file except in compliance with the License. You may obtain 6 | * a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | (function () { 18 | 'use strict'; 19 | 20 | /** 21 | * @ngdoc overview 22 | * @ngname designatedashboard.resources.os-designate-recordset 23 | * 24 | * @description 25 | * Provides all of the services and widgets required 26 | * to support and display DNS (designate) record set related content. 27 | */ 28 | angular 29 | .module('designatedashboard.resources.os-designate-recordset', [ 30 | 'ngRoute', 31 | 'designatedashboard.resources.os-designate-recordset.actions', 32 | 'designatedashboard.resources.os-designate-recordset.details' 33 | ]) 34 | .constant( 35 | 'designatedashboard.resources.os-designate-recordset.resourceType', 36 | 'OS::Designate::RecordSet') 37 | .constant( 38 | 'designatedashboard.resources.os-designate-recordset.typeMap', 39 | { 40 | A: gettext('A - Address record'), 41 | AAAA: gettext('AAAA - IPv6 address record'), 42 | CNAME: gettext('CNAME - Canonical name record'), 43 | MX: gettext('MX - Mail exchange record'), 44 | PTR: gettext('PTR - Pointer record'), 45 | SPF: gettext('SPF - Sender Policy Framework'), 46 | SRV: gettext('SRV - Service locator'), 47 | SSHFP: gettext('SSHFP - SSH Public Key Fingerprint'), 48 | TXT: gettext('TXT - Text record'), 49 | SOA: gettext('SOA - Start of authority record'), 50 | NS: gettext('NS - Name server'), 51 | CAA: gettext('CAA - Certificate Authority Authorization record') 52 | }) 53 | .constant( 54 | 'designatedashboard.resources.os-designate-recordset.editableTypes', 55 | [ 56 | "A", 57 | "AAAA", 58 | "CNAME", 59 | "MX", 60 | "NS", 61 | "PTR", 62 | "SPF", 63 | "SRV", 64 | "SSHFP", 65 | "TXT", 66 | "CAA" 67 | ]) 68 | .config(config) 69 | .run(run); 70 | 71 | config.$inject = ['$provide', '$windowProvider']; 72 | 73 | function config($provide, $windowProvider) { 74 | var path = $windowProvider.$get().STATIC_URL + 75 | 'designatedashboard/resources/os-designate-recordset/'; 76 | $provide.constant('designatedashboard.resources.os-designate-recordset.basePath', path); 77 | } 78 | 79 | run.$inject = [ 80 | 'horizon.app.core.detailRoute', 81 | 'horizon.framework.conf.resource-type-registry.service', 82 | 'designatedashboard.resources.os-designate-recordset.api', 83 | 'designatedashboard.resources.os-designate-recordset.resourceType', 84 | 'designatedashboard.resources.os-designate-recordset.typeMap', 85 | 'designatedashboard.resources.util' 86 | ]; 87 | 88 | function run(detailRoute, 89 | registry, 90 | recordSetApi, 91 | resourceTypeString, 92 | typeMap, 93 | util) { 94 | var resourceType = registry.getResourceType(resourceTypeString); 95 | resourceType 96 | .setNames(gettext('DNS Record Set'), gettext('DNS Record Sets')) 97 | .setDefaultIndexUrl('/project/dnszones/') 98 | .setListFunction(list) 99 | .setProperty('id', { 100 | label: gettext('ID') 101 | }) 102 | .setProperty('zone_id', { 103 | label: gettext('Zone ID'), 104 | filters: ['noValue'] 105 | }) 106 | .setProperty('zone_name', { 107 | label: gettext('Zone Name'), 108 | filters: ['noName'] 109 | }) 110 | .setProperty('project_id', { 111 | label: gettext('Project ID'), 112 | filters: ['noValue'] 113 | }) 114 | .setProperty('name', { 115 | label: gettext('Name'), 116 | filters: ['noName'] 117 | }) 118 | .setProperty('description', { 119 | label: gettext('Description'), 120 | filters: ['noName'] 121 | }) 122 | .setProperty('type', { 123 | label: gettext('Type'), 124 | filters: ['uppercase'], 125 | values: typeMap 126 | }) 127 | .setProperty('ttl', { 128 | label: gettext('Time To Live'), 129 | filters: ['noValue'] 130 | }) 131 | .setProperty('records', { 132 | label: gettext('Records'), 133 | filters: ['noValue'] 134 | }) 135 | .setProperty('notes', { 136 | label: gettext('Notes'), 137 | filters: ['noName'] 138 | }) 139 | .setProperty('status', { 140 | label: gettext('Status'), 141 | filters: ['lowercase', 'noName'], 142 | values: util.statusMap() 143 | }) 144 | .setProperty('action', { 145 | label: gettext('Action'), 146 | filters: ['lowercase', 'noName'], 147 | values: util.actionMap() 148 | }) 149 | .setProperty('version', { 150 | label: gettext('Version'), 151 | filters: ['noValue'] 152 | }) 153 | .setProperty('created_at', { 154 | label: gettext('Created At'), 155 | filters: ['noValue'] 156 | }) 157 | .setProperty('updated_at', { 158 | label: gettext('Updated At'), 159 | filters: ['noValue'] 160 | }); 161 | 162 | resourceType 163 | .tableColumns 164 | .append({ 165 | id: 'name', 166 | priority: 1, 167 | sortDefault: true, 168 | filters: ['noName'], 169 | // For link format, see pathGenerator in details.module.js 170 | template: '{$ item.name $}' 173 | }) 174 | .append({ 175 | id: 'type', 176 | priority: 2, 177 | filters: ['uppercase'], 178 | values: typeMap 179 | }) 180 | .append({ 181 | id: 'records', 182 | priority: 2, 183 | filters: ['noValue'] 184 | }) 185 | .append({ 186 | id: 'status', 187 | filters: ['lowercase'], 188 | values: util.statusMap(), 189 | priority: 2 190 | }); 191 | 192 | resourceType 193 | .filterFacets 194 | .append({ 195 | label: gettext('Type'), 196 | name: 'type', 197 | isServer: false, 198 | singleton: true, 199 | persistent: false, 200 | options: Object.keys(typeMap).map(function toOptionLabel(key) { 201 | return { 202 | label: typeMap[key], 203 | key: key 204 | }; 205 | }) 206 | }) 207 | .append({ 208 | label: gettext('Name'), 209 | name: 'name', 210 | isServer: false, 211 | singleton: true, 212 | persistent: false 213 | }) 214 | .append({ 215 | label: gettext('Status'), 216 | name: 'status', 217 | isServer: false, 218 | singleton: true, 219 | persistent: false, 220 | options: [ 221 | {label: gettext('Active'), key: 'active'}, 222 | {label: gettext('Pending'), key: 'pending'} 223 | ] 224 | }); 225 | 226 | /* 227 | * list all recordsets within a zone. Requires "zoneId" in the params. All other 228 | * params will be passed unmodified as URL params to the API. 229 | * 230 | * @param params 231 | * zoneId (required) list recordsets within the zone 232 | * 233 | * @returns {*|Object} 234 | */ 235 | function list(params) { 236 | return recordSetApi.list(params.zoneId, params).then(function onList(response) { 237 | // listFunctions are expected to return data in "items" 238 | response.data.items = response.data.recordsets; 239 | 240 | util.addTimestampIds(response.data.items); 241 | 242 | return response; 243 | }); 244 | } 245 | } 246 | 247 | })(); 248 | -------------------------------------------------------------------------------- /designatedashboard/static/designatedashboard/resources/os-designate-zone/actions/actions.module.js: -------------------------------------------------------------------------------- 1 | /** 2 | * (c) Copyright 2016 Hewlett Packard Enterprise Development LP 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | * not use this file except in compliance with the License. You may obtain 6 | * a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | (function () { 18 | 'use strict'; 19 | 20 | /** 21 | * @ngdoc overview 22 | * @ngname designatedashboard.resources.os-designate-zone.actions 23 | * 24 | * @description 25 | * Provides all of the actions for DNS Zones. 26 | */ 27 | angular.module('designatedashboard.resources.os-designate-zone.actions', [ 28 | 'horizon.framework.conf', 29 | 'horizon.app.core' 30 | ]) 31 | .run(run); 32 | 33 | run.$inject = [ 34 | 'horizon.framework.conf.resource-type-registry.service', 35 | 'designatedashboard.resources.os-designate-zone.resourceType', 36 | 'designatedashboard.resources.os-designate-zone.actions.create', 37 | 'designatedashboard.resources.os-designate-zone.actions.delete', 38 | 'designatedashboard.resources.os-designate-zone.actions.update' 39 | ]; 40 | 41 | function run(registry, 42 | resourceTypeString, 43 | createAction, 44 | deleteAction, 45 | updateAction) { 46 | var resourceType = registry.getResourceType(resourceTypeString); 47 | resourceType 48 | .globalActions 49 | .append({ 50 | id: 'create', 51 | service: createAction, 52 | template: { 53 | text: gettext('Create Zone') 54 | } 55 | }); 56 | 57 | resourceType 58 | .itemActions 59 | .append({ 60 | id: 'update', 61 | service: updateAction, 62 | template: { 63 | text: gettext('Update') 64 | } 65 | }) 66 | .append({ 67 | id: 'delete', 68 | service: deleteAction, 69 | template: { 70 | text: gettext('Delete'), 71 | type: 'delete' 72 | } 73 | }); 74 | } 75 | 76 | })(); 77 | -------------------------------------------------------------------------------- /designatedashboard/static/designatedashboard/resources/os-designate-zone/actions/actions.module.spec.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 4 | * not use this file except in compliance with the License. You may obtain 5 | * a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | * License for the specific language governing permissions and limitations 13 | * under the License. 14 | */ 15 | 16 | (function() { 17 | 'use strict'; 18 | 19 | describe('zone actions module', function() { 20 | var registry; 21 | beforeEach(module('designatedashboard')); 22 | 23 | beforeEach(inject(function($injector) { 24 | registry = $injector.get('horizon.framework.conf.resource-type-registry.service'); 25 | })); 26 | 27 | it('registers Create Zone as a global action', function() { 28 | var actions = registry.getResourceType('OS::Designate::Zone').globalActions; 29 | expect(actionHasId(actions, 'create')).toBe(true); 30 | }); 31 | 32 | it('registers Update Zone as a item action', function() { 33 | var actions = registry.getResourceType('OS::Designate::Zone').itemActions; 34 | expect(actionHasId(actions, 'update')).toBe(true); 35 | }); 36 | 37 | function actionHasId(list, value) { 38 | return list.filter(matchesId).length === 1; 39 | 40 | function matchesId(action) { 41 | if (action.id === value) { 42 | return true; 43 | } 44 | } 45 | } 46 | 47 | }); 48 | 49 | })(); 50 | -------------------------------------------------------------------------------- /designatedashboard/static/designatedashboard/resources/os-designate-zone/actions/common-forms.service.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * (c) Copyright 2016 Hewlett Packard Enterprise Development Company LP 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 6 | * not use self file except in compliance with the License. You may obtain 7 | * a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | * License for the specific language governing permissions and limitations 15 | * under the License. 16 | */ 17 | 18 | (function () { 19 | 'use strict'; 20 | 21 | angular 22 | .module('designatedashboard.resources.os-designate-zone.actions') 23 | .factory('designatedashboard.resources.os-designate-zone.actions.common-forms', service); 24 | 25 | service.$inject = [ 26 | ]; 27 | 28 | /** 29 | * Service to return a schema form config for action forms. Especially useful for forms 30 | * like create and update that differ only in the readonly state of certain form fields. 31 | * 32 | * @returns {object} A schema form config 33 | */ 34 | function service() { 35 | var service = { 36 | getCreateFormConfig: getCreateFormConfig, 37 | getUpdateFormConfig: getUpdateFormConfig 38 | }; 39 | 40 | return service; 41 | 42 | ///////////////// 43 | 44 | /* 45 | * Returns the create zone form config 46 | * @returns {{schema, form, model}|*} 47 | */ 48 | function getCreateFormConfig() { 49 | return getCreateUpdateFormConfig(false); 50 | } 51 | 52 | /* 53 | * Return the update zone form config 54 | * @returns {{schema, form, model}|*} 55 | */ 56 | function getUpdateFormConfig() { 57 | return getCreateUpdateFormConfig(true); 58 | } 59 | 60 | /* 61 | * Return the create/update zone form. The two forms are identical except for 62 | * during update, some fields are read-only. 63 | * 64 | * @param readonly - sets readonly value on form fields that change between update and create 65 | * @returns {object} a schema form config, including default model 66 | */ 67 | function getCreateUpdateFormConfig(readonly) { 68 | return { 69 | schema: { 70 | type: "object", 71 | properties: { 72 | name: { 73 | type: "string", 74 | pattern: /^.+\.$/ 75 | }, 76 | description: { 77 | type: "string" 78 | }, 79 | email: { 80 | type: "string", 81 | format: "email", 82 | pattern: /^[^@]+@[^@]+$/ 83 | }, 84 | type: { 85 | type: "string", 86 | enum: [ 87 | "PRIMARY", 88 | "SECONDARY" 89 | ] 90 | }, 91 | ttl: { 92 | type: "integer", 93 | minimum: 1, 94 | maximum: 2147483647 95 | }, 96 | masters: { 97 | type: "array", 98 | items: { 99 | type: "object", 100 | properties: { 101 | address: { 102 | type: "string" 103 | } 104 | } 105 | }, 106 | minItems: 1, 107 | uniqueItems: true 108 | } 109 | } 110 | }, 111 | form: [ 112 | { 113 | key: "name", 114 | readonly: readonly, 115 | title: gettext("Name"), 116 | description: gettext("Zone name ending in '.'"), 117 | validationMessage: gettext("Zone must end with '.'"), 118 | placeholder: "example.com.", 119 | type: "text", 120 | required: true 121 | }, 122 | { 123 | key: "description", 124 | type: "textarea", 125 | title: gettext("Description"), 126 | description: gettext("Details about the zone.") 127 | }, 128 | { 129 | key: "email", 130 | title: gettext("Email Address"), 131 | description: gettext("Email address to contact the zone owner."), 132 | validationMessage: gettext("Email address must contain a single '@' character"), 133 | type: "text", 134 | condition: "model.type == 'PRIMARY'", 135 | required: true 136 | }, 137 | { 138 | key: "ttl", 139 | title: gettext("TTL"), 140 | description: gettext("Time To Live in seconds."), 141 | type: "number", 142 | condition: "model.type == 'PRIMARY'", 143 | required: true 144 | }, 145 | { 146 | key: "type", 147 | readonly: readonly, 148 | title: gettext("Type"), 149 | description: gettext("Select the type of zone"), 150 | type: "select", 151 | titleMap: [ 152 | { 153 | value: "PRIMARY", 154 | name: gettext("Primary") 155 | }, 156 | { 157 | value: "SECONDARY", 158 | name: gettext("Secondary") 159 | } 160 | ] 161 | }, 162 | { 163 | key: "masters", 164 | readonly: readonly, 165 | title: gettext("Masters"), 166 | type: "array", 167 | description: gettext("DNS master(s) for the Secondary zone."), 168 | condition: "model.type == 'SECONDARY'", 169 | add: gettext("Add Master"), 170 | items: [ 171 | { 172 | key: "masters[].address", 173 | title: gettext("IP Address") 174 | } 175 | ] 176 | } 177 | ], 178 | model: { 179 | type: "PRIMARY", 180 | ttl: 3600 181 | } 182 | }; 183 | } 184 | } 185 | })(); 186 | -------------------------------------------------------------------------------- /designatedashboard/static/designatedashboard/resources/os-designate-zone/actions/create.html: -------------------------------------------------------------------------------- 1 |

CREATE TEMPLATE

-------------------------------------------------------------------------------- /designatedashboard/static/designatedashboard/resources/os-designate-zone/actions/create.service.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * (c) Copyright 2016 Hewlett Packard Enterprise Development Company LP 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 6 | * not use self file except in compliance with the License. You may obtain 7 | * a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | * License for the specific language governing permissions and limitations 15 | * under the License. 16 | */ 17 | 18 | (function () { 19 | 'use strict'; 20 | 21 | angular 22 | .module('designatedashboard.resources.os-designate-zone.actions') 23 | .factory('designatedashboard.resources.os-designate-zone.actions.create', action); 24 | 25 | action.$inject = [ 26 | '$q', 27 | 'designatedashboard.resources.os-designate-zone.actions.common-forms', 28 | 'designatedashboard.resources.os-designate-zone.api', 29 | 'designatedashboard.resources.os-designate-zone.resourceType', 30 | 'horizon.app.core.openstack-service-api.policy', 31 | 'horizon.app.core.openstack-service-api.serviceCatalog', 32 | 'horizon.framework.widgets.form.ModalFormService', 33 | 'horizon.framework.widgets.toast.service', 34 | 'horizon.framework.widgets.modal-wait-spinner.service' 35 | ]; 36 | 37 | /* 38 | * @ngDoc factory 39 | * @name designatedashboard.resources.os-designate-zone.actions.create 40 | * 41 | * @Description 42 | * Brings up the Create Zone modal. 43 | */ 44 | function action($q, 45 | forms, 46 | api, 47 | resourceTypeName, 48 | policy, 49 | serviceCatalog, 50 | schemaFormModalService, 51 | toast, 52 | waitSpinner) { 53 | var createZonePolicy, dnsServiceEnabled; 54 | var title = gettext("Create Zone"); 55 | var message = { 56 | success: gettext('Zone %s was successfully created.') 57 | }; 58 | 59 | var service = { 60 | initAction: initAction, 61 | allowed: allowed, 62 | perform: perform 63 | }; 64 | 65 | return service; 66 | 67 | ///////////////// 68 | 69 | function initAction() { 70 | createZonePolicy = policy.ifAllowed({rules: [['dns', 'create_zone']]}); 71 | dnsServiceEnabled = serviceCatalog.ifTypeEnabled('dns'); 72 | } 73 | 74 | function allowed() { 75 | return $q.all([ 76 | createZonePolicy, 77 | dnsServiceEnabled 78 | ]); 79 | } 80 | 81 | function perform() { 82 | var formConfig = forms.getCreateFormConfig(); 83 | formConfig.title = title; 84 | return schemaFormModalService.open(formConfig).then(onSubmit, onCancel); 85 | } 86 | 87 | function onSubmit(context) { 88 | var zoneModel = angular.copy(context.model); 89 | // schema form doesn't appear to support populating the masters array directly 90 | // Map the masters objects to simple array of addresses 91 | if (context.model.hasOwnProperty("masters")) { 92 | var masters = context.model.masters.map(function (item) { 93 | return item.address; 94 | }); 95 | zoneModel.masters = masters; 96 | } 97 | 98 | waitSpinner.showModalSpinner(gettext('Creating Zone')); 99 | 100 | return api.create(zoneModel).then(onSuccess, onFailure); 101 | } 102 | 103 | function onCancel() { 104 | waitSpinner.hideModalSpinner(); 105 | } 106 | 107 | function onSuccess(response) { 108 | waitSpinner.hideModalSpinner(); 109 | var zone = response.data; 110 | toast.add('success', interpolate(message.success, [zone.name])); 111 | 112 | // To make the result of this action generically useful, reformat the return 113 | // from the deleteModal into a standard form 114 | return { 115 | created: [{type: resourceTypeName, id: zone.id}], 116 | updated: [], 117 | deleted: [], 118 | failed: [] 119 | }; 120 | } 121 | 122 | function onFailure() { 123 | waitSpinner.hideModalSpinner(); 124 | } 125 | } 126 | })(); 127 | -------------------------------------------------------------------------------- /designatedashboard/static/designatedashboard/resources/os-designate-zone/actions/delete.service.js: -------------------------------------------------------------------------------- 1 | /** 2 | * (c) Copyright 2016 Hewlett Packard Enterprise Development LP 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | * not use self file except in compliance with the License. You may obtain 6 | * a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | (function() { 18 | 'use strict'; 19 | 20 | angular 21 | .module('designatedashboard.resources.os-designate-zone.actions') 22 | .factory('designatedashboard.resources.os-designate-zone.actions.delete', action); 23 | 24 | action.$inject = [ 25 | '$q', 26 | 'designatedashboard.resources.os-designate-zone.api', 27 | 'designatedashboard.resources.util', 28 | 'horizon.app.core.openstack-service-api.policy', 29 | 'horizon.framework.util.actions.action-result.service', 30 | 'horizon.framework.util.i18n.gettext', 31 | 'horizon.framework.util.q.extensions', 32 | 'horizon.framework.widgets.modal.deleteModalService', 33 | 'horizon.framework.widgets.toast.service', 34 | 'designatedashboard.resources.os-designate-zone.resourceType' 35 | ]; 36 | 37 | /* 38 | * @ngdoc factory 39 | * @name designatedashboard.resources.os-designate-zone.actions.delete 40 | * 41 | * @Description 42 | * Brings up the delete zone confirmation modal dialog. 43 | 44 | * On submit, delete given zone. 45 | * On cancel, do nothing. 46 | */ 47 | function action( 48 | $q, 49 | zoneApi, 50 | util, 51 | policy, 52 | actionResultService, 53 | gettext, 54 | $qExtensions, 55 | deleteModal, 56 | toast, 57 | resourceType 58 | ) { 59 | var context, deleteZonePromise; 60 | var notAllowedMessage = gettext("You are not allowed to delete zones: %s"); 61 | 62 | var service = { 63 | initAction: initAction, 64 | allowed: allowed, 65 | perform: perform 66 | }; 67 | 68 | return service; 69 | 70 | ////////////// 71 | 72 | function initAction() { 73 | context = { }; 74 | deleteZonePromise = policy.ifAllowed({rules: [['dns', 'delete_zone']]}); 75 | } 76 | 77 | function perform(items, scope) { 78 | var zones = angular.isArray(items) ? items : [items]; 79 | context.labels = labelize(zones.length); 80 | context.deleteEntity = deleteZone; 81 | return $qExtensions 82 | .allSettled(zones.map(checkPermission)) 83 | .then( 84 | afterCheck.bind(this, scope) 85 | ); 86 | } 87 | 88 | function allowed(zone) { 89 | // only row actions pass in zone 90 | // otherwise, assume it is a batch action 91 | if (zone) { 92 | return $q.all([ 93 | deleteZonePromise, 94 | util.notDeleted(zone), 95 | util.notPending(zone) 96 | ]); 97 | } else { 98 | return policy.ifAllowed({ rules: [['dns', 'delete_zone']] }); 99 | } 100 | } 101 | 102 | function checkPermission(zone) { 103 | return {promise: allowed(zone), context: zone}; 104 | } 105 | 106 | function afterCheck(scope, result) { 107 | var outcome = $q.reject().catch(angular.noop); // Reject the promise by default 108 | if (result.fail.length > 0) { 109 | toast.add('error', getMessage(notAllowedMessage, result.fail)); 110 | outcome = $q.reject(result.fail).catch(angular.noop); 111 | } 112 | if (result.pass.length > 0) { 113 | outcome = deleteModal.open(scope, result.pass.map(getEntity), context).then(createResult); 114 | } 115 | return outcome; 116 | } 117 | 118 | function createResult(deleteModalResult) { 119 | // To make the result of this action generically useful, reformat the return 120 | // from the deleteModal into a standard form 121 | var actionResult = actionResultService.getActionResult(); 122 | deleteModalResult.pass.forEach(function markDeleted(item) { 123 | actionResult.deleted(resourceType, getEntity(item).id); 124 | }); 125 | deleteModalResult.fail.forEach(function markFailed(item) { 126 | actionResult.failed(resourceType, getEntity(item).id); 127 | }); 128 | return actionResult.result; 129 | } 130 | 131 | function labelize(count) { 132 | return { 133 | 134 | title: ngettext( 135 | 'Confirm Delete Zone', 136 | 'Confirm Delete Zones', count), 137 | 138 | message: ngettext( 139 | 'You have selected "%s". Deleted zone is not recoverable.', 140 | 'You have selected "%s". Deleted zones are not recoverable.', count), 141 | 142 | submit: ngettext( 143 | 'Delete Zone', 144 | 'Delete Zones', count), 145 | 146 | success: ngettext( 147 | 'Deleted Zone: %s.', 148 | 'Deleted Zones: %s.', count), 149 | 150 | error: ngettext( 151 | 'Unable to delete Zone: %s.', 152 | 'Unable to delete Zones: %s.', count) 153 | }; 154 | } 155 | 156 | function deleteZone(zone) { 157 | return zoneApi.deleteZone(zone, true); 158 | } 159 | 160 | function getMessage(message, entities) { 161 | return interpolate(message, [entities.map(getName).join(", ")]); 162 | } 163 | 164 | function getName(result) { 165 | return getEntity(result).name; 166 | } 167 | 168 | function getEntity(result) { 169 | return result.context; 170 | } 171 | } 172 | })(); 173 | -------------------------------------------------------------------------------- /designatedashboard/static/designatedashboard/resources/os-designate-zone/actions/update.service.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * (c) Copyright 2016 Hewlett Packard Enterprise Development Company LP 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 6 | * not use self file except in compliance with the License. You may obtain 7 | * a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | * License for the specific language governing permissions and limitations 15 | * under the License. 16 | */ 17 | 18 | (function () { 19 | 'use strict'; 20 | 21 | angular 22 | .module('designatedashboard.resources.os-designate-zone.actions') 23 | .factory('designatedashboard.resources.os-designate-zone.actions.update', action); 24 | 25 | action.$inject = [ 26 | '$q', 27 | 'designatedashboard.resources.os-designate-zone.actions.common-forms', 28 | 'designatedashboard.resources.os-designate-zone.api', 29 | 'designatedashboard.resources.os-designate-zone.resourceType', 30 | 'designatedashboard.resources.util', 31 | 'horizon.app.core.openstack-service-api.policy', 32 | 'horizon.app.core.openstack-service-api.serviceCatalog', 33 | 'horizon.framework.widgets.form.ModalFormService', 34 | 'horizon.framework.widgets.toast.service', 35 | 'horizon.framework.widgets.modal-wait-spinner.service' 36 | ]; 37 | 38 | /* 39 | * @ngDoc factory 40 | * @name designatedashboard.resources.os-designate-zone.actions.update 41 | * 42 | * @Description 43 | * Brings up the Update Zone modal. 44 | */ 45 | function action($q, 46 | forms, 47 | api, 48 | resourceTypeName, 49 | util, 50 | policy, 51 | serviceCatalog, 52 | schemaFormModalService, 53 | toast, 54 | waitSpinner) { 55 | var updateZonePolicy; 56 | var title = gettext("Update Zone"); 57 | var message = { 58 | success: gettext('Zone %s was successfully updated.') 59 | }; 60 | 61 | var service = { 62 | initAction: initAction, 63 | allowed: allowed, 64 | perform: perform 65 | }; 66 | 67 | return service; 68 | 69 | ///////////////// 70 | 71 | function initAction() { 72 | updateZonePolicy = policy.ifAllowed({rules: [['dns', 'update_zone']]}); 73 | } 74 | 75 | function allowed(zone) { 76 | // only supports row action (exactly 1 zone) 77 | if (zone) { 78 | return $q.all([ 79 | updateZonePolicy, 80 | util.notDeleted(zone), 81 | util.notPending(zone) 82 | ]); 83 | } else { 84 | return false; 85 | } 86 | } 87 | 88 | function perform(item) { 89 | var formConfig = forms.getUpdateFormConfig(); 90 | formConfig.title = title; 91 | formConfig.model = util.getModel(formConfig.form, item); 92 | 93 | // Append the id so it can be used on submit 94 | formConfig.model.id = item.id; 95 | 96 | // schema form doesn't appear to support populating the masters array directly 97 | // Map the masters objects to address objects 98 | if (item.hasOwnProperty("masters")) { 99 | var masters = item.masters.map(function (item) { 100 | return { address: item }; 101 | }); 102 | formConfig.model.masters = masters; 103 | } 104 | return schemaFormModalService.open(formConfig).then(onSubmit, onCancel); 105 | } 106 | 107 | function onSubmit(context) { 108 | var zoneModel = angular.copy(context.model); 109 | // schema form doesn't appear to support populating the masters array directly 110 | // Map the masters objects to simple array of addresses 111 | if (context.model.hasOwnProperty("masters")) { 112 | var masters = context.model.masters.map(function (item) { 113 | return item.address; 114 | }); 115 | zoneModel.masters = masters; 116 | } 117 | 118 | waitSpinner.showModalSpinner(gettext('Updating Zone')); 119 | 120 | return api.update(zoneModel.id, zoneModel).then(onSuccess, onFailure); 121 | } 122 | 123 | function onCancel() { 124 | waitSpinner.hideModalSpinner(); 125 | } 126 | 127 | function onSuccess(response) { 128 | waitSpinner.hideModalSpinner(); 129 | var zone = response.data; 130 | toast.add('success', interpolate(message.success, [zone.name])); 131 | 132 | // To make the result of this action generically useful, reformat the return 133 | // from the deleteModal into a standard form 134 | return { 135 | created: [], 136 | updated: [{type: resourceTypeName, id: zone.id}], 137 | deleted: [], 138 | failed: [] 139 | }; 140 | } 141 | 142 | function onFailure() { 143 | waitSpinner.hideModalSpinner(); 144 | } 145 | } 146 | })(); 147 | -------------------------------------------------------------------------------- /designatedashboard/static/designatedashboard/resources/os-designate-zone/api.service.js: -------------------------------------------------------------------------------- 1 | /** 2 | * (c) Copyright 2016 Hewlett Packard Enterprise Development LP 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | (function () { 17 | 'use strict'; 18 | 19 | angular 20 | .module('designatedashboard.resources.os-designate-zone') 21 | .factory('designatedashboard.resources.os-designate-zone.api', apiService); 22 | 23 | apiService.$inject = [ 24 | 'designatedashboard.apiPassthroughUrl', 25 | 'horizon.framework.util.http.service', 26 | 'horizon.framework.widgets.toast.service' 27 | ]; 28 | 29 | /* 30 | * @ngdoc service 31 | * @param {Object} httpService 32 | * @param {Object} toastService 33 | * @name apiService 34 | * @description Provides direct access to Designate Zone APIs. 35 | * @returns {Object} The service 36 | */ 37 | function apiService(apiPassthroughUrl, httpService, toastService) { 38 | var service = { 39 | get: get, 40 | list: list, 41 | deleteZone: deleteZone, 42 | create: create, 43 | update: update 44 | }; 45 | 46 | return service; 47 | 48 | /////////////// 49 | 50 | /** 51 | * @name list 52 | * @description 53 | * Get a list of zones. 54 | * 55 | * The listing result is an object with property "items." Each item is 56 | * a zone. 57 | * 58 | * @param {Object} params 59 | * Query parameters. Optional. 60 | * 61 | * @returns {Object} The result of the API call 62 | */ 63 | /* 64 | function list(params) { 65 | var config = params ? {'params': params} : {}; 66 | return httpService.get('/api/designate/zones/', config) 67 | .catch(function () { 68 | toastService.add('error', gettext('Unable to retrieve the zone.')); 69 | }); 70 | }*/ 71 | function list(params) { 72 | var config = params ? {params: params} : {}; 73 | return httpService.get(apiPassthroughUrl + 'v2/zones/', config) 74 | .catch(function () { 75 | toastService.add('error', gettext('Unable to retrieve the zone.')); 76 | }); 77 | } 78 | 79 | /** 80 | * @name get 81 | * @description 82 | * Get a single zone by ID. 83 | * 84 | * @param {string} id 85 | * Specifies the id of the zone to request. 86 | * 87 | * @returns {Object} The result of the API call 88 | */ 89 | function get(id) { 90 | return httpService.get(apiPassthroughUrl + 'v2/zones/' + id + '/') 91 | .catch(function () { 92 | toastService.add('error', gettext('Unable to retrieve the zone.')); 93 | }); 94 | } 95 | 96 | /* 97 | * @name deleteZone 98 | * @description 99 | * Delete a single zone by ID 100 | * @param id 101 | * @returns {*} 102 | */ 103 | function deleteZone(id) { 104 | return httpService.delete(apiPassthroughUrl + 'v2/zones/' + id + '/') 105 | .catch(function () { 106 | toastService.add('error', gettext('Unable to delete the zone.')); 107 | }); 108 | } 109 | 110 | /** 111 | * @name create 112 | * @description 113 | * Create a zone 114 | * 115 | * @param {Object} data 116 | * Specifies the zone information to create 117 | * 118 | * @returns {Object} The created zone object 119 | */ 120 | function create(data) { 121 | return httpService.post(apiPassthroughUrl + 'v2/zones/', data) 122 | .catch(function() { 123 | toastService.add('error', gettext('Unable to create the zone.')); 124 | }); 125 | } 126 | 127 | /** 128 | * @name create 129 | * @description 130 | * Update a zone 131 | * 132 | * @param {Object} id - zone id 133 | * @param {Object} data to pass directly to zone update API 134 | * Specifies the zone information to update 135 | * 136 | * @returns {Object} The updated zone object 137 | */ 138 | function update(id, data) { 139 | // The update API will not accept extra data. Restrict the input to only the allowed 140 | // fields 141 | var apiData = { 142 | email: data.email, 143 | ttl: data.ttl, 144 | description: data.description 145 | }; 146 | return httpService.patch(apiPassthroughUrl + 'v2/zones/' + id + '/', apiData) 147 | .catch(function() { 148 | toastService.add('error', gettext('Unable to update the zone.')); 149 | }); 150 | } 151 | } 152 | }()); 153 | -------------------------------------------------------------------------------- /designatedashboard/static/designatedashboard/resources/os-designate-zone/details/details.module.js: -------------------------------------------------------------------------------- 1 | /** 2 | * (c) Copyright 2016 Hewlett Packard Enterprise Development LP 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | * not use this file except in compliance with the License. You may obtain 6 | * a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | (function() { 18 | 'use strict'; 19 | 20 | /** 21 | * @ngdoc overview 22 | * @ngname designatedashboard.resources.os-designate-zone.details 23 | * 24 | * @description 25 | * Provides details features for zones. 26 | */ 27 | angular.module('designatedashboard.resources.os-designate-zone.details', 28 | ['horizon.framework.conf', 'horizon.app.core']) 29 | .run(run); 30 | 31 | run.$inject = [ 32 | 'designatedashboard.resources.os-designate-zone.resourceType', 33 | 'designatedashboard.resources.os-designate-zone.api', 34 | 'designatedashboard.resources.os-designate-zone.basePath', 35 | 'horizon.framework.conf.resource-type-registry.service' 36 | ]; 37 | 38 | function run( 39 | zoneResourceType, 40 | zoneApi, 41 | basePath, 42 | registry 43 | ) { 44 | var resourceType = registry.getResourceType(zoneResourceType); 45 | resourceType 46 | .setLoadFunction(loadFunction) 47 | .setSummaryTemplateUrl(basePath + 'details/drawer.html'); 48 | 49 | resourceType.detailsViews 50 | .prepend({ 51 | id: 'zoneDetailsOverview', 52 | name: gettext('Overview'), 53 | template: basePath + 'details/overview.html' 54 | }, 0); 55 | 56 | function loadFunction(identifier) { 57 | return zoneApi.get(identifier); 58 | } 59 | } 60 | 61 | })(); 62 | -------------------------------------------------------------------------------- /designatedashboard/static/designatedashboard/resources/os-designate-zone/details/drawer.html: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /designatedashboard/static/designatedashboard/resources/os-designate-zone/details/overview.controller.js: -------------------------------------------------------------------------------- 1 | /** 2 | * (c) Copyright 2016 Hewlett Packard Enterprise Development LP 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the 'License'); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an 'AS IS' BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | (function() { 17 | "use strict"; 18 | 19 | angular 20 | .module('designatedashboard.resources.os-designate-zone') 21 | .controller('designatedashboard.resources.os-designate-zone.detailController', controller); 22 | 23 | controller.$inject = [ 24 | 'designatedashboard.resources.os-designate-zone.resourceType', 25 | 'horizon.framework.conf.resource-type-registry.service', 26 | '$scope' 27 | ]; 28 | 29 | function controller( 30 | resourceTypeCode, 31 | registry, 32 | $scope 33 | ) { 34 | var ctrl = this; 35 | 36 | ctrl.item = {}; 37 | ctrl.resourceType = registry.getResourceType(resourceTypeCode); 38 | 39 | $scope.context.loadPromise.then(onGetResponse); 40 | 41 | function onGetResponse(response) { 42 | ctrl.item = response.data; 43 | 44 | var attr = ''; 45 | var keys = Object.keys(response.data.attributes); 46 | 47 | for (var i = keys.length - 1; i >= 0; i--) { 48 | attr += keys[i] + ':' + response.data.attributes[keys[i]] + ', '; 49 | } 50 | 51 | ctrl.item.attributes = attr; 52 | } 53 | } 54 | 55 | })(); 56 | -------------------------------------------------------------------------------- /designatedashboard/static/designatedashboard/resources/os-designate-zone/details/overview.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |

Details

5 |
6 | 14 | 15 |
16 |
17 |

Attributes

18 |
19 | 27 | 28 |
29 |
30 |
31 |
32 |

Modification Times

33 |
34 | 42 | 43 |
44 |
45 |

Associations

46 |
47 | 55 | 56 |
57 |
58 |
59 | -------------------------------------------------------------------------------- /designatedashboard/static/designatedashboard/resources/os-designate-zone/os-designate-zone.module.js: -------------------------------------------------------------------------------- 1 | /** 2 | * (c) Copyright 2016 Hewlett Packard Enterprise Development LP 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | * not use this file except in compliance with the License. You may obtain 6 | * a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | (function () { 18 | 'use strict'; 19 | 20 | /** 21 | * @ngdoc overview 22 | * @ngname designatedashboard.resources.os-designate-zone 23 | * 24 | * @description 25 | * Provides all of the services and widgets required 26 | * to support and display DNS (designate) zone related content. 27 | */ 28 | angular 29 | .module('designatedashboard.resources.os-designate-zone', [ 30 | 'ngRoute', 31 | 'designatedashboard.resources.os-designate-zone.actions', 32 | 'designatedashboard.resources.os-designate-zone.details' 33 | ]) 34 | .constant( 35 | 'designatedashboard.resources.os-designate-zone.resourceType', 36 | 'OS::Designate::Zone') 37 | .config(config) 38 | .run(run); 39 | 40 | config.$inject = ['$provide', '$windowProvider']; 41 | 42 | function config($provide, $windowProvider) { 43 | var path = $windowProvider.$get().STATIC_URL + 44 | 'designatedashboard/resources/os-designate-zone/'; 45 | $provide.constant('designatedashboard.resources.os-designate-zone.basePath', path); 46 | } 47 | 48 | run.$inject = [ 49 | 'horizon.app.core.detailRoute', 50 | 'horizon.framework.conf.resource-type-registry.service', 51 | 'designatedashboard.resources.os-designate-zone.api', 52 | 'designatedashboard.resources.os-designate-zone.resourceType', 53 | 'designatedashboard.resources.util' 54 | ]; 55 | 56 | function run(detailRoute, 57 | registry, 58 | zoneApi, 59 | resourceTypeString, 60 | util) { 61 | var resourceType = registry.getResourceType(resourceTypeString); 62 | resourceType 63 | .setNames(gettext('DNS Zone'), gettext('DNS Zones')) 64 | .setDefaultIndexUrl('/project/dnszones/') 65 | .setListFunction(listZones) 66 | .setProperty('action', { 67 | label: gettext('Action'), 68 | filters: ['lowercase', 'noName'], 69 | values: util.actionMap() 70 | }) 71 | .setProperty('attributes', { 72 | label: gettext('Attributes') 73 | }) 74 | .setProperty('created_at', { 75 | label: gettext('Created At'), 76 | filters: ['noValue'] 77 | }) 78 | .setProperty('description', { 79 | label: gettext('Description'), 80 | filters: ['noName'] 81 | }) 82 | .setProperty('email', { 83 | label: gettext('Email'), 84 | filters: ['noName'] 85 | }) 86 | .setProperty('id', { 87 | label: gettext('ID') 88 | }) 89 | .setProperty('masters', { 90 | label: gettext('Masters'), 91 | filters: ['noValue'] 92 | }) 93 | .setProperty('name', { 94 | label: gettext('Name'), 95 | filters: ['noName'] 96 | }) 97 | .setProperty('pool_id', { 98 | label: gettext('Pool ID') 99 | }) 100 | .setProperty('project_id', { 101 | label: gettext('Project ID') 102 | }) 103 | .setProperty('serial', { 104 | label: gettext('Serial'), 105 | filters: ['noValue'] 106 | }) 107 | .setProperty('status', { 108 | label: gettext('Status'), 109 | filters: ['lowercase', 'noName'], 110 | values: util.statusMap() 111 | }) 112 | .setProperty('transferred_at', { 113 | label: gettext('Transferred At'), 114 | filters: ['noValue'] 115 | }) 116 | .setProperty('ttl', { 117 | label: gettext('Time To Live'), 118 | filters: ['noValue'] 119 | }) 120 | .setProperty('type', { 121 | label: gettext('Type'), 122 | filters: ['lowercase', 'noName'], 123 | values: typeMap() 124 | }) 125 | .setProperty('updated_at', { 126 | label: gettext('Updated At'), 127 | filters: ['noValue'] 128 | }) 129 | .setProperty('version', { 130 | label: gettext('Version'), 131 | filters: ['noValue'] 132 | }); 133 | 134 | resourceType 135 | .tableColumns 136 | .append({ 137 | id: 'name', 138 | priority: 1, 139 | sortDefault: true, 140 | template: '{$ item.name $}' 142 | }) 143 | .append({ 144 | id: 'type', 145 | filters: ['lowercase'], 146 | values: typeMap(), 147 | priority: 2 148 | }) 149 | .append({ 150 | id: 'status', 151 | filters: ['lowercase'], 152 | values: util.statusMap(), 153 | priority: 2 154 | }); 155 | 156 | resourceType 157 | .filterFacets 158 | .append({ 159 | label: gettext('Name'), 160 | name: 'name', 161 | isServer: false, 162 | singleton: true, 163 | persistent: false 164 | }) 165 | .append({ 166 | label: gettext('Type'), 167 | name: 'type', 168 | isServer: false, 169 | singleton: true, 170 | persistent: false, 171 | options: [ 172 | {label: gettext('Primary'), key: 'primary'}, 173 | {label: gettext('Secondary'), key: 'secondary'} 174 | ] 175 | }) 176 | .append({ 177 | label: gettext('Status'), 178 | name: 'status', 179 | isServer: false, 180 | singleton: true, 181 | persistent: false, 182 | options: [ 183 | {label: gettext('Active'), key: 'active'}, 184 | {label: gettext('Pending'), key: 'pending'} 185 | ] 186 | }); 187 | 188 | function typeMap() { 189 | return { 190 | primary: gettext('Primary'), 191 | secondary: gettext('Secondary') 192 | }; 193 | } 194 | 195 | function listZones() { 196 | return zoneApi.list().then(function onList(response) { 197 | // listFunctions are expected to return data in "items" 198 | response.data.items = response.data.zones; 199 | 200 | util.addTimestampIds(response.data.items, 'id', 'updated_at'); 201 | 202 | return response; 203 | }); 204 | } 205 | } 206 | 207 | })(); 208 | -------------------------------------------------------------------------------- /designatedashboard/static/designatedashboard/resources/resources.module.js: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) Copyright 2016 Hewlett-Packard Development Company, L.P. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | (function () { 17 | 'use strict'; 18 | 19 | /** 20 | * @ngdoc overview 21 | * @name designatedashboard.resources 22 | * @description 23 | * 24 | * # designatedashboard.resources 25 | * 26 | * This module hosts registered resource types. This module file may 27 | * contain individual registrations, or may have sub-modules that 28 | * more fully contain registrations. 29 | */ 30 | angular 31 | .module('designatedashboard.resources', [ 32 | 'designatedashboard.resources.os-designate-recordset', 33 | 'designatedashboard.resources.os-designate-zone', 34 | 'designatedashboard.resources.os-designate-floatingip' 35 | ]); 36 | })(); 37 | -------------------------------------------------------------------------------- /designatedashboard/static/designatedashboard/resources/util.service.js: -------------------------------------------------------------------------------- 1 | /** 2 | * (c) Copyright 2016 Hewlett Packard Enterprise Development LP 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | (function () { 17 | 'use strict'; 18 | 19 | angular 20 | .module('designatedashboard.resources') 21 | .factory('designatedashboard.resources.util', utilService); 22 | 23 | utilService.$inject = [ 24 | 'horizon.framework.util.q.extensions' 25 | ]; 26 | 27 | function utilService($qExtensions) { 28 | var service = { 29 | notDeleted: notDeleted, 30 | notPending: notPending, 31 | getModel: getModel, 32 | actionMap: actionMap, 33 | statusMap: statusMap, 34 | addTimestampIds: addTimestampIds 35 | }; 36 | 37 | return service; 38 | 39 | /////////////// 40 | 41 | function notDeleted(resource) { 42 | return $qExtensions.booleanAsPromise(resource.status !== 'DELETED'); 43 | } 44 | 45 | function notPending(resource) { 46 | return $qExtensions.booleanAsPromise(resource.status !== 'PENDING'); 47 | } 48 | 49 | /* 50 | * Build a model object based on the given item, using only the fields 51 | * present in the form config 'key's. Only 'truthy' values are copied. 52 | * 53 | * @param form - an array of objects describing the form. Must have a 'key' attribute. 54 | * @param item - the data to copy into the model 55 | */ 56 | function getModel(form, item) { 57 | var result = {}; 58 | var value; 59 | form.forEach(function iterateForm(formItem) { 60 | value = item[formItem.key]; 61 | if (value) { 62 | result[formItem.key] = item[formItem.key]; 63 | } 64 | }); 65 | return result; 66 | } 67 | 68 | function actionMap() { 69 | return { 70 | none: gettext('None'), 71 | create: gettext('Create') 72 | }; 73 | } 74 | 75 | function statusMap() { 76 | return { 77 | active: gettext('Active'), 78 | pending: gettext('Pending') 79 | }; 80 | } 81 | 82 | /* 83 | * hz-resource-table tracks by 'id' which doesn't change when an individual item is updated. 84 | * Create a synthetic '_timestampId' using the item id plus the specified timestamp field. 85 | * When this field is used as a track-by in hz-resource-table, items in the table to update 86 | * after row actions. 87 | * 88 | * If a timestamp field is not specified, the current time is used. 89 | * 90 | * @param items {object} - The items to add a _timestampId. 91 | * @param idField {string} - (Optional) A field on the item to use as the id. Defaults to 'id' 92 | * @param timestampField {string} - (Optional) A field on item to use as a timestamp. Defaults 93 | * to current time. 94 | */ 95 | function addTimestampIds(items, idField, timestampField) { 96 | var _idField = idField || 'id'; 97 | var timestamp = Date.now(); 98 | items.map(function annotateFloatingIp(item) { 99 | if (angular.isDefined(timestampField)) { 100 | timestamp = item[timestampField]; 101 | } 102 | item._timestampId = item[_idField] + timestamp; 103 | }); 104 | } 105 | } 106 | }()); 107 | -------------------------------------------------------------------------------- /designatedashboard/static/designatedashboard/reverse_dns.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /designatedashboard/static/designatedashboard/zones.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /designatedashboard/tests/.secret_key_store: -------------------------------------------------------------------------------- 1 | 5NMb6ZfXYBLClFGFYf6VkbiJ9TRNyU3w8NQHPG8LXJltU8EZFeB7I632vQ8MF5m6 -------------------------------------------------------------------------------- /designatedashboard/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/designate-dashboard/e9ce32addfdb257956cce7e6961ef3172f304a22/designatedashboard/tests/__init__.py -------------------------------------------------------------------------------- /designatedashboard/tests/base.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Copyright 2010-2011 OpenStack Foundation 4 | # Copyright (c) 2013 Hewlett-Packard Development Company, L.P. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 7 | # not use this file except in compliance with the License. You may obtain 8 | # a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 14 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 15 | # License for the specific language governing permissions and limitations 16 | # under the License. 17 | 18 | import os 19 | 20 | import fixtures 21 | import testtools 22 | 23 | 24 | _TRUE_VALUES = ('True', 'true', '1', 'yes') 25 | 26 | 27 | class TestCase(testtools.TestCase): 28 | 29 | """Test case base class for all unit tests.""" 30 | 31 | def setUp(self): 32 | """Run before each test method to initialize test environment.""" 33 | 34 | super(TestCase, self).setUp() 35 | test_timeout = os.environ.get('OS_TEST_TIMEOUT', 0) 36 | try: 37 | test_timeout = int(test_timeout) 38 | except ValueError: 39 | # If timeout value is invalid do not set a timeout. 40 | test_timeout = 0 41 | if test_timeout > 0: 42 | self.useFixture(fixtures.Timeout(test_timeout, gentle=True)) 43 | 44 | self.useFixture(fixtures.NestedTempfile()) 45 | self.useFixture(fixtures.TempHomeDir()) 46 | 47 | if os.environ.get('OS_STDOUT_CAPTURE') in _TRUE_VALUES: 48 | stdout = self.useFixture(fixtures.StringStream('stdout')).stream 49 | self.useFixture(fixtures.MonkeyPatch('sys.stdout', stdout)) 50 | if os.environ.get('OS_STDERR_CAPTURE') in _TRUE_VALUES: 51 | stderr = self.useFixture(fixtures.StringStream('stderr')).stream 52 | self.useFixture(fixtures.MonkeyPatch('sys.stderr', stderr)) 53 | 54 | self.log_fixture = self.useFixture(fixtures.FakeLogger()) 55 | -------------------------------------------------------------------------------- /designatedashboard/tests/settings.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 Hewlett-Packard Development Company, L.P. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 4 | # not use this file except in compliance with the License. You may obtain 5 | # a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | # License for the specific language governing permissions and limitations 13 | # under the License. 14 | 15 | # Default to Horizons test settings to avoid any missing keys 16 | 17 | import openstack_dashboard.enabled # noqa: F811 18 | from openstack_dashboard.test.settings import * # noqa: F403,H303 19 | from openstack_dashboard.utils import settings 20 | 21 | import designatedashboard.enabled 22 | 23 | # pop these keys to avoid log warnings about deprecation 24 | # update_dashboards will populate them anyway 25 | HORIZON_CONFIG.pop('dashboards', None) 26 | HORIZON_CONFIG.pop('default_dashboard', None) 27 | 28 | # Update the dashboards with designatedashboard enabled files 29 | # and current INSTALLED_APPS 30 | settings.update_dashboards( 31 | [ 32 | openstack_dashboard.enabled, 33 | designatedashboard.enabled, 34 | ], 35 | HORIZON_CONFIG, 36 | INSTALLED_APPS 37 | ) 38 | 39 | # Remove duplicated apps 40 | INSTALLED_APPS = list(set(INSTALLED_APPS)) 41 | -------------------------------------------------------------------------------- /doc/requirements.txt: -------------------------------------------------------------------------------- 1 | sphinxcontrib-svg2pdfconverter>=1.2.3 # BSD 2 | openstackdocstheme>=3.5.0 # Apache-2.0 3 | reno>=4.1.0 # Apache-2.0 4 | -------------------------------------------------------------------------------- /doc/source/conf.py: -------------------------------------------------------------------------------- 1 | # Licensed under the Apache License, Version 2.0 (the "License"); 2 | # you may not use this file except in compliance with the License. 3 | # You may obtain a copy of the License at 4 | # 5 | # http://www.apache.org/licenses/LICENSE-2.0 6 | # 7 | # Unless reqdashboardred by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 10 | # implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License. 13 | 14 | import os 15 | import sys 16 | 17 | sys.path.insert(0, os.path.abspath('../..')) 18 | # -- General configuration ---------------------------------------------------- 19 | 20 | # Add any Sphinx extension module names here, as strings. They can be 21 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. 22 | extensions = [ 23 | 'sphinx.ext.autodoc', 24 | #'sphinx.ext.intersphinx', 25 | 'openstackdocstheme', 26 | 'sphinxcontrib.rsvgconverter', 27 | ] 28 | 29 | # openstackdocstheme options 30 | openstackdocs_repo_name = 'openstack/designate-dashboard' 31 | openstackdocs_pdf_link = True 32 | openstackdocs_bug_project = 'designate-dashboard' 33 | openstackdocs_bug_tag = '' 34 | html_theme = 'openstackdocs' 35 | 36 | # autodoc generation is a bit aggressive and a ndashboardsance when doing heavy 37 | # text edit cycles. 38 | # execute "export SPHINX_DEBUG=1" in your terminal to disable 39 | 40 | # The suffix of source filenames. 41 | source_suffix = '.rst' 42 | 43 | # The master toctree document. 44 | master_doc = 'index' 45 | 46 | # General information about the project. 47 | project = 'designate_dashboard' 48 | copyright = '2013, OpenStack Foundation' 49 | 50 | # If true, '()' will be appended to :func: etc. cross-reference text. 51 | add_function_parentheses = True 52 | 53 | # If true, the current module name will be prepended to all description 54 | # unit titles (such as .. function::). 55 | add_module_names = True 56 | 57 | # The name of the Pygments (syntax highlighting) style to use. 58 | pygments_style = 'native' 59 | 60 | # -- Options for HTML output -------------------------------------------------- 61 | 62 | # The theme to use for HTML and HTML Help pages. Major themes that come with 63 | # Sphinx are currently 'default' and 'sphinxdoc'. 64 | # html_theme_path = ["."] 65 | # html_theme = '_theme' 66 | # html_static_path = ['static'] 67 | 68 | # Output file base name for HTML help bdashboardlder. 69 | htmlhelp_basename = '%sdoc' % project 70 | 71 | # Grouping the document tree into LaTeX files. List of tuples 72 | # (source start file, target name, title, author, documentclass 73 | # [howto/manual]). 74 | latex_documents = [ 75 | ('index', 76 | 'doc-designate-dashboard.tex', 77 | 'Designate Dashboard Documentation', 78 | 'OpenStack Foundation', 'manual', True), 79 | ] 80 | 81 | latex_domain_indices = False 82 | 83 | latex_elements = { 84 | # Additional stuff for the LaTeX preamble. 85 | # openany: Skip blank pages in generated PDFs 86 | 'extraclassoptions': 'openany,oneside', 87 | 'makeindex': '', 88 | 'printindex': '', 89 | 'preamble': r'\setcounter{tocdepth}{3}', 90 | } 91 | 92 | # Example configuration for intersphinx: refer to the Python standard library. 93 | #intersphinx_mapping = {'https://docs.python.org/': None} 94 | -------------------------------------------------------------------------------- /doc/source/contributor/index.rst: -------------------------------------------------------------------------------- 1 | ============ 2 | Contributing 3 | ============ 4 | 5 | .. include:: ../../../CONTRIBUTING.rst 6 | -------------------------------------------------------------------------------- /doc/source/index.rst: -------------------------------------------------------------------------------- 1 | ============================================= 2 | Welcome to Designate Dashboard Documentation 3 | ============================================= 4 | 5 | .. toctree:: 6 | :maxdepth: 2 7 | 8 | install/index 9 | user/index 10 | contributor/index 11 | 12 | .. rubric:: Indices and tables 13 | 14 | * :ref:`genindex` 15 | * :ref:`search` 16 | -------------------------------------------------------------------------------- /doc/source/install/index.rst: -------------------------------------------------------------------------------- 1 | ============ 2 | Installation 3 | ============ 4 | 5 | At the command line:: 6 | 7 | $ pip install designate_dashboard 8 | 9 | Or, if you have virtualenvwrapper installed:: 10 | 11 | $ mkvirtualenv designate_dashboard 12 | $ pip install designate_dashboard -------------------------------------------------------------------------------- /doc/source/user/index.rst: -------------------------------------------------------------------------------- 1 | ======== 2 | Usage 3 | ======== 4 | 5 | To use designate_dashboard in a project:: 6 | 7 | import designate_dashboard -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the 'License'); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an 'AS IS' BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | 'use strict'; 17 | 18 | var fs = require('fs'); 19 | var path = require('path'); 20 | 21 | module.exports = function (config) { 22 | // This tox venv is setup in the post-install npm step 23 | var toxPath = path.resolve('./.tox/npm'); 24 | if (!toxPath) { 25 | console.error('xStatic libraries not found, please run `tox -e npm`'); 26 | process.exit(1); 27 | } 28 | toxPath += '/lib/'; 29 | toxPath += fs.readdirSync(toxPath).find(function(directory) { 30 | return directory.indexOf('python') === 0; 31 | }); 32 | toxPath += '/site-packages/'; 33 | var xstaticPath = toxPath + 'xstatic/pkg/'; 34 | 35 | config.set({ 36 | preprocessors: { 37 | // Used to collect templates for preprocessing. 38 | // NOTE: the templates must also be listed in the files section below. 39 | './static/**/*.html': ['ng-html2js'] 40 | }, 41 | 42 | // Sets up module to process templates. 43 | ngHtml2JsPreprocessor: { 44 | prependPrefix: '/', 45 | moduleName: 'templates' 46 | }, 47 | 48 | basePath: './', 49 | 50 | // Contains both source and test files. 51 | files: [ 52 | /* 53 | * shim, partly stolen from /i18n/js/horizon/ 54 | * Contains expected items not provided elsewhere (dynamically by 55 | * Django or via jasmine template. 56 | */ 57 | './test-shim.js', 58 | 59 | // from jasmine.html 60 | xstaticPath + 'jquery/data/jquery.js', 61 | xstaticPath + 'angular/data/angular.js', 62 | xstaticPath + 'angular/data/angular-route.js', 63 | xstaticPath + 'angular/data/angular-mocks.js', 64 | xstaticPath + 'angular/data/angular-cookies.js', 65 | xstaticPath + 'angular_bootstrap/data/angular-bootstrap.js', 66 | xstaticPath + 'angular_gettext/data/angular-gettext.js', 67 | xstaticPath + 'angular_fileupload/data/ng-file-upload-all.js', 68 | xstaticPath + 'angular/data/angular-sanitize.js', 69 | xstaticPath + 'd3/data/d3.js', 70 | xstaticPath + 'rickshaw/data/rickshaw.js', 71 | xstaticPath + 'angular_smart_table/data/smart-table.js', 72 | xstaticPath + 'angular_lrdragndrop/data/lrdragndrop.js', 73 | xstaticPath + 'spin/data/spin.js', 74 | xstaticPath + 'spin/data/spin.jquery.js', 75 | xstaticPath + 'tv4/data/tv4.js', 76 | xstaticPath + 'objectpath/data/ObjectPath.js', 77 | xstaticPath + 'angular_schema_form/data/schema-form.js', 78 | 79 | // TODO: These should be mocked. 80 | toxPath + '/horizon/static/horizon/js/horizon.js', 81 | 82 | /** 83 | * Include framework source code from horizon that we need. 84 | * Otherwise, karma will not be able to find them when testing. 85 | * These files should be mocked in the foreseeable future. 86 | */ 87 | toxPath + 'horizon/static/framework/**/*.module.js', 88 | toxPath + 'horizon/static/framework/**/!(*.spec|*.mock).js', 89 | toxPath + 'openstack_dashboard/static/**/*.module.js', 90 | toxPath + 'openstack_dashboard/static/**/!(*.spec|*.mock).js', 91 | toxPath + 'openstack_dashboard/dashboards/**/static/**/*.module.js', 92 | toxPath + 'openstack_dashboard/dashboards/**/static/**/!(*.spec|*.mock).js', 93 | 94 | /** 95 | * First, list all the files that defines application's angular modules. 96 | * Those files have extension of `.module.js`. The order among them is 97 | * not significant. 98 | */ 99 | './designatedashboard/static/**/*.module.js', 100 | 101 | /** 102 | * Followed by other JavaScript files that defines angular providers 103 | * on the modules defined in files listed above. And they are not mock 104 | * files or spec files defined below. The order among them is not 105 | * significant. 106 | */ 107 | './designatedashboard/static/**/!(*.spec|*.mock).js', 108 | 109 | /** 110 | * Then, list files for mocks with `mock.js` extension. The order 111 | * among them should not be significant. 112 | */ 113 | toxPath + 'openstack_dashboard/static/**/*.mock.js', 114 | //'./static/**/*.mock.js', 115 | 116 | /** 117 | * Finally, list files for spec with `spec.js` extension. The order 118 | * among them should not be significant. 119 | */ 120 | './designatedashboard/static/**/*.spec.js', 121 | 122 | /** 123 | * Angular external templates 124 | */ 125 | './designatedashboard/static/**/*.html', 126 | 127 | ], 128 | 129 | autoWatch: true, 130 | 131 | frameworks: ['jasmine'], 132 | 133 | browsers: ['Firefox'], 134 | 135 | phantomjsLauncher: { 136 | // Have phantomjs exit if a ResourceError is encountered 137 | // (useful if karma exits without killing phantom) 138 | exitOnResourceError: true 139 | }, 140 | 141 | reporters: ['progress'], 142 | 143 | plugins: [ 144 | 'karma-firefox-launcher', 145 | 'karma-jasmine', 146 | 'karma-ng-html2js-preprocessor' 147 | ] 148 | 149 | }); 150 | }; 151 | -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # Copyright 2014 Hewlett-Packard Development Company, L.P. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | import os 16 | import sys 17 | 18 | 19 | if __name__ == "__main__": 20 | os.environ.setdefault( 21 | "DJANGO_SETTINGS_MODULE", "openstack_dashboard.settings") 22 | from django.core.management import execute_from_command_line # noqa 23 | execute_from_command_line(sys.argv) 24 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.0.0", 3 | "private": true, 4 | "name": "designate-dashboard", 5 | "description": "Designate Dashboard", 6 | "repository": "none", 7 | "license": "Apache 2.0", 8 | "devDependencies": { 9 | "eslint": "^1.10.3", 10 | "eslint-config-openstack": "1.2.4", 11 | "eslint-plugin-angular": "^1.0.1", 12 | "jasmine-core": "2.4.1", 13 | "karma": "~1.1.2", 14 | "karma-firefox-launcher": "2.1.0", 15 | "karma-cli": "1.0.1", 16 | "karma-jasmine": "1.0.2", 17 | "karma-ng-html2js-preprocessor": "1.0.0" 18 | }, 19 | "scripts": { 20 | "postinstall": "if [ ! -d .tox/npm ]; then tox -e npm --notest; fi", 21 | "lint": "eslint --no-color designatedashboard/static", 22 | "lintq": "eslint --quiet designatedashboard/static", 23 | "test": "karma start karma.conf.js --single-run" 24 | }, 25 | "dependencies": {} 26 | } 27 | -------------------------------------------------------------------------------- /releasenotes/notes/drop-py-2-7-ae8cade4a0ee1da8.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | upgrade: 3 | - | 4 | Python 2.7 support has been dropped. Last release of designate-dashboard 5 | to support python 2.7 is OpenStack Train. The minimum version of Python now 6 | supported by designate-dashboard is Python 3.6. 7 | -------------------------------------------------------------------------------- /releasenotes/notes/drop-python-3-6-and-3-7-8d166b2f80b27277.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | upgrade: 3 | - | 4 | Python 3.6 & 3.7 support has been dropped. The minimum version of Python now 5 | supported is Python 3.8. -------------------------------------------------------------------------------- /releasenotes/notes/drop-python-39.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | upgrade: 3 | - | 4 | Support for Python 3.9 has been dropped. 5 | -------------------------------------------------------------------------------- /releasenotes/notes/min-openstacksdk-b7e4661f8800bb9c.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | upgrade: 3 | - | 4 | The designate dashboard requires a minimum openstacksdk version of 2.1.0 5 | -------------------------------------------------------------------------------- /releasenotes/notes/openstacksdk-11483491f9978bd1.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | upgrade: 3 | - | 4 | The designate dashboard now needs openstacksdk 5 | -------------------------------------------------------------------------------- /releasenotes/notes/remove-designateclient-e98963b8baa4aa4f.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | upgrade: 3 | - | 4 | The ``python-designateclient`` library is no longer required. 5 | -------------------------------------------------------------------------------- /releasenotes/notes/remove-oslo-log-078df11995380f36.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | upgrade: 3 | - | 4 | The ``oslo.log`` library is no longer required. 5 | -------------------------------------------------------------------------------- /releasenotes/notes/remove-py38-1bc6676c8e5e880c.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | upgrade: 3 | - | 4 | Support for Python 3.8 has been removed. Now the minimum python version 5 | supported is 3.9 . 6 | -------------------------------------------------------------------------------- /releasenotes/notes/removed-v1-dashboard-56d4697d57baef09.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | upgrade: 3 | - | 4 | Removed the long deprecated v1 API dashboard. -------------------------------------------------------------------------------- /releasenotes/source/2023.1.rst: -------------------------------------------------------------------------------- 1 | =========================== 2 | 2023.1 Series Release Notes 3 | =========================== 4 | 5 | .. release-notes:: 6 | :branch: unmaintained/2023.1 7 | -------------------------------------------------------------------------------- /releasenotes/source/2023.2.rst: -------------------------------------------------------------------------------- 1 | =========================== 2 | 2023.2 Series Release Notes 3 | =========================== 4 | 5 | .. release-notes:: 6 | :branch: stable/2023.2 7 | -------------------------------------------------------------------------------- /releasenotes/source/2024.1.rst: -------------------------------------------------------------------------------- 1 | =========================== 2 | 2024.1 Series Release Notes 3 | =========================== 4 | 5 | .. release-notes:: 6 | :branch: stable/2024.1 7 | -------------------------------------------------------------------------------- /releasenotes/source/2024.2.rst: -------------------------------------------------------------------------------- 1 | =========================== 2 | 2024.2 Series Release Notes 3 | =========================== 4 | 5 | .. release-notes:: 6 | :branch: stable/2024.2 7 | -------------------------------------------------------------------------------- /releasenotes/source/2025.1.rst: -------------------------------------------------------------------------------- 1 | =========================== 2 | 2025.1 Series Release Notes 3 | =========================== 4 | 5 | .. release-notes:: 6 | :branch: stable/2025.1 7 | -------------------------------------------------------------------------------- /releasenotes/source/index.rst: -------------------------------------------------------------------------------- 1 | =========================================================== 2 | Welcome to Designate dashboard Release Notes documentation! 3 | =========================================================== 4 | 5 | Contents 6 | ======== 7 | 8 | .. toctree:: 9 | :maxdepth: 2 10 | 11 | unreleased 12 | 2025.1 13 | 2024.2 14 | 2024.1 15 | 2023.2 16 | 2023.1 17 | zed 18 | yoga 19 | xena 20 | wallaby 21 | victoria 22 | ussuri 23 | train 24 | 25 | Indices and tables 26 | ================== 27 | 28 | * :ref:`genindex` 29 | * :ref:`search` 30 | -------------------------------------------------------------------------------- /releasenotes/source/locale/cs/LC_MESSAGES/releasenotes.po: -------------------------------------------------------------------------------- 1 | # Zbyněk Schwarz , 2017. #zanata 2 | msgid "" 3 | msgstr "" 4 | "Project-Id-Version: Designate dashboard Release Notes\n" 5 | "Report-Msgid-Bugs-To: \n" 6 | "POT-Creation-Date: 2022-09-13 22:31+0000\n" 7 | "MIME-Version: 1.0\n" 8 | "Content-Type: text/plain; charset=UTF-8\n" 9 | "Content-Transfer-Encoding: 8bit\n" 10 | "PO-Revision-Date: 2017-11-17 09:06+0000\n" 11 | "Last-Translator: Zbyněk Schwarz \n" 12 | "Language-Team: Czech\n" 13 | "Language: cs\n" 14 | "X-Generator: Zanata 4.3.3\n" 15 | "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2\n" 16 | 17 | msgid ":ref:`genindex`" 18 | msgstr ":ref:`genindex`" 19 | 20 | msgid ":ref:`search`" 21 | msgstr ":ref:`search`" 22 | 23 | msgid "Contents" 24 | msgstr "Obsah" 25 | 26 | msgid "Current Series Release Notes" 27 | msgstr "Poznámky k vydání současné verze" 28 | 29 | msgid "Indices and tables" 30 | msgstr "Rejstříky a tabulky" 31 | -------------------------------------------------------------------------------- /releasenotes/source/locale/de/LC_MESSAGES/releasenotes.po: -------------------------------------------------------------------------------- 1 | # Frank Kloeker , 2017. #zanata 2 | # Andreas Jaeger , 2019. #zanata 3 | # Andreas Jaeger , 2020. #zanata 4 | msgid "" 5 | msgstr "" 6 | "Project-Id-Version: designate-dashboard\n" 7 | "Report-Msgid-Bugs-To: \n" 8 | "POT-Creation-Date: 2020-04-19 10:55+0000\n" 9 | "MIME-Version: 1.0\n" 10 | "Content-Type: text/plain; charset=UTF-8\n" 11 | "Content-Transfer-Encoding: 8bit\n" 12 | "PO-Revision-Date: 2020-04-25 09:13+0000\n" 13 | "Last-Translator: Andreas Jaeger \n" 14 | "Language-Team: German\n" 15 | "Language: de\n" 16 | "X-Generator: Zanata 4.3.3\n" 17 | "Plural-Forms: nplurals=2; plural=(n != 1)\n" 18 | 19 | msgid "9.0.0" 20 | msgstr "9.0.0" 21 | 22 | msgid ":ref:`genindex`" 23 | msgstr ":ref:`genindex`" 24 | 25 | msgid ":ref:`search`" 26 | msgstr ":ref:`search`" 27 | 28 | msgid "Contents" 29 | msgstr "Inhalt" 30 | 31 | msgid "Current Series Release Notes" 32 | msgstr "Aktuelle Serie Releasenotes" 33 | 34 | msgid "Indices and tables" 35 | msgstr "Indizes und Tabellen" 36 | 37 | msgid "" 38 | "Python 2.7 support has been dropped. Last release of designate-dashboard to " 39 | "support python 2.7 is OpenStack Train. The minimum version of Python now " 40 | "supported by designate-dashboard is Python 3.6." 41 | msgstr "" 42 | "Python 2.7 Unterstützung wurde beendet. Der letzte Release von designate-" 43 | "dashboard welcher Python 2.7 unterstützt ist OpenStack Train. Die minimal " 44 | "Python Version welche von designate-dashboard unterstützt wird ist Python " 45 | "3.6." 46 | 47 | msgid "Removed the long deprecated v1 API dashboard." 48 | msgstr "Das lange abgekündigte v1 API Dashboard wurde entfernt." 49 | 50 | msgid "Train Series Release Notes" 51 | msgstr "Train Serie Releasenotes" 52 | 53 | msgid "Upgrade Notes" 54 | msgstr "Aktualisierungsnotizen" 55 | 56 | msgid "Welcome to Designate dashboard Release Notes documentation!" 57 | msgstr "Willkommen bei den Releasenotes für das Designate Dashboard" 58 | -------------------------------------------------------------------------------- /releasenotes/source/locale/en_GB/LC_MESSAGES/releasenotes.po: -------------------------------------------------------------------------------- 1 | # Andi Chandler , 2017. #zanata 2 | # Andi Chandler , 2019. #zanata 3 | # Andi Chandler , 2020. #zanata 4 | # Andi Chandler , 2021. #zanata 5 | # Andi Chandler , 2022. #zanata 6 | # Andi Chandler , 2023. #zanata 7 | # Andi Chandler , 2024. #zanata 8 | msgid "" 9 | msgstr "" 10 | "Project-Id-Version: Designate dashboard Release Notes\n" 11 | "Report-Msgid-Bugs-To: \n" 12 | "POT-Creation-Date: 2024-04-15 14:29+0000\n" 13 | "MIME-Version: 1.0\n" 14 | "Content-Type: text/plain; charset=UTF-8\n" 15 | "Content-Transfer-Encoding: 8bit\n" 16 | "PO-Revision-Date: 2024-04-18 12:34+0000\n" 17 | "Last-Translator: Andi Chandler \n" 18 | "Language-Team: English (United Kingdom)\n" 19 | "Language: en_GB\n" 20 | "X-Generator: Zanata 4.3.3\n" 21 | "Plural-Forms: nplurals=2; plural=(n != 1)\n" 22 | 23 | msgid "10.0.0" 24 | msgstr "10.0.0" 25 | 26 | msgid "15.0.0" 27 | msgstr "15.0.0" 28 | 29 | msgid "18.0.0" 30 | msgstr "18.0.0" 31 | 32 | msgid "2023.1 Series Release Notes" 33 | msgstr "2023.1 Series Release Notes" 34 | 35 | msgid "2023.2 Series Release Notes" 36 | msgstr "2023.2 Series Release Notes" 37 | 38 | msgid "2024.1 Series Release Notes" 39 | msgstr "2024.1 Series Release Notes" 40 | 41 | msgid "9.0.0" 42 | msgstr "9.0.0" 43 | 44 | msgid ":ref:`genindex`" 45 | msgstr ":ref:`genindex`" 46 | 47 | msgid ":ref:`search`" 48 | msgstr ":ref:`search`" 49 | 50 | msgid "Contents" 51 | msgstr "Contents" 52 | 53 | msgid "Current Series Release Notes" 54 | msgstr "Current Series Release Notes" 55 | 56 | msgid "Indices and tables" 57 | msgstr "Indices and tables" 58 | 59 | msgid "" 60 | "Python 2.7 support has been dropped. Last release of designate-dashboard to " 61 | "support python 2.7 is OpenStack Train. The minimum version of Python now " 62 | "supported by designate-dashboard is Python 3.6." 63 | msgstr "" 64 | "Python 2.7 support has been dropped. Last release of Designate-dashboard to " 65 | "support Python 2.7 is OpenStack Train. The minimum version of Python now " 66 | "supported by Designate-dashboard is Python 3.6." 67 | 68 | msgid "" 69 | "Python 3.6 & 3.7 support has been dropped. The minimum version of Python now " 70 | "supported is Python 3.8." 71 | msgstr "" 72 | "Python 3.6 & 3.7 support has been dropped. The minimum version of Python now " 73 | "supported is Python 3.8." 74 | 75 | msgid "Removed the long deprecated v1 API dashboard." 76 | msgstr "Removed the long deprecated v1 API dashboard." 77 | 78 | msgid "The ``oslo.log`` library is no longer required." 79 | msgstr "The ``oslo.log`` library is no longer required." 80 | 81 | msgid "The ``python-designateclient`` library is no longer required." 82 | msgstr "The ``python-designateclient`` library is no longer required." 83 | 84 | msgid "The designate dashboard now needs openstacksdk" 85 | msgstr "The Designate dashboard now needs openstacksdk" 86 | 87 | msgid "Train Series Release Notes" 88 | msgstr "Train Series Release Notes" 89 | 90 | msgid "Upgrade Notes" 91 | msgstr "Upgrade Notes" 92 | 93 | msgid "Ussuri Series Release Notes" 94 | msgstr "Ussuri Series Release Notes" 95 | 96 | msgid "Victoria Series Release Notes" 97 | msgstr "Victoria Series Release Notes" 98 | 99 | msgid "Wallaby Series Release Notes" 100 | msgstr "Wallaby Series Release Notes" 101 | 102 | msgid "Welcome to Designate dashboard Release Notes documentation!" 103 | msgstr "Welcome to Designate dashboard Release Notes documentation!" 104 | 105 | msgid "Xena Series Release Notes" 106 | msgstr "Xena Series Release Notes" 107 | 108 | msgid "Yoga Series Release Notes" 109 | msgstr "Yoga Series Release Notes" 110 | 111 | msgid "Zed Series Release Notes" 112 | msgstr "Zed Series Release Notes" 113 | -------------------------------------------------------------------------------- /releasenotes/source/locale/fr/LC_MESSAGES/releasenotes.po: -------------------------------------------------------------------------------- 1 | # Gaelle , 2017. #zanata 2 | # François Magimel , 2018. #zanata 3 | msgid "" 4 | msgstr "" 5 | "Project-Id-Version: Designate dashboard Release Notes\n" 6 | "Report-Msgid-Bugs-To: \n" 7 | "POT-Creation-Date: 2022-09-13 22:31+0000\n" 8 | "MIME-Version: 1.0\n" 9 | "Content-Type: text/plain; charset=UTF-8\n" 10 | "Content-Transfer-Encoding: 8bit\n" 11 | "PO-Revision-Date: 2018-07-13 02:29+0000\n" 12 | "Last-Translator: François Magimel \n" 13 | "Language-Team: French\n" 14 | "Language: fr\n" 15 | "X-Generator: Zanata 4.3.3\n" 16 | "Plural-Forms: nplurals=2; plural=(n > 1)\n" 17 | 18 | msgid ":ref:`genindex`" 19 | msgstr ":ref:`genindex`" 20 | 21 | msgid ":ref:`search`" 22 | msgstr ":ref:`search`" 23 | 24 | msgid "Contents" 25 | msgstr "Contenus" 26 | 27 | msgid "Current Series Release Notes" 28 | msgstr "Notes sur la version actuelle" 29 | 30 | msgid "Indices and tables" 31 | msgstr "Index et table des matières" 32 | -------------------------------------------------------------------------------- /releasenotes/source/locale/id/LC_MESSAGES/releasenotes.po: -------------------------------------------------------------------------------- 1 | # suhartono , 2017. #zanata 2 | msgid "" 3 | msgstr "" 4 | "Project-Id-Version: Designate dashboard Release Notes\n" 5 | "Report-Msgid-Bugs-To: \n" 6 | "POT-Creation-Date: 2022-09-13 22:31+0000\n" 7 | "MIME-Version: 1.0\n" 8 | "Content-Type: text/plain; charset=UTF-8\n" 9 | "Content-Transfer-Encoding: 8bit\n" 10 | "PO-Revision-Date: 2017-01-09 04:01+0000\n" 11 | "Last-Translator: suhartono \n" 12 | "Language-Team: Indonesian\n" 13 | "Language: id\n" 14 | "X-Generator: Zanata 4.3.3\n" 15 | "Plural-Forms: nplurals=1; plural=0\n" 16 | 17 | msgid ":ref:`genindex`" 18 | msgstr ":ref:`genindex`" 19 | 20 | msgid ":ref:`search`" 21 | msgstr ":ref:`search`" 22 | 23 | msgid "Contents" 24 | msgstr "Contents (Isi)" 25 | 26 | msgid "Current Series Release Notes" 27 | msgstr "Series Release Notes saat ini" 28 | 29 | msgid "Indices and tables" 30 | msgstr "Indices and tables (indeks dan tabel)" 31 | -------------------------------------------------------------------------------- /releasenotes/source/locale/ja/LC_MESSAGES/releasenotes.po: -------------------------------------------------------------------------------- 1 | # Akihiro Motoki , 2018. #zanata 2 | msgid "" 3 | msgstr "" 4 | "Project-Id-Version: Designate dashboard Release Notes\n" 5 | "Report-Msgid-Bugs-To: \n" 6 | "POT-Creation-Date: 2022-09-13 22:31+0000\n" 7 | "MIME-Version: 1.0\n" 8 | "Content-Type: text/plain; charset=UTF-8\n" 9 | "Content-Transfer-Encoding: 8bit\n" 10 | "PO-Revision-Date: 2018-02-08 08:46+0000\n" 11 | "Last-Translator: Akihiro Motoki \n" 12 | "Language-Team: Japanese\n" 13 | "Language: ja\n" 14 | "X-Generator: Zanata 4.3.3\n" 15 | "Plural-Forms: nplurals=1; plural=0\n" 16 | 17 | msgid ":ref:`genindex`" 18 | msgstr ":ref:`genindex`" 19 | 20 | msgid ":ref:`search`" 21 | msgstr ":ref:`search`" 22 | 23 | msgid "Contents" 24 | msgstr "内容" 25 | 26 | msgid "Current Series Release Notes" 27 | msgstr "開発中バージョンのリリースノート" 28 | 29 | msgid "Indices and tables" 30 | msgstr "目次と表" 31 | -------------------------------------------------------------------------------- /releasenotes/source/locale/ko_KR/LC_MESSAGES/releasenotes.po: -------------------------------------------------------------------------------- 1 | # Sungjin Kang , 2017. #zanata 2 | msgid "" 3 | msgstr "" 4 | "Project-Id-Version: Designate dashboard Release Notes\n" 5 | "Report-Msgid-Bugs-To: \n" 6 | "POT-Creation-Date: 2022-09-13 22:31+0000\n" 7 | "MIME-Version: 1.0\n" 8 | "Content-Type: text/plain; charset=UTF-8\n" 9 | "Content-Transfer-Encoding: 8bit\n" 10 | "PO-Revision-Date: 2017-01-10 11:18+0000\n" 11 | "Last-Translator: Sungjin Kang \n" 12 | "Language-Team: Korean (South Korea)\n" 13 | "Language: ko_KR\n" 14 | "X-Generator: Zanata 4.3.3\n" 15 | "Plural-Forms: nplurals=1; plural=0\n" 16 | 17 | msgid ":ref:`genindex`" 18 | msgstr ":ref:`genindex`" 19 | 20 | msgid ":ref:`search`" 21 | msgstr ":ref:`search`" 22 | 23 | msgid "Contents" 24 | msgstr "내용" 25 | 26 | msgid "Current Series Release Notes" 27 | msgstr "최신 시리즈에 대한 릴리즈 노트" 28 | 29 | msgid "Indices and tables" 30 | msgstr "인텍스 및 테이블" 31 | -------------------------------------------------------------------------------- /releasenotes/source/locale/ne/LC_MESSAGES/releasenotes.po: -------------------------------------------------------------------------------- 1 | # Surit Aryal , 2019. #zanata 2 | msgid "" 3 | msgstr "" 4 | "Project-Id-Version: Designate dashboard Release Notes\n" 5 | "Report-Msgid-Bugs-To: \n" 6 | "POT-Creation-Date: 2022-09-13 22:31+0000\n" 7 | "MIME-Version: 1.0\n" 8 | "Content-Type: text/plain; charset=UTF-8\n" 9 | "Content-Transfer-Encoding: 8bit\n" 10 | "PO-Revision-Date: 2019-06-12 04:27+0000\n" 11 | "Last-Translator: Surit Aryal \n" 12 | "Language-Team: Nepali\n" 13 | "Language: ne\n" 14 | "X-Generator: Zanata 4.3.3\n" 15 | "Plural-Forms: nplurals=2; plural=(n != 1)\n" 16 | 17 | msgid ":ref:`genindex`" 18 | msgstr ":ref:`genindex`" 19 | 20 | msgid ":ref:`search`" 21 | msgstr ":ref:`search`" 22 | 23 | msgid "Contents" 24 | msgstr "सामग्रीहरू" 25 | 26 | msgid "Current Series Release Notes" 27 | msgstr "Current Series रिलीज नोट्स" 28 | 29 | msgid "Indices and tables" 30 | msgstr "सूचकांक र तालिकाहरू" 31 | -------------------------------------------------------------------------------- /releasenotes/source/locale/pt_BR/LC_MESSAGES/releasenotes.po: -------------------------------------------------------------------------------- 1 | # Fernando Pimenta , 2018. #zanata 2 | # Rodrigo Loures , 2018. #zanata 3 | msgid "" 4 | msgstr "" 5 | "Project-Id-Version: Designate dashboard Release Notes\n" 6 | "Report-Msgid-Bugs-To: \n" 7 | "POT-Creation-Date: 2022-09-13 22:31+0000\n" 8 | "MIME-Version: 1.0\n" 9 | "Content-Type: text/plain; charset=UTF-8\n" 10 | "Content-Transfer-Encoding: 8bit\n" 11 | "PO-Revision-Date: 2018-03-09 06:57+0000\n" 12 | "Last-Translator: Fernando Pimenta \n" 13 | "Language-Team: Portuguese (Brazil)\n" 14 | "Language: pt_BR\n" 15 | "X-Generator: Zanata 4.3.3\n" 16 | "Plural-Forms: nplurals=2; plural=(n != 1)\n" 17 | 18 | msgid ":ref:`genindex`" 19 | msgstr ":ref:`genindex`" 20 | 21 | msgid ":ref:`search`" 22 | msgstr ":ref:`search`" 23 | 24 | msgid "Contents" 25 | msgstr "Conteúdo" 26 | 27 | msgid "Current Series Release Notes" 28 | msgstr "Notas de Versão da Série Atual" 29 | 30 | msgid "Indices and tables" 31 | msgstr "Índices e tabelas" 32 | -------------------------------------------------------------------------------- /releasenotes/source/locale/ru/LC_MESSAGES/releasenotes.po: -------------------------------------------------------------------------------- 1 | # Fedor Tarasenko , 2017. #zanata 2 | msgid "" 3 | msgstr "" 4 | "Project-Id-Version: Designate dashboard Release Notes\n" 5 | "Report-Msgid-Bugs-To: \n" 6 | "POT-Creation-Date: 2022-09-13 22:31+0000\n" 7 | "MIME-Version: 1.0\n" 8 | "Content-Type: text/plain; charset=UTF-8\n" 9 | "Content-Transfer-Encoding: 8bit\n" 10 | "PO-Revision-Date: 2017-02-03 08:41+0000\n" 11 | "Last-Translator: Fedor Tarasenko \n" 12 | "Language-Team: Russian\n" 13 | "Language: ru\n" 14 | "X-Generator: Zanata 4.3.3\n" 15 | "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" 16 | "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n" 17 | 18 | msgid ":ref:`genindex`" 19 | msgstr ":ref:`genindex`" 20 | 21 | msgid ":ref:`search`" 22 | msgstr ":ref:`search`" 23 | 24 | msgid "Contents" 25 | msgstr "Содержание" 26 | 27 | msgid "Current Series Release Notes" 28 | msgstr "Примечания к текущему релизу" 29 | -------------------------------------------------------------------------------- /releasenotes/source/locale/zh_CN/LC_MESSAGES/releasenotes.po: -------------------------------------------------------------------------------- 1 | # TigerFang , 2017. #zanata 2 | msgid "" 3 | msgstr "" 4 | "Project-Id-Version: Designate dashboard Release Notes\n" 5 | "Report-Msgid-Bugs-To: \n" 6 | "POT-Creation-Date: 2022-09-13 22:31+0000\n" 7 | "MIME-Version: 1.0\n" 8 | "Content-Type: text/plain; charset=UTF-8\n" 9 | "Content-Transfer-Encoding: 8bit\n" 10 | "PO-Revision-Date: 2017-05-15 09:55+0000\n" 11 | "Last-Translator: TigerFang \n" 12 | "Language-Team: Chinese (China)\n" 13 | "Language: zh_CN\n" 14 | "X-Generator: Zanata 4.3.3\n" 15 | "Plural-Forms: nplurals=1; plural=0\n" 16 | 17 | msgid ":ref:`genindex`" 18 | msgstr ":ref:`genindex`" 19 | 20 | msgid ":ref:`search`" 21 | msgstr ":ref:`search`" 22 | 23 | msgid "Contents" 24 | msgstr "内容" 25 | 26 | msgid "Current Series Release Notes" 27 | msgstr "当前版本发布说明" 28 | 29 | msgid "Indices and tables" 30 | msgstr "索引和表格" 31 | -------------------------------------------------------------------------------- /releasenotes/source/train.rst: -------------------------------------------------------------------------------- 1 | ========================== 2 | Train Series Release Notes 3 | ========================== 4 | 5 | .. release-notes:: 6 | :branch: stable/train 7 | -------------------------------------------------------------------------------- /releasenotes/source/unreleased.rst: -------------------------------------------------------------------------------- 1 | ============================ 2 | Current Series Release Notes 3 | ============================ 4 | 5 | .. release-notes:: 6 | -------------------------------------------------------------------------------- /releasenotes/source/ussuri.rst: -------------------------------------------------------------------------------- 1 | =========================== 2 | Ussuri Series Release Notes 3 | =========================== 4 | 5 | .. release-notes:: 6 | :branch: stable/ussuri 7 | -------------------------------------------------------------------------------- /releasenotes/source/victoria.rst: -------------------------------------------------------------------------------- 1 | ============================= 2 | Victoria Series Release Notes 3 | ============================= 4 | 5 | .. release-notes:: 6 | :branch: unmaintained/victoria 7 | -------------------------------------------------------------------------------- /releasenotes/source/wallaby.rst: -------------------------------------------------------------------------------- 1 | ============================ 2 | Wallaby Series Release Notes 3 | ============================ 4 | 5 | .. release-notes:: 6 | :branch: unmaintained/wallaby 7 | -------------------------------------------------------------------------------- /releasenotes/source/xena.rst: -------------------------------------------------------------------------------- 1 | ========================= 2 | Xena Series Release Notes 3 | ========================= 4 | 5 | .. release-notes:: 6 | :branch: unmaintained/xena 7 | -------------------------------------------------------------------------------- /releasenotes/source/yoga.rst: -------------------------------------------------------------------------------- 1 | ========================= 2 | Yoga Series Release Notes 3 | ========================= 4 | 5 | .. release-notes:: 6 | :branch: unmaintained/yoga 7 | -------------------------------------------------------------------------------- /releasenotes/source/zed.rst: -------------------------------------------------------------------------------- 1 | ======================== 2 | Zed Series Release Notes 3 | ======================== 4 | 5 | .. release-notes:: 6 | :branch: unmaintained/zed 7 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | # Requirements lower bounds listed here are our best effort to keep them up to 2 | # date but we do not test them so no guarantee of having them all correct. If 3 | # you find any incorrect lower bounds, let us know or propose a fix. 4 | pbr!=2.1.0,>=2.0.0 # Apache-2.0 5 | 6 | horizon>=17.1.0 # Apache-2.0 7 | openstacksdk>=2.1.0 # Apache-2.0 8 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | name = designate-dashboard 3 | summary = Designate Horizon UI bits 4 | description_file = 5 | README.rst 6 | author = OpenStack 7 | author_email = openstack-discuss@lists.openstack.org 8 | home_page = https://docs.openstack.org/designate-dashboard/latest/ 9 | python_requires = >=3.10 10 | classifier = 11 | Environment :: OpenStack 12 | Intended Audience :: Information Technology 13 | Intended Audience :: System Administrators 14 | License :: OSI Approved :: Apache Software License 15 | Operating System :: POSIX :: Linux 16 | Programming Language :: Python 17 | Programming Language :: Python :: Implementation :: CPython 18 | Programming Language :: Python :: 3 :: Only 19 | Programming Language :: Python :: 3 20 | Programming Language :: Python :: 3.10 21 | Programming Language :: Python :: 3.11 22 | Programming Language :: Python :: 3.12 23 | Programming Language :: Python :: 3.13 24 | 25 | [files] 26 | packages = 27 | designatedashboard 28 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2013 Hewlett-Packard Development Company, L.P. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 | # implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | import setuptools 17 | 18 | setuptools.setup( 19 | setup_requires=['pbr>=2.0.0'], 20 | pbr=True) 21 | -------------------------------------------------------------------------------- /test: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstack/designate-dashboard/e9ce32addfdb257956cce7e6961ef3172f304a22/test -------------------------------------------------------------------------------- /test-requirements.txt: -------------------------------------------------------------------------------- 1 | hacking>=6.1.0,<6.2.0 # Apache-2.0 2 | 3 | coverage!=4.4,>=4.0 # Apache-2.0 4 | oslo.config>=5.2.0 # Apache-2.0 5 | pylint==1.4.5 # GPLv2 6 | testrepository>=0.0.18 # Apache-2.0/BSD 7 | testtools>=2.2.0 # MIT 8 | -------------------------------------------------------------------------------- /test-shim.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 3 | * not use this file except in compliance with the License. You may obtain 4 | * a copy of the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations 12 | * under the License. 13 | */ 14 | 15 | /* 16 | * Shim for Javascript unit tests; supplying expected global features. 17 | * This should be removed from the codebase once i18n services are provided. 18 | * Taken from default i18n file provided by Django. 19 | */ 20 | 21 | var horizonPlugInModules = []; 22 | 23 | 24 | (function (globals) { 25 | 26 | var django = globals.django || (globals.django = {}); 27 | 28 | 29 | django.pluralidx = function (count) { return (count == 1) ? 0 : 1; }; 30 | 31 | /* gettext identity library */ 32 | 33 | django.gettext = function (msgid) { return msgid; }; 34 | django.ngettext = function (singular, plural, count) { return (count == 1) ? singular : plural; }; 35 | django.gettext_noop = function (msgid) { return msgid; }; 36 | django.pgettext = function (context, msgid) { return msgid; }; 37 | django.npgettext = function (context, singular, plural, count) { return (count == 1) ? singular : plural; }; 38 | 39 | 40 | django.interpolate = function (fmt, obj, named) { 41 | if (named) { 42 | return fmt.replace(/%\(\w+\)s/g, function(match){return String(obj[match.slice(2,-2)])}); 43 | } else { 44 | return fmt.replace(/%s/g, function(match){return String(obj.shift())}); 45 | } 46 | }; 47 | 48 | 49 | /* formatting library */ 50 | 51 | django.formats = { 52 | "DATETIME_FORMAT": "N j, Y, P", 53 | "DATETIME_INPUT_FORMATS": [ 54 | "%Y-%m-%d %H:%M:%S", 55 | "%Y-%m-%d %H:%M:%S.%f", 56 | "%Y-%m-%d %H:%M", 57 | "%Y-%m-%d", 58 | "%m/%d/%Y %H:%M:%S", 59 | "%m/%d/%Y %H:%M:%S.%f", 60 | "%m/%d/%Y %H:%M", 61 | "%m/%d/%Y", 62 | "%m/%d/%y %H:%M:%S", 63 | "%m/%d/%y %H:%M:%S.%f", 64 | "%m/%d/%y %H:%M", 65 | "%m/%d/%y" 66 | ], 67 | "DATE_FORMAT": "N j, Y", 68 | "DATE_INPUT_FORMATS": [ 69 | "%Y-%m-%d", 70 | "%m/%d/%Y", 71 | "%m/%d/%y" 72 | ], 73 | "DECIMAL_SEPARATOR": ".", 74 | "FIRST_DAY_OF_WEEK": "0", 75 | "MONTH_DAY_FORMAT": "F j", 76 | "NUMBER_GROUPING": "3", 77 | "SHORT_DATETIME_FORMAT": "m/d/Y P", 78 | "SHORT_DATE_FORMAT": "m/d/Y", 79 | "THOUSAND_SEPARATOR": ",", 80 | "TIME_FORMAT": "P", 81 | "TIME_INPUT_FORMATS": [ 82 | "%H:%M:%S", 83 | "%H:%M:%S.%f", 84 | "%H:%M" 85 | ], 86 | "YEAR_MONTH_FORMAT": "F Y" 87 | }; 88 | 89 | django.get_format = function (format_type) { 90 | var value = django.formats[format_type]; 91 | if (typeof(value) == 'undefined') { 92 | return format_type; 93 | } else { 94 | return value; 95 | } 96 | }; 97 | 98 | /* add to global namespace */ 99 | globals.pluralidx = django.pluralidx; 100 | globals.gettext = django.gettext; 101 | globals.ngettext = django.ngettext; 102 | globals.gettext_noop = django.gettext_noop; 103 | globals.pgettext = django.pgettext; 104 | globals.npgettext = django.npgettext; 105 | globals.interpolate = django.interpolate; 106 | globals.get_format = django.get_format; 107 | globals.STATIC_URL = '/static/'; 108 | globals.WEBROOT = '/'; 109 | 110 | }(this)); 111 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | minversion = 3.18.0 3 | envlist = py3,pep8,npm 4 | skipsdist = True 5 | 6 | [testenv] 7 | usedevelop = True 8 | setenv = VIRTUAL_ENV={envdir} 9 | NOSE_WITH_OPENSTACK=1 10 | NOSE_OPENSTACK_COLOR=1 11 | NOSE_OPENSTACK_RED=0.05 12 | NOSE_OPENSTACK_YELLOW=0.025 13 | NOSE_OPENSTACK_SHOW_ELAPSED=1 14 | PYTHONDONTWRITEBYTECODE=1 15 | DJANGO_SETTINGS_MODULE=designatedashboard.settings 16 | allowlist_externals = find 17 | {toxinidir}/manage.py 18 | npm 19 | deps = -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master} 20 | -r{toxinidir}/requirements.txt 21 | -r{toxinidir}/test-requirements.txt 22 | 23 | commands = 24 | find . -type f -name "*.pyc" -delete 25 | {toxinidir}/manage.py test designatedashboard --settings=designatedashboard.tests.settings 26 | passenv = 27 | http_proxy 28 | HTTP_PROXY 29 | https_proxy 30 | HTTPS_PROXY 31 | no_proxy 32 | NO_PROXY 33 | 34 | [testenv:pep8] 35 | commands = flake8 36 | 37 | [testenv:venv] 38 | commands = {posargs} 39 | 40 | [testenv:cover] 41 | commands = 42 | coverage erase 43 | coverage run {toxinidir}/manage.py test designatedashboard --settings=designatedashboard.tests.settings {posargs} 44 | coverage xml --include 'designatedashboard/*' -o cover/coverage.xml 45 | coverage html --include 'designatedashboard/*' -d cover 46 | 47 | [testenv:docs] 48 | deps = -r{toxinidir}/doc/requirements.txt 49 | commands = sphinx-build -W -b html -d doc/build/doctrees doc/source doc/build/html 50 | 51 | [testenv:pdf-docs] 52 | deps = -r{toxinidir}/doc/requirements.txt 53 | allowlist_externals = 54 | make 55 | commands = 56 | sphinx-build -W -b latex doc/source doc/build/pdf 57 | make -C doc/build/pdf 58 | 59 | [flake8] 60 | # E123, E125 skipped as they are invalid PEP-8. 61 | # F405 TEMPLATES may be undefined, or defined from star imports. 62 | # (because it is not easy to avoid this in openstack_dashboard.test.settings) 63 | # W504 line break after binary operator 64 | show-source = True 65 | ignore = E123,E125,F405,W504 66 | builtins = _ 67 | exclude=.venv,.git,.tox,dist,doc,*openstack/common*,*lib/python*,*egg,build,releasenotes,node_modules 68 | 69 | [testenv:releasenotes] 70 | commands = sphinx-build -a -E -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html 71 | 72 | [testenv:eslint] 73 | # npm must be installed on the system, for example 74 | # sudo apt-get install npm 75 | commands = npm install 76 | npm run lint 77 | 78 | [testenv:karma] 79 | # npm must be installed on the system, for example 80 | # sudo apt-get install npm 81 | commands = npm install 82 | npm test 83 | --------------------------------------------------------------------------------