예제 #1
0
def ComputeChange(current, to_be_imported, replace_all=False):
    """Returns a change for importing the given record-sets.

  Args:
    current: dict, (name, type) keyed dict of current record-sets.
    to_be_imported: dict, (name, type) keyed dict of record-sets to be imported.
    replace_all: bool, Whether the record-sets to be imported should replace the
      current record-sets.

  Raises:
    ToolException: If conflicting CNAME records are found.

  Returns:
    A Change that describes the actions required to import the given
    record-sets.
  """
    change = messages.Change()
    change.additions = []
    change.deletions = []

    current_keys = set(current.keys())
    keys_to_be_imported = set(to_be_imported.keys())

    intersecting_keys = current_keys.intersection(keys_to_be_imported)
    if not replace_all and intersecting_keys:
        raise exceptions.ToolException(
            'Conflicting records for the following (name type): {0}'.format([
                _NameAndType(current[key]) for key in sorted(intersecting_keys)
            ]))

    for key in intersecting_keys:
        current_record = current[key]
        record_to_be_imported = to_be_imported[key]
        rdtype = rdatatype.from_text(key[1])
        replacement = _RDATA_REPLACEMENTS[rdtype](current_record,
                                                  record_to_be_imported)
        if replacement:
            change.deletions.append(current_record)
            change.additions.append(replacement)

    for key in keys_to_be_imported.difference(current_keys):
        change.additions.append(to_be_imported[key])

    for key in current_keys.difference(keys_to_be_imported):
        current_record = current[key]
        rdtype = rdatatype.from_text(key[1])
        if rdtype is rdatatype.SOA:
            change.deletions.append(current_record)
            change.additions.append(NextSOARecordSet(current_record))
        elif replace_all and rdtype is not rdatatype.NS:
            change.deletions.append(current_record)

    # If the only change is an SOA increment, there is nothing to be done.
    if IsOnlySOAIncrement(change):
        return None

    change.additions.sort(key=_NameAndType)
    change.deletions.sort(key=_NameAndType)
    return change
예제 #2
0
def ChangeFromYamlFile(yaml_file):
    """Returns the change contained in the given yaml file.

  Args:
    yaml_file: file, A yaml file with change.

  Returns:
    Change, the change contained in the given yaml file.
  """
    change_dict = yaml.safe_load(yaml_file)
    change = messages.Change()
    change.additions = _RecordSetsFromDictionaries(change_dict['additions'])
    change.deletions = _RecordSetsFromDictionaries(change_dict['deletions'])
    return change
def ChangeFromYamlFile(yaml_file):
    """Returns the change contained in the given yaml file.

  Args:
    yaml_file: file, A yaml file with change.

  Returns:
    Change, the change contained in the given yaml file.

  Raises:
    CorruptedTransactionFileError: if the record_set_dictionaries are invalid
  """
    try:
        change_dict = yaml.safe_load(yaml_file) or {}
    except yaml.error.YAMLError:
        raise CorruptedTransactionFileError()
    if (change_dict.get('additions') is None
            or change_dict.get('deletions') is None):
        raise CorruptedTransactionFileError()
    change = messages.Change()
    change.additions = _RecordSetsFromDictionaries(change_dict['additions'])
    change.deletions = _RecordSetsFromDictionaries(change_dict['deletions'])
    return change