mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
DNS Locations: dnsserver-* commands
New commands for manipulation with DNS server configuration were added: * dnsserver-show * dnsserver-mod * dnsserver-find https://fedorahosted.org/bind-dyndb-ldap/wiki/Design/PerServerConfigInLDAP https://fedorahosted.org/freeipa/ticket/2008 Reviewed-By: Petr Spacek <pspacek@redhat.com> Reviewed-By: Jan Cholasta <jcholast@redhat.com>
This commit is contained in:
4
ACI.txt
4
ACI.txt
@@ -63,6 +63,10 @@ aci: (targetattr = "createtimestamp || entryusn || idnsallowsyncptr || idnsforwa
|
|||||||
dn: dc=ipa,dc=example
|
dn: dc=ipa,dc=example
|
||||||
aci: (targetattr = "idnsallowsyncptr || idnsforwarders || idnsforwardpolicy || idnspersistentsearch || idnszonerefresh")(target = "ldap:///cn=dns,dc=ipa,dc=example")(targetfilter = "(objectclass=idnsConfigObject)")(version 3.0;acl "permission:System: Write DNS Configuration";allow (write) groupdn = "ldap:///cn=System: Write DNS Configuration,cn=permissions,cn=pbac,dc=ipa,dc=example";)
|
aci: (targetattr = "idnsallowsyncptr || idnsforwarders || idnsforwardpolicy || idnspersistentsearch || idnszonerefresh")(target = "ldap:///cn=dns,dc=ipa,dc=example")(targetfilter = "(objectclass=idnsConfigObject)")(version 3.0;acl "permission:System: Write DNS Configuration";allow (write) groupdn = "ldap:///cn=System: Write DNS Configuration,cn=permissions,cn=pbac,dc=ipa,dc=example";)
|
||||||
dn: dc=ipa,dc=example
|
dn: dc=ipa,dc=example
|
||||||
|
aci: (targetattr = "idnsforwarders || idnsforwardpolicy || idnssoamname || idnssubstitutionvariable")(targetfilter = "(objectclass=idnsServerConfigObject)")(version 3.0;acl "permission:System: Modify DNS Servers Configuration";allow (write) groupdn = "ldap:///cn=System: Modify DNS Servers Configuration,cn=permissions,cn=pbac,dc=ipa,dc=example";)
|
||||||
|
dn: dc=ipa,dc=example
|
||||||
|
aci: (targetattr = "createtimestamp || entryusn || idnsforwarders || idnsforwardpolicy || idnsserverid || idnssoamname || idnssubstitutionvariable || modifytimestamp || objectclass")(targetfilter = "(objectclass=idnsServerConfigObject)")(version 3.0;acl "permission:System: Read DNS Servers Configuration";allow (compare,read,search) groupdn = "ldap:///cn=System: Read DNS Servers Configuration,cn=permissions,cn=pbac,dc=ipa,dc=example";)
|
||||||
|
dn: dc=ipa,dc=example
|
||||||
aci: (target = "ldap:///idnsname=*,cn=dns,dc=ipa,dc=example")(version 3.0;acl "permission:System: Add DNS Entries";allow (add) groupdn = "ldap:///cn=System: Add DNS Entries,cn=permissions,cn=pbac,dc=ipa,dc=example";)
|
aci: (target = "ldap:///idnsname=*,cn=dns,dc=ipa,dc=example")(version 3.0;acl "permission:System: Add DNS Entries";allow (add) groupdn = "ldap:///cn=System: Add DNS Entries,cn=permissions,cn=pbac,dc=ipa,dc=example";)
|
||||||
dn: dc=ipa,dc=example
|
dn: dc=ipa,dc=example
|
||||||
aci: (targetattr = "ipaprivatekey || ipapublickey || ipasecretkey || ipasecretkeyref || ipawrappingkey || ipawrappingmech || ipk11allowedmechanisms || ipk11alwaysauthenticate || ipk11alwayssensitive || ipk11checkvalue || ipk11copyable || ipk11decrypt || ipk11derive || ipk11destroyable || ipk11distrusted || ipk11encrypt || ipk11enddate || ipk11extractable || ipk11id || ipk11keygenmechanism || ipk11keytype || ipk11label || ipk11local || ipk11modifiable || ipk11neverextractable || ipk11private || ipk11publickeyinfo || ipk11sensitive || ipk11sign || ipk11signrecover || ipk11startdate || ipk11subject || ipk11trusted || ipk11uniqueid || ipk11unwrap || ipk11unwraptemplate || ipk11verify || ipk11verifyrecover || ipk11wrap || ipk11wraptemplate || ipk11wrapwithtrusted || objectclass")(target = "ldap:///cn=keys,cn=sec,cn=dns,dc=ipa,dc=example")(version 3.0;acl "permission:System: Manage DNSSEC keys";allow (all) groupdn = "ldap:///cn=System: Manage DNSSEC keys,cn=permissions,cn=pbac,dc=ipa,dc=example";)
|
aci: (targetattr = "ipaprivatekey || ipapublickey || ipasecretkey || ipasecretkeyref || ipawrappingkey || ipawrappingmech || ipk11allowedmechanisms || ipk11alwaysauthenticate || ipk11alwayssensitive || ipk11checkvalue || ipk11copyable || ipk11decrypt || ipk11derive || ipk11destroyable || ipk11distrusted || ipk11encrypt || ipk11enddate || ipk11extractable || ipk11id || ipk11keygenmechanism || ipk11keytype || ipk11label || ipk11local || ipk11modifiable || ipk11neverextractable || ipk11private || ipk11publickeyinfo || ipk11sensitive || ipk11sign || ipk11signrecover || ipk11startdate || ipk11subject || ipk11trusted || ipk11uniqueid || ipk11unwrap || ipk11unwraptemplate || ipk11verify || ipk11verifyrecover || ipk11wrap || ipk11wraptemplate || ipk11wrapwithtrusted || objectclass")(target = "ldap:///cn=keys,cn=sec,cn=dns,dc=ipa,dc=example")(version 3.0;acl "permission:System: Manage DNSSEC keys";allow (all) groupdn = "ldap:///cn=System: Manage DNSSEC keys,cn=permissions,cn=pbac,dc=ipa,dc=example";)
|
||||||
|
|||||||
65
API.txt
65
API.txt
@@ -1499,6 +1499,71 @@ arg: Str('name')
|
|||||||
arg: Str('value')
|
arg: Str('value')
|
||||||
option: Str('version?')
|
option: Str('version?')
|
||||||
output: Output('result')
|
output: Output('result')
|
||||||
|
command: dnsserver_add
|
||||||
|
args: 1,8,3
|
||||||
|
arg: Str('idnsserverid', cli_name='hostname')
|
||||||
|
option: Str('addattr*', cli_name='addattr')
|
||||||
|
option: Flag('all', autofill=True, cli_name='all', default=False)
|
||||||
|
option: Str('idnsforwarders*', cli_name='forwarder')
|
||||||
|
option: StrEnum('idnsforwardpolicy?', cli_name='forward_policy', values=[u'only', u'first', u'none'])
|
||||||
|
option: DNSNameParam('idnssoamname?', cli_name='soa_mname_override')
|
||||||
|
option: Flag('raw', autofill=True, cli_name='raw', default=False)
|
||||||
|
option: Str('setattr*', cli_name='setattr')
|
||||||
|
option: Str('version?')
|
||||||
|
output: Entry('result')
|
||||||
|
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
|
||||||
|
output: PrimaryKey('value')
|
||||||
|
command: dnsserver_del
|
||||||
|
args: 1,2,3
|
||||||
|
arg: Str('idnsserverid+', cli_name='hostname')
|
||||||
|
option: Flag('continue', autofill=True, cli_name='continue', default=False)
|
||||||
|
option: Str('version?')
|
||||||
|
output: Output('result', type=[<type 'dict'>])
|
||||||
|
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
|
||||||
|
output: ListOfPrimaryKeys('value')
|
||||||
|
command: dnsserver_find
|
||||||
|
args: 1,10,4
|
||||||
|
arg: Str('criteria?')
|
||||||
|
option: Flag('all', autofill=True, cli_name='all', default=False)
|
||||||
|
option: Str('idnsforwarders*', autofill=False, cli_name='forwarder')
|
||||||
|
option: StrEnum('idnsforwardpolicy?', autofill=False, cli_name='forward_policy', values=[u'only', u'first', u'none'])
|
||||||
|
option: Str('idnsserverid?', autofill=False, cli_name='hostname')
|
||||||
|
option: DNSNameParam('idnssoamname?', autofill=False, cli_name='soa_mname_override')
|
||||||
|
option: Flag('pkey_only?', autofill=True, default=False)
|
||||||
|
option: Flag('raw', autofill=True, cli_name='raw', default=False)
|
||||||
|
option: Int('sizelimit?', autofill=False)
|
||||||
|
option: Int('timelimit?', autofill=False)
|
||||||
|
option: Str('version?')
|
||||||
|
output: Output('count', type=[<type 'int'>])
|
||||||
|
output: ListOfEntries('result')
|
||||||
|
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
|
||||||
|
output: Output('truncated', type=[<type 'bool'>])
|
||||||
|
command: dnsserver_mod
|
||||||
|
args: 1,10,3
|
||||||
|
arg: Str('idnsserverid', cli_name='hostname')
|
||||||
|
option: Str('addattr*', cli_name='addattr')
|
||||||
|
option: Flag('all', autofill=True, cli_name='all', default=False)
|
||||||
|
option: Str('delattr*', cli_name='delattr')
|
||||||
|
option: Str('idnsforwarders*', autofill=False, cli_name='forwarder')
|
||||||
|
option: StrEnum('idnsforwardpolicy?', autofill=False, cli_name='forward_policy', values=[u'only', u'first', u'none'])
|
||||||
|
option: DNSNameParam('idnssoamname?', autofill=False, cli_name='soa_mname_override')
|
||||||
|
option: Flag('raw', autofill=True, cli_name='raw', default=False)
|
||||||
|
option: Flag('rights', autofill=True, default=False)
|
||||||
|
option: Str('setattr*', cli_name='setattr')
|
||||||
|
option: Str('version?')
|
||||||
|
output: Entry('result')
|
||||||
|
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
|
||||||
|
output: PrimaryKey('value')
|
||||||
|
command: dnsserver_show
|
||||||
|
args: 1,4,3
|
||||||
|
arg: Str('idnsserverid', cli_name='hostname')
|
||||||
|
option: Flag('all', autofill=True, cli_name='all', default=False)
|
||||||
|
option: Flag('raw', autofill=True, cli_name='raw', default=False)
|
||||||
|
option: Flag('rights', autofill=True, default=False)
|
||||||
|
option: Str('version?')
|
||||||
|
output: Entry('result')
|
||||||
|
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
|
||||||
|
output: PrimaryKey('value')
|
||||||
command: dnszone_add
|
command: dnszone_add
|
||||||
args: 1,28,3
|
args: 1,28,3
|
||||||
arg: DNSNameParam('idnsname', cli_name='name')
|
arg: DNSNameParam('idnsname', cli_name='name')
|
||||||
|
|||||||
4
VERSION
4
VERSION
@@ -90,5 +90,5 @@ IPA_DATA_VERSION=20100614120000
|
|||||||
# #
|
# #
|
||||||
########################################################
|
########################################################
|
||||||
IPA_API_VERSION_MAJOR=2
|
IPA_API_VERSION_MAJOR=2
|
||||||
IPA_API_VERSION_MINOR=185
|
IPA_API_VERSION_MINOR=186
|
||||||
# Last change: mbasti - added command dns-update-system-records
|
# Last change: mbasti - added dnsserver-* commands
|
||||||
|
|||||||
@@ -12,3 +12,9 @@ aci: (targetattr = "*")(version 3.0; acl "Allow read access"; allow (read,search
|
|||||||
aci: (target = "ldap:///idnsname=*,cn=dns,$SUFFIX")(version 3.0;acl "Add DNS entries in a zone";allow (add) userattr = "parent[1].managedby#GROUPDN";)
|
aci: (target = "ldap:///idnsname=*,cn=dns,$SUFFIX")(version 3.0;acl "Add DNS entries in a zone";allow (add) userattr = "parent[1].managedby#GROUPDN";)
|
||||||
aci: (target = "ldap:///idnsname=*,cn=dns,$SUFFIX")(version 3.0;acl "Remove DNS entries from a zone";allow (delete) userattr = "parent[1].managedby#GROUPDN";)
|
aci: (target = "ldap:///idnsname=*,cn=dns,$SUFFIX")(version 3.0;acl "Remove DNS entries from a zone";allow (delete) userattr = "parent[1].managedby#GROUPDN";)
|
||||||
aci: (targetattr = "a6record || aaaarecord || afsdbrecord || aplrecord || arecord || certrecord || cn || cnamerecord || dhcidrecord || dlvrecord || dnamerecord || dnsclass || dnsttl || dsrecord || hinforecord || hiprecord || idnsallowdynupdate || idnsallowquery || idnsallowsyncptr || idnsallowtransfer || idnsforwarders || idnsforwardpolicy || idnsname || idnssecinlinesigning || idnssoaexpire || idnssoaminimum || idnssoamname || idnssoarefresh || idnssoaretry || idnssoarname || idnssoaserial || idnsupdatepolicy || idnszoneactive || ipseckeyrecord || keyrecord || kxrecord || locrecord || mdrecord || minforecord || mxrecord || naptrrecord || nsecrecord || nsec3paramrecord || nsrecord || nxtrecord || ptrrecord || rprecord || rrsigrecord || sigrecord || spfrecord || srvrecord || sshfprecord || tlsarecord || txtrecord || unknownrecord ")(target = "ldap:///idnsname=*,cn=dns,$SUFFIX")(version 3.0;acl "Update DNS entries in a zone";allow (write) userattr = "parent[0,1].managedby#GROUPDN";)
|
aci: (targetattr = "a6record || aaaarecord || afsdbrecord || aplrecord || arecord || certrecord || cn || cnamerecord || dhcidrecord || dlvrecord || dnamerecord || dnsclass || dnsttl || dsrecord || hinforecord || hiprecord || idnsallowdynupdate || idnsallowquery || idnsallowsyncptr || idnsallowtransfer || idnsforwarders || idnsforwardpolicy || idnsname || idnssecinlinesigning || idnssoaexpire || idnssoaminimum || idnssoamname || idnssoarefresh || idnssoaretry || idnssoarname || idnssoaserial || idnsupdatepolicy || idnszoneactive || ipseckeyrecord || keyrecord || kxrecord || locrecord || mdrecord || minforecord || mxrecord || naptrrecord || nsecrecord || nsec3paramrecord || nsrecord || nxtrecord || ptrrecord || rprecord || rrsigrecord || sigrecord || spfrecord || srvrecord || sshfprecord || tlsarecord || txtrecord || unknownrecord ")(target = "ldap:///idnsname=*,cn=dns,$SUFFIX")(version 3.0;acl "Update DNS entries in a zone";allow (write) userattr = "parent[0,1].managedby#GROUPDN";)
|
||||||
|
|
||||||
|
dn: cn=servers,cn=dns,$SUFFIX
|
||||||
|
changetype: add
|
||||||
|
objectClass: nsContainer
|
||||||
|
objectClass: top
|
||||||
|
cn: servers
|
||||||
|
|||||||
@@ -33,3 +33,9 @@ default: nsslapd-plugintype: preoperation
|
|||||||
default: nsslapd-pluginvendor: Red Hat, Inc.
|
default: nsslapd-pluginvendor: Red Hat, Inc.
|
||||||
default: nsslapd-pluginversion: 1.0
|
default: nsslapd-pluginversion: 1.0
|
||||||
default: nsslapd-plugin-depends-on-type: database
|
default: nsslapd-plugin-depends-on-type: database
|
||||||
|
|
||||||
|
# add dns servers container
|
||||||
|
dn: cn=servers,cn=dns,$SUFFIX
|
||||||
|
default: objectClass: nsContainer
|
||||||
|
default: objectClass: top
|
||||||
|
default: cn: servers
|
||||||
|
|||||||
@@ -123,6 +123,7 @@ DEFAULT_CONFIG = (
|
|||||||
('container_caacl', DN(('cn', 'caacls'), ('cn', 'ca'))),
|
('container_caacl', DN(('cn', 'caacls'), ('cn', 'ca'))),
|
||||||
('container_locations', DN(('cn', 'locations'), ('cn', 'etc'))),
|
('container_locations', DN(('cn', 'locations'), ('cn', 'etc'))),
|
||||||
('container_ca', DN(('cn', 'cas'), ('cn', 'ca'))),
|
('container_ca', DN(('cn', 'cas'), ('cn', 'ca'))),
|
||||||
|
('container_dnsservers', DN(('cn', 'servers'), ('cn', 'dns'))),
|
||||||
|
|
||||||
# Ports, hosts, and URIs:
|
# Ports, hosts, and URIs:
|
||||||
('xmlrpc_uri', 'http://localhost:8888/ipa/xml'),
|
('xmlrpc_uri', 'http://localhost:8888/ipa/xml'),
|
||||||
|
|||||||
@@ -898,3 +898,56 @@ class classproperty(object):
|
|||||||
def getter(self, fget):
|
def getter(self, fget):
|
||||||
self.fget = fget
|
self.fget = fget
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
|
||||||
|
def normalize_hostname(hostname):
|
||||||
|
"""Use common fqdn form without the trailing dot"""
|
||||||
|
if hostname.endswith(u'.'):
|
||||||
|
hostname = hostname[:-1]
|
||||||
|
hostname = hostname.lower()
|
||||||
|
return hostname
|
||||||
|
|
||||||
|
|
||||||
|
def hostname_validator(ugettext, value):
|
||||||
|
try:
|
||||||
|
validate_hostname(value)
|
||||||
|
except ValueError as e:
|
||||||
|
return _('invalid domain-name: %s') % unicode(e)
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def ipaddr_validator(ugettext, ipaddr, ip_version=None):
|
||||||
|
try:
|
||||||
|
ip = netaddr.IPAddress(str(ipaddr), flags=netaddr.INET_PTON)
|
||||||
|
|
||||||
|
if ip_version is not None:
|
||||||
|
if ip.version != ip_version:
|
||||||
|
return _(
|
||||||
|
'invalid IP address version (is %(value)d, must be '
|
||||||
|
'%(required_value)d)!') % dict(
|
||||||
|
value=ip.version,
|
||||||
|
required_value=ip_version
|
||||||
|
)
|
||||||
|
except (netaddr.AddrFormatError, ValueError):
|
||||||
|
return _('invalid IP address format')
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def validate_bind_forwarder(ugettext, forwarder):
|
||||||
|
ip_address, sep, port = forwarder.partition(u' port ')
|
||||||
|
|
||||||
|
ip_address_validation = ipaddr_validator(ugettext, ip_address)
|
||||||
|
|
||||||
|
if ip_address_validation is not None:
|
||||||
|
return ip_address_validation
|
||||||
|
|
||||||
|
if sep:
|
||||||
|
try:
|
||||||
|
port = int(port)
|
||||||
|
if port < 0 or port > 65535:
|
||||||
|
raise ValueError()
|
||||||
|
except ValueError:
|
||||||
|
return _('%(port)s is not a valid port' % dict(port=port))
|
||||||
|
|
||||||
|
return None
|
||||||
|
|||||||
@@ -66,7 +66,9 @@ from ipalib.util import (normalize_zonemgr,
|
|||||||
EDNS0UnsupportedError, DNSSECValidationError,
|
EDNS0UnsupportedError, DNSSECValidationError,
|
||||||
validate_dnssec_zone_forwarder_step1,
|
validate_dnssec_zone_forwarder_step1,
|
||||||
validate_dnssec_zone_forwarder_step2,
|
validate_dnssec_zone_forwarder_step2,
|
||||||
verify_host_resolvable)
|
verify_host_resolvable,
|
||||||
|
validate_bind_forwarder,
|
||||||
|
ipaddr_validator)
|
||||||
from ipapython.dn import DN
|
from ipapython.dn import DN
|
||||||
from ipapython.ipautil import CheckedIPAddress
|
from ipapython.ipautil import CheckedIPAddress
|
||||||
from ipapython.dnsutil import check_zone_overlap
|
from ipapython.dnsutil import check_zone_overlap
|
||||||
@@ -373,23 +375,12 @@ def _reverse_zone_name(netstr):
|
|||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def _validate_ipaddr(ugettext, ipaddr, ip_version=None):
|
|
||||||
try:
|
|
||||||
ip = netaddr.IPAddress(str(ipaddr), flags=netaddr.INET_PTON)
|
|
||||||
|
|
||||||
if ip_version is not None:
|
|
||||||
if ip.version != ip_version:
|
|
||||||
return _('invalid IP address version (is %(value)d, must be %(required_value)d)!') \
|
|
||||||
% dict(value=ip.version, required_value=ip_version)
|
|
||||||
except (netaddr.AddrFormatError, ValueError):
|
|
||||||
return _('invalid IP address format')
|
|
||||||
return None
|
|
||||||
|
|
||||||
def _validate_ip4addr(ugettext, ipaddr):
|
def _validate_ip4addr(ugettext, ipaddr):
|
||||||
return _validate_ipaddr(ugettext, ipaddr, 4)
|
return ipaddr_validator(ugettext, ipaddr, 4)
|
||||||
|
|
||||||
def _validate_ip6addr(ugettext, ipaddr):
|
def _validate_ip6addr(ugettext, ipaddr):
|
||||||
return _validate_ipaddr(ugettext, ipaddr, 6)
|
return ipaddr_validator(ugettext, ipaddr, 6)
|
||||||
|
|
||||||
def _validate_ipnet(ugettext, ipnet):
|
def _validate_ipnet(ugettext, ipnet):
|
||||||
try:
|
try:
|
||||||
@@ -457,24 +448,6 @@ def _normalize_bind_aci(bind_acis):
|
|||||||
acis += u';'
|
acis += u';'
|
||||||
return acis
|
return acis
|
||||||
|
|
||||||
def _validate_bind_forwarder(ugettext, forwarder):
|
|
||||||
ip_address, sep, port = forwarder.partition(u' port ')
|
|
||||||
|
|
||||||
ip_address_validation = _validate_ipaddr(ugettext, ip_address)
|
|
||||||
|
|
||||||
if ip_address_validation is not None:
|
|
||||||
return ip_address_validation
|
|
||||||
|
|
||||||
if sep:
|
|
||||||
try:
|
|
||||||
port = int(port)
|
|
||||||
if port < 0 or port > 65535:
|
|
||||||
raise ValueError()
|
|
||||||
except ValueError:
|
|
||||||
return _('%(port)s is not a valid port' % dict(port=port))
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
def _validate_nsec3param_record(ugettext, value):
|
def _validate_nsec3param_record(ugettext, value):
|
||||||
_nsec3param_pattern = (r'^(?P<alg>\d+) (?P<flags>\d+) (?P<iter>\d+) '
|
_nsec3param_pattern = (r'^(?P<alg>\d+) (?P<flags>\d+) (?P<iter>\d+) '
|
||||||
r'(?P<salt>([0-9a-fA-F]{2})+|-)$')
|
r'(?P<salt>([0-9a-fA-F]{2})+|-)$')
|
||||||
@@ -2001,7 +1974,7 @@ class DNSZoneBase(LDAPObject):
|
|||||||
attribute=True,
|
attribute=True,
|
||||||
),
|
),
|
||||||
Str('idnsforwarders*',
|
Str('idnsforwarders*',
|
||||||
_validate_bind_forwarder,
|
validate_bind_forwarder,
|
||||||
cli_name='forwarder',
|
cli_name='forwarder',
|
||||||
label=_('Zone forwarders'),
|
label=_('Zone forwarders'),
|
||||||
doc=_('Per-zone forwarders. A custom port can be specified '
|
doc=_('Per-zone forwarders. A custom port can be specified '
|
||||||
@@ -4043,7 +4016,7 @@ class dnsconfig(LDAPObject):
|
|||||||
|
|
||||||
takes_params = (
|
takes_params = (
|
||||||
Str('idnsforwarders*',
|
Str('idnsforwarders*',
|
||||||
_validate_bind_forwarder,
|
validate_bind_forwarder,
|
||||||
cli_name='forwarder',
|
cli_name='forwarder',
|
||||||
label=_('Global forwarders'),
|
label=_('Global forwarders'),
|
||||||
doc=_('Global forwarders. A custom port can be specified for each '
|
doc=_('Global forwarders. A custom port can be specified for each '
|
||||||
|
|||||||
183
ipaserver/plugins/dnsserver.py
Normal file
183
ipaserver/plugins/dnsserver.py
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2016 FreeIPA Contributors see COPYING for license
|
||||||
|
#
|
||||||
|
|
||||||
|
from __future__ import absolute_import
|
||||||
|
|
||||||
|
from ipalib import (
|
||||||
|
_,
|
||||||
|
ngettext,
|
||||||
|
api,
|
||||||
|
DNSNameParam,
|
||||||
|
Str,
|
||||||
|
StrEnum,
|
||||||
|
)
|
||||||
|
from ipalib.frontend import Local
|
||||||
|
from ipalib.plugable import Registry
|
||||||
|
from ipalib.util import (
|
||||||
|
normalize_hostname,
|
||||||
|
hostname_validator,
|
||||||
|
validate_bind_forwarder,
|
||||||
|
)
|
||||||
|
from ipaserver.plugins.baseldap import (
|
||||||
|
LDAPObject,
|
||||||
|
LDAPRetrieve,
|
||||||
|
LDAPUpdate,
|
||||||
|
LDAPSearch,
|
||||||
|
LDAPCreate,
|
||||||
|
LDAPDelete,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
__doc__ = _("""
|
||||||
|
DNS server configuration
|
||||||
|
""") + _("""
|
||||||
|
Manipulate DNS server configuration
|
||||||
|
""") + _("""
|
||||||
|
EXAMPLES:
|
||||||
|
""") + _("""
|
||||||
|
Show configuration of a specific DNS server:
|
||||||
|
ipa dnsserver-show
|
||||||
|
""") + _("""
|
||||||
|
Update configuration of a specific DNS server:
|
||||||
|
ipa dnsserver-mod
|
||||||
|
""")
|
||||||
|
|
||||||
|
|
||||||
|
register = Registry()
|
||||||
|
|
||||||
|
dnsserver_object_class = ['top', 'idnsServerConfigObject']
|
||||||
|
|
||||||
|
@register()
|
||||||
|
class dnsserver(LDAPObject):
|
||||||
|
"""
|
||||||
|
DNS Servers
|
||||||
|
"""
|
||||||
|
container_dn = api.env.container_dnsservers
|
||||||
|
object_name = _('DNS server')
|
||||||
|
object_name_plural = _('DNS servers')
|
||||||
|
object_class = dnsserver_object_class
|
||||||
|
default_attributes = [
|
||||||
|
'idnsServerId',
|
||||||
|
'idnsSOAmName',
|
||||||
|
'idnsForwarders',
|
||||||
|
'idnsForwardPolicy',
|
||||||
|
]
|
||||||
|
label = _('DNS Servers')
|
||||||
|
label_singular = _('DNS Server')
|
||||||
|
|
||||||
|
permission_filter_objectclasses = ['idnsServerConfigObject']
|
||||||
|
|
||||||
|
managed_permissions = {
|
||||||
|
'System: Read DNS Servers Configuration': {
|
||||||
|
'ipapermright': {'read', 'search', 'compare'},
|
||||||
|
'ipapermdefaultattr': {
|
||||||
|
'objectclass',
|
||||||
|
'idnsServerId',
|
||||||
|
'idnsSOAmName',
|
||||||
|
'idnsForwarders',
|
||||||
|
'idnsForwardPolicy',
|
||||||
|
'idnsSubstitutionVariable',
|
||||||
|
},
|
||||||
|
'ipapermlocation': api.env.basedn,
|
||||||
|
'default_privileges': {
|
||||||
|
'DNS Servers',
|
||||||
|
'DNS Administrators'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'System: Modify DNS Servers Configuration': {
|
||||||
|
'ipapermright': {'write'},
|
||||||
|
'ipapermdefaultattr': {
|
||||||
|
'idnsSOAmName',
|
||||||
|
'idnsForwarders',
|
||||||
|
'idnsForwardPolicy',
|
||||||
|
'idnsSubstitutionVariable',
|
||||||
|
},
|
||||||
|
'ipapermlocation': api.env.basedn,
|
||||||
|
'default_privileges': {'DNS Administrators'},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
takes_params = (
|
||||||
|
Str(
|
||||||
|
'idnsserverid',
|
||||||
|
hostname_validator,
|
||||||
|
cli_name='hostname',
|
||||||
|
primary_key=True,
|
||||||
|
label=_('Server name'),
|
||||||
|
doc=_('DNS Server name'),
|
||||||
|
normalizer=normalize_hostname,
|
||||||
|
),
|
||||||
|
DNSNameParam(
|
||||||
|
'idnssoamname?',
|
||||||
|
cli_name='soa_mname_override',
|
||||||
|
label=_('SOA mname override'),
|
||||||
|
doc=_('SOA mname (authoritative server) override'),
|
||||||
|
),
|
||||||
|
Str(
|
||||||
|
'idnsforwarders*',
|
||||||
|
validate_bind_forwarder,
|
||||||
|
cli_name='forwarder',
|
||||||
|
label=_('Forwarders'),
|
||||||
|
doc=_(
|
||||||
|
'Per-server forwarders. A custom port can be specified '
|
||||||
|
'for each forwarder using a standard format '
|
||||||
|
'"IP_ADDRESS port PORT"'
|
||||||
|
),
|
||||||
|
),
|
||||||
|
StrEnum(
|
||||||
|
'idnsforwardpolicy?',
|
||||||
|
cli_name='forward_policy',
|
||||||
|
label=_('Forward policy'),
|
||||||
|
doc=_(
|
||||||
|
'Per-server conditional forwarding policy. Set to "none" to '
|
||||||
|
'disable forwarding to global forwarder for this zone. In '
|
||||||
|
'that case, conditional zone forwarders are disregarded.'
|
||||||
|
),
|
||||||
|
values=(u'only', u'first', u'none'),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@register()
|
||||||
|
class dnsserver_mod(LDAPUpdate):
|
||||||
|
__doc__ = _('Modify DNS server configuration')
|
||||||
|
|
||||||
|
msg_summary = _('Modified DNS server "%(value)s"')
|
||||||
|
|
||||||
|
|
||||||
|
@register()
|
||||||
|
class dnsserver_find(LDAPSearch):
|
||||||
|
__doc__ = _('Search for DNS servers.')
|
||||||
|
|
||||||
|
msg_summary = ngettext(
|
||||||
|
'%(count)d DNS server matched',
|
||||||
|
'%(count)d DNS servers matched', 0
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@register()
|
||||||
|
class dnsserver_show(LDAPRetrieve):
|
||||||
|
__doc__=_('Display configuration of a DNS server.')
|
||||||
|
|
||||||
|
|
||||||
|
@register()
|
||||||
|
class dnsserver_add(LDAPCreate, Local):
|
||||||
|
"""
|
||||||
|
Only for internal use, this is not part of public API on purpose.
|
||||||
|
Be careful in future this will be transformed to public API call
|
||||||
|
"""
|
||||||
|
__doc__ = _('Add a new DNS server.')
|
||||||
|
|
||||||
|
msg_summary = _('Added new DNS server "%(value)s"')
|
||||||
|
|
||||||
|
|
||||||
|
@register()
|
||||||
|
class dnsserver_del(LDAPDelete, Local):
|
||||||
|
"""
|
||||||
|
Only for internal use, this is not part of public API on purpose.
|
||||||
|
Be careful in future this will be transformed to public API call
|
||||||
|
"""
|
||||||
|
__doc__ = _('Delete a DNS server')
|
||||||
|
|
||||||
|
msg_summary = _('Deleted DNS server "%(value)s"')
|
||||||
@@ -44,10 +44,13 @@ from ipalib import x509
|
|||||||
from ipalib import output
|
from ipalib import output
|
||||||
from ipalib.request import context
|
from ipalib.request import context
|
||||||
from ipalib.util import (normalize_sshpubkey, validate_sshpubkey_no_options,
|
from ipalib.util import (normalize_sshpubkey, validate_sshpubkey_no_options,
|
||||||
convert_sshpubkey_post, validate_hostname,
|
convert_sshpubkey_post,
|
||||||
add_sshpubkey_to_attrs_pre,
|
add_sshpubkey_to_attrs_pre,
|
||||||
remove_sshpubkey_from_output_post,
|
remove_sshpubkey_from_output_post,
|
||||||
remove_sshpubkey_from_output_list_post)
|
remove_sshpubkey_from_output_list_post,
|
||||||
|
normalize_hostname,
|
||||||
|
hostname_validator,
|
||||||
|
)
|
||||||
from ipapython.ipautil import ipa_generate_password, CheckedIPAddress
|
from ipapython.ipautil import ipa_generate_password, CheckedIPAddress
|
||||||
from ipapython.dnsutil import DNSName
|
from ipapython.dnsutil import DNSName
|
||||||
from ipapython.ssh import SSHPublicKey
|
from ipapython.ssh import SSHPublicKey
|
||||||
@@ -271,23 +274,6 @@ def validate_ipaddr(ugettext, ipaddr):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def normalize_hostname(hostname):
|
|
||||||
"""Use common fqdn form without the trailing dot"""
|
|
||||||
if hostname.endswith(u'.'):
|
|
||||||
hostname = hostname[:-1]
|
|
||||||
hostname = hostname.lower()
|
|
||||||
return hostname
|
|
||||||
|
|
||||||
|
|
||||||
def _hostname_validator(ugettext, value):
|
|
||||||
try:
|
|
||||||
validate_hostname(value)
|
|
||||||
except ValueError as e:
|
|
||||||
return _('invalid domain-name: %s') % unicode(e)
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
@register()
|
@register()
|
||||||
class host(LDAPObject):
|
class host(LDAPObject):
|
||||||
"""
|
"""
|
||||||
@@ -465,7 +451,7 @@ class host(LDAPObject):
|
|||||||
label_singular = _('Host')
|
label_singular = _('Host')
|
||||||
|
|
||||||
takes_params = (
|
takes_params = (
|
||||||
Str('fqdn', _hostname_validator,
|
Str('fqdn', hostname_validator,
|
||||||
cli_name='hostname',
|
cli_name='hostname',
|
||||||
label=_('Host name'),
|
label=_('Host name'),
|
||||||
primary_key=True,
|
primary_key=True,
|
||||||
@@ -734,7 +720,7 @@ class host_del(LDAPDelete):
|
|||||||
def pre_callback(self, ldap, dn, *keys, **options):
|
def pre_callback(self, ldap, dn, *keys, **options):
|
||||||
assert isinstance(dn, DN)
|
assert isinstance(dn, DN)
|
||||||
# If we aren't given a fqdn, find it
|
# If we aren't given a fqdn, find it
|
||||||
if _hostname_validator(None, keys[-1]) is not None:
|
if hostname_validator(None, keys[-1]) is not None:
|
||||||
hostentry = api.Command['host_show'](keys[-1])['result']
|
hostentry = api.Command['host_show'](keys[-1])['result']
|
||||||
fqdn = hostentry['fqdn'][0]
|
fqdn = hostentry['fqdn'][0]
|
||||||
else:
|
else:
|
||||||
@@ -1093,7 +1079,7 @@ class host_disable(LDAPQuery):
|
|||||||
ldap = self.obj.backend
|
ldap = self.obj.backend
|
||||||
|
|
||||||
# If we aren't given a fqdn, find it
|
# If we aren't given a fqdn, find it
|
||||||
if _hostname_validator(None, keys[-1]) is not None:
|
if hostname_validator(None, keys[-1]) is not None:
|
||||||
hostentry = api.Command['host_show'](keys[-1])['result']
|
hostentry = api.Command['host_show'](keys[-1])['result']
|
||||||
fqdn = hostentry['fqdn'][0]
|
fqdn = hostentry['fqdn'][0]
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -237,6 +237,7 @@ class server_mod(LDAPUpdate):
|
|||||||
if not result.get('value'):
|
if not result.get('value'):
|
||||||
self.add_message(messages.AutomaticDNSRecordsUpdateFailed())
|
self.add_message(messages.AutomaticDNSRecordsUpdateFailed())
|
||||||
self.obj.convert_location(entry_attrs, **options)
|
self.obj.convert_location(entry_attrs, **options)
|
||||||
|
|
||||||
return dn
|
return dn
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user