1ff8469ef7
The Oslo libraries have moved all of their code out of the 'oslo' namespace package into per-library packages. The namespace package was retained during kilo for backwards compatibility, but will be removed by the liberty-2 milestone. This change removes the use of the namespace package, replacing it with the new package names. The patches in the libraries will be put on hold until application patches have landed, or L2, whichever comes first. At that point, new versions of the libraries without namespace packages will be released as a major version update. Please merge this patch, or an equivalent, before L2 to avoid problems with those library releases. Blueprint: remove-namespace-packages https://blueprints.launchpad.net/oslo-incubator/+spec/remove-namespace-packages Change-Id: Iae62b48993eef3b31420f8cc245a55f5e303c4fc
142 lines
5.6 KiB
Python
142 lines
5.6 KiB
Python
# Copyright (c) 2014 Rackspace Hosting
|
|
# All Rights Reserved.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
import csv
|
|
import os
|
|
|
|
from oslo_config import cfg
|
|
from oslo_log import log as logging
|
|
|
|
from designate import exceptions
|
|
from designate import rpc
|
|
from designate.central import rpcapi as central_rpcapi
|
|
from designate.i18n import _LI
|
|
from designate.i18n import _LE
|
|
from designate.manage import base
|
|
from designate.schema import format
|
|
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
|
|
class TLDCommands(base.Commands):
|
|
"""
|
|
Import TLDs to Designate. The format of the command is:
|
|
designate-manage import-tlds --input-file="<complete path to input file>"
|
|
[--delimiter="delimiter character"]
|
|
The TLDs need to be provided in a csv file. Each line in
|
|
this file contains a TLD entry followed by an optional description.
|
|
By default the delimiter character is ","
|
|
|
|
If any lines in the input file result in an error, the program
|
|
continues to the next line.
|
|
|
|
On completion the output is reported (LOG.info) in the format:
|
|
Number of tlds added: <number>
|
|
|
|
If there are any errors, they are reported (LOG.err) in the format:
|
|
<Error> --> <Line causing the error>
|
|
|
|
<Error> can be one of the following:
|
|
DuplicateTld - This occurs if the TLD is already present.
|
|
InvalidTld - This occurs if the TLD does not conform to the TLD schema.
|
|
InvalidDescription - This occurs if the description does not conform to
|
|
the description schema
|
|
InvalidLine - This occurs if the line contains more than 2 fields.
|
|
"""
|
|
|
|
def __init__(self):
|
|
super(TLDCommands, self).__init__()
|
|
rpc.init(cfg.CONF)
|
|
self.central_api = central_rpcapi.CentralAPI()
|
|
|
|
# The dictionary function __str__() does not list the fields in any
|
|
# particular order.
|
|
# It makes it easier to read if the tld_name is printed first, so we have
|
|
# a separate function to do the necessary conversions
|
|
def _convert_tld_dict_to_str(self, line):
|
|
keys = ['name', 'description', 'extra_fields']
|
|
values = [line['name'],
|
|
line['description'],
|
|
line['extra_fields'] if 'extra_fields' in line else None]
|
|
dict_str = ''.join([str.format("'{0}': '{1}', ", keys[x], values[x])
|
|
for x in range(len(values)) if values[x]])
|
|
|
|
return '{' + dict_str.rstrip(' ,') + '}'
|
|
|
|
# validates and returns the number of tlds added - either 0 in case of
|
|
# any errors or 1 if everything is successful
|
|
# In case of errors, the error message is appended to the list error_lines
|
|
def _validate_and_create_tld(self, line, error_lines):
|
|
# validate the tld name
|
|
if not format.is_tldname(line['name']):
|
|
error_lines.append("InvalidTld --> " +
|
|
self._convert_tld_dict_to_str(line))
|
|
return 0
|
|
# validate the description if there is one
|
|
elif (line['description']) and (len(line['description']) > 160):
|
|
error_lines.append("InvalidDescription --> " +
|
|
self._convert_tld_dict_to_str(line))
|
|
|
|
return 0
|
|
else:
|
|
try:
|
|
self.central_api.create_tld(self.context, values=line)
|
|
return 1
|
|
except exceptions.DuplicateTld:
|
|
error_lines.append("DuplicateTld --> " +
|
|
self._convert_tld_dict_to_str(line))
|
|
return 0
|
|
|
|
@base.name('import')
|
|
@base.args('--input_file', help="Input file path containing TLDs",
|
|
default=None, required=True, type=str)
|
|
@base.args('--delimiter',
|
|
help="delimiter between fields in the input file",
|
|
default=',', type=str)
|
|
def from_file(self, input_file=None, delimiter=None):
|
|
input_file = str(input_file) if input_file is not None else None
|
|
|
|
if not os.path.exists(input_file):
|
|
raise Exception('TLD Input file Not Found')
|
|
|
|
LOG.info(_LI("Importing TLDs from %s") % input_file)
|
|
|
|
error_lines = []
|
|
tlds_added = 0
|
|
|
|
with open(input_file) as inf:
|
|
csv.register_dialect('import-tlds', delimiter=str(delimiter))
|
|
reader = csv.DictReader(inf,
|
|
fieldnames=['name', 'description'],
|
|
restkey='extra_fields',
|
|
dialect='import-tlds')
|
|
for line in reader:
|
|
# check if there are more than 2 fields
|
|
if 'extra_fields' in line:
|
|
error_lines.append("InvalidLine --> " +
|
|
self._convert_tld_dict_to_str(line))
|
|
else:
|
|
tlds_added += self._validate_and_create_tld(line,
|
|
error_lines)
|
|
|
|
LOG.info(_LI("Number of tlds added: %d") % tlds_added)
|
|
|
|
errors = len(error_lines)
|
|
if errors > 0:
|
|
LOG.error(_LE("Number of errors: %d") % errors)
|
|
# Sorting the errors and printing them so that it is easier to
|
|
# read the errors
|
|
LOG.error(_LE("Error Lines:\n%s") % '\n'.join(sorted(error_lines)))
|