[28848] in Source-Commits
moira commit [debian]: More testing.
daemon@ATHENA.MIT.EDU (Anders Kaseorg)
Wed Apr 25 23:50:22 2018
Date: Wed, 25 Apr 2018 23:49:59 -0400
From: Anders Kaseorg <andersk@mit.edu>
Message-Id: <201804260349.w3Q3nxqr025362@drugstore.mit.edu>
To: source-commits@mit.edu
https://github.com/mit-athena/moira/commit/1ba690ff4c45305d705b477a020a3f3a18c1cd45
commit 1ba690ff4c45305d705b477a020a3f3a18c1cd45
Author: Garry Zacheiss <zacheiss@mit.edu>
Date: Mon Sep 25 16:42:31 2017 -0400
More testing.
moira/clients/stella/stella.c | 77 +++++++++-----
moira/incremental/infoblox/infoblox.incr | 166 +++++++++++++++++++-----------
moira/man/stella.1 | 2 +-
moira/server/mr_server.h | 4 +-
moira/server/qaccess.pc | 33 ++++++
moira/server/qsetup.pc | 24 ++++-
moira/server/qsupport.pc | 122 ++++++++++++++++++++++
moira/server/queries2.c | 34 ++++++
8 files changed, 367 insertions(+), 95 deletions(-)
diff --git a/moira/clients/stella/stella.c b/moira/clients/stella/stella.c
index 0f68bd5..48face2 100644
--- a/moira/clients/stella/stella.c
+++ b/moira/clients/stella/stella.c
@@ -55,7 +55,7 @@ int list_container_flag, update_container_flag, unformatted_flag;
int list_identifier_flag, update_identifier_flag;
int list_resource_records_flag, update_resource_records_flag;
int set_host_opt_flag, set_ttl_flag, set_ptr_flag;
-int add_dynamic_host_flag, show_host_usage_flag;
+int add_dynamic_host_flag, show_host_usage_flag, upgrade_priv_addr_flag;
struct string_list *alias_add_queue, *alias_remove_queue;
struct string_list *address_add_queue, *address_remove_queue;
@@ -105,6 +105,7 @@ int main(int argc, char **argv)
list_container_flag = update_container_flag = list_resource_records_flag = 0;
list_identifier_flag = update_identifier_flag = show_host_usage_flag = 0;
set_host_opt_flag = set_ttl_flag = set_ptr_flag = add_dynamic_host_flag = 0;
+ upgrade_priv_addr_flag = 0;
newname = address = network = h_status = vendor = model = NULL;
os = location = contact = billing_contact = account_number = adm_cmt = NULL;
op_cmt = opt = NULL;
@@ -384,6 +385,8 @@ int main(int argc, char **argv)
list_resource_records_flag++;
else if (argis("su", "showusage"))
show_host_usage_flag++;
+ else if (argis("up4", "upgradeprivaddr"))
+ upgrade_priv_addr_flag++;
else if (argis("adh", "adddynamic")) {
add_dynamic_host_flag++;
if (arg - argv < argc - 1) {
@@ -439,7 +442,7 @@ int main(int argc, char **argv)
update_alias_flag || update_address_flag || update_container_flag || \
list_container_flag || update_identifier_flag || list_identifier_flag || \
update_resource_records_flag || list_resource_records_flag || set_host_opt_flag || \
- set_ttl_flag || set_ptr_flag || add_dynamic_host_flag || show_host_usage_flag)) {
+ set_ttl_flag || set_ptr_flag || add_dynamic_host_flag || show_host_usage_flag || upgrade_priv_addr_flag)) {
info_flag++;
}
@@ -448,7 +451,7 @@ int main(int argc, char **argv)
update_alias_flag || update_address_flag || update_container_flag || \
list_container_flag || update_identifier_flag || list_resource_records_flag || \
update_resource_records_flag || list_identifier_flag || set_host_opt_flag || \
- set_ttl_flag || set_ptr_flag || show_host_usage_flag))
+ set_ttl_flag || set_ptr_flag || show_host_usage_flag || upgrade_priv_addr_flag))
{
com_err(whoami, 0, "-adh / -adddynamic option must be the only argument provided.");
exit(1);
@@ -719,8 +722,9 @@ int main(int argc, char **argv)
}
}
- if (address_add_queue) {
- struct string_list *q = address_add_queue;
+ /* Need to process address removals first */
+ if (address_remove_queue) {
+ struct string_list *q = address_remove_queue;
while (q) {
/* string is of the form network:address */
@@ -729,27 +733,26 @@ int main(int argc, char **argv)
netaddr = mrcl_parse_netaddr(q->string);
if (!netaddr)
- {
- com_err(whoami, 0, "Could not parse network address specification while adding host address.");
- exit(1);
- }
+ {
+ com_err(whoami, 0, "Could not parse network address specification while removing host address.");
+ exit(1);
+ }
args[0] = canonicalize_hostname(strdup(hostname));
args[1] = netaddr->network;
args[2] = netaddr->address;
- status = wrap_mr_query("add_host_address", 3, args, NULL, NULL);
+ status = wrap_mr_query("delete_host_address", 3, args, NULL, NULL);
if (status) {
- com_err(whoami, status, "while adding host address");
- exit(1);
+ com_err(whoami, status, "while removing host address");
+ exit(1);
}
-
q = q->next;
}
}
- if (address_remove_queue) {
- struct string_list *q = address_remove_queue;
+ if (address_add_queue) {
+ struct string_list *q = address_add_queue;
while (q) {
/* string is of the form network:address */
@@ -759,7 +762,7 @@ int main(int argc, char **argv)
netaddr = mrcl_parse_netaddr(q->string);
if (!netaddr)
{
- com_err(whoami, 0, "Could not parse network address specification while removing host address.");
+ com_err(whoami, 0, "Could not parse network address specification while adding host address.");
exit(1);
}
@@ -767,11 +770,12 @@ int main(int argc, char **argv)
args[1] = netaddr->network;
args[2] = netaddr->address;
- status = wrap_mr_query("delete_host_address", 3, args, NULL, NULL);
+ status = wrap_mr_query("add_host_address", 3, args, NULL, NULL);
if (status) {
- com_err(whoami, status, "while removing host address");
+ com_err(whoami, status, "while adding host address");
exit(1);
}
+
q = q->next;
}
}
@@ -1102,6 +1106,21 @@ int main(int argc, char **argv)
}
}
+ /* upgrade private address */
+ if (upgrade_priv_addr_flag)
+ {
+ char *argv[1];
+
+ argv[0] = canonicalize_hostname(strdup(hostname));
+
+ status = wrap_mr_query("upgrade_host_private_ipv4_addr", 1, argv, NULL, NULL);
+ if (status)
+ if (status != MR_NO_MATCH) {
+ com_err(whoami, status, "while upgrading host private IPv4 address");
+ exit(1);
+ }
+ }
+
if (set_host_opt_flag) {
char *argv[3];
@@ -1310,7 +1329,9 @@ void usage(char **argv)
fprintf(stderr, USAGE_OPTIONS_FORMAT, "-arr | -addrecord record",
"-drr | -delrecord record");
fprintf(stderr, USAGE_OPTIONS_FORMAT, "-lrr | -listrecords",
- "-db | -database host[:port]");
+ "-up4 | -upgradeprivaddr");
+ fprintf(stderr, USAGE_OPTIONS_FORMAT, "-db | -database host[:port]",
+ "");
exit(1);
}
@@ -1344,10 +1365,8 @@ int show_address_info(int argc, char **argv, void *hint)
{
char tbuf[BUFSIZ];
- sprintf(tbuf, "%s:%s", argv[2], argv[3]);
- printf("Address: %-16s Network: %-16s", tbuf, argv[1]);
- if (atoi(argv[5]) == 1)
- printf(" PTR record: yes");
+ sprintf(tbuf, "%s:%s%s", argv[2], argv[3], atoi(argv[5]) == 1 ? "*" : "");
+ printf("Address: %-24s Network: %-16s", tbuf, argv[1]);
if (atoi(argv[4]) != DEFAULT_TTL)
printf(" DNS TTL: %-16s", argv[4]);
printf("\n");
@@ -1445,17 +1464,17 @@ void show_host_info(char **argv)
sprintf(tbuf, "%s %s", argv[M_OWNER_TYPE],
strcmp(argv[M_OWNER_TYPE], "NONE") ? argv[M_OWNER_NAME] : "");
- printf("Owner: %-16s Use data: %s\n", tbuf, argv[M_INUSE]);
- printf("Status: %-16s Changed: %s\n",
+ printf("Owner: %-24s Use data: %s\n", tbuf, argv[M_INUSE]);
+ printf("Status: %-24s Changed: %s\n",
MacState(atoi(argv[M_STAT])), argv[M_STAT_CHNG]);
printf("\n");
- printf("Vendor: %-16s Location: %s\n", argv[M_VENDOR],
+ printf("Vendor: %-24s Location: %s\n", argv[M_VENDOR],
argv[M_LOC]);
- printf("Model: %-16s Contact: %s\n", argv[M_MODEL],
+ printf("Model: %-24s Contact: %s\n", argv[M_MODEL],
argv[M_CONTACT]);
- printf("OS: %-16s Billing Contact: %s\n", argv[M_OS],
+ printf("OS: %-24s Billing Contact: %s\n", argv[M_OS],
argv[M_BILL_CONTACT]);
- printf("Opt: %-16s Account Number: %s\n", argv[M_USE],
+ printf("Opt: %-24s Account Number: %s\n", argv[M_USE],
argv[M_ACCT_NUMBER]);
printf("\nAdm cmt: %s\n", argv[M_ACOMMENT]);
printf("Op cmt: %s\n", argv[M_OCOMMENT]);
diff --git a/moira/incremental/infoblox/infoblox.incr b/moira/incremental/infoblox/infoblox.incr
index 6fe4de6..12e3550 100755
--- a/moira/incremental/infoblox/infoblox.incr
+++ b/moira/incremental/infoblox/infoblox.incr
@@ -125,9 +125,6 @@ def mach_to_ib(record):
ib_host_record = {
'name' : record[0].lower(),
- 'ttl' : default_ttl,
- 'use_ttl' : False,
- 'disable' : False,
'extattrs' : extattrs
}
@@ -196,9 +193,12 @@ def ib_create_host(record, myviews=None):
log('ib_search_by_name returned error, aborting')
return
- # For creation, use dummy IPs.
+ # For creation, use dummy v4 IP and default TTL.
ib_record['ipv4addrs'] = [ { 'ipv4addr' : '0.0.0.0' } ]
ib_record['ipv6addrs'] = [ ]
+ ib_record['ttl'] = default_ttl
+ ib_record['use_ttl'] = False
+ ib_record['disable'] = True
if myviews == None:
myviews = views
@@ -279,7 +279,7 @@ def ib_update_host(before, after):
critical_log('Record already exists in view %s for new name %s, old name %s' % (view, before_record['name'], after_record['name']))
elif len(mach_id_results[view]) == 0:
log('No record exists for mach id %s in view %s, creating' % (moira_mach_id, view))
- ib_create_host(after)
+ ib_create_host(after, myviews=view)
elif len(mach_id_results[view]) > 1:
critical_log('Mutiple records exist for mach_id %s in view %s, should not happen!' % (moira_mach_id, view))
elif mach_id_results[view][0]['extattrs']['moira_managed']['value'] != 1:
@@ -536,7 +536,11 @@ def ib_add_host_duid(record):
else:
search_result = search_results[view][0]
- ipv6addrs = [ { 'ipv6addr' : search_result['ipv6addrs'][0]['ipv6addr'] } ]
+ if 'ipv6addrs' in search_result and 'ipv6addr' in search_result['ipv6addrs'][0]:
+ ipv6addrs = [ { 'ipv6addr' : search_result['ipv6addrs'][0]['ipv6addr'] } ]
+ else:
+ ipv6addrs = [ {} ]
+
ipv6addrs[0]['duid'] = id_value
ipv6addrs[0]['configure_for_dhcp'] = True
@@ -593,7 +597,7 @@ def ib_add_host_mac(record):
log('Added %s %s to host %s in view %s: %s' % (id_type, id_value, ib_record['name'], view, r.text))
def ib_add_host_ipv4_address(record):
- ib_record = { 'name' : record[0].lower() }
+ ib_record = { 'name' : record[0].lower(), 'disable' : False }
ttl = int(record[4])
if ttl == default_ttl:
@@ -626,7 +630,7 @@ def ib_add_host_ipv4_address(record):
ipv4addrs = [ { 'ipv4addr' : address } ]
# preserve MAC address if assigned.
- if 'mac' in search_result['ipv4addrs'][0]:
+ if 'ipv4addrs' in search_result and 'mac' in search_result['ipv4addrs'][0]:
ipv4addrs[0]['mac'] = search_result['ipv4addrs'][0]['mac']
ipv4addrs[0]['configure_for_dhcp'] = True
@@ -644,7 +648,7 @@ def ib_add_host_ipv4_address(record):
log('Added IPv4 address %s to host %s in view %s: %s' % (address, ib_record['name'], view, r.text))
def ib_add_host_ipv6_address(record):
- ib_record = { 'name' : record[0].lower() }
+ ib_record = { 'name' : record[0].lower(), 'disable' : False }
ttl = int(record[4])
if ttl == default_ttl:
@@ -683,6 +687,10 @@ def ib_add_host_ipv6_address(record):
ib_record['ipv6addrs'] = ipv6addrs
+ # Handle v6 only case; if v4 address is set to 0.0.0.0, set it to empty array.
+ if 'ipv4addrs' in search_result and search_result['ipv4addrs'][0]['ipv4addr'] == '0.0.0.0':
+ ib_record['ipv4addrs'] = []
+
ib_ref = search_result['_ref']
ib_url = ib_base_url + '/' + ib_ref
headers = { 'Content-Type' : 'application/json' }
@@ -1091,7 +1099,10 @@ def ib_delete_host_duid(record):
else:
search_result = search_results[view][0]
- ipv6addrs = [ { 'ipv6addr' : search_result['ipv6addrs'][0]['ipv6addr'] } ]
+ if 'ipv6addrs' in search_result and 'ipv6addr' in search_result['ipv6addrs'][0]:
+ ipv6addrs = [ { 'ipv6addr' : search_result['ipv6addrs'][0]['ipv6addr'] } ]
+ else:
+ ipv6addrs = [ {} ]
if 'duid' in search_result['ipv6addrs'][0]:
if search_result['ipv6addrs'][0]['duid'] == id_value:
@@ -1178,11 +1189,16 @@ def ib_delete_host_ipv4_address(record):
# exactly one result, as expected.
search_result = search_results[view][0]
- ipv4addrs = [ { 'ipv4addr' : '0.0.0.0' } ]
- # preserve MAC address if assigned.
- if 'mac' in search_result['ipv4addrs'][0]:
- ipv4addrs[0]['mac'] = search_result['ipv4addrs'][0]['mac']
- ipv4addrs[0]['configure_for_dhcp'] = True
+ # Do we still have a v6 address assigned?
+ if 'ipv6addrs' in search_result and search_result['ipv6addrs'][0]['ipv6addr'] != '::':
+ ipv4addrs = []
+ else:
+ ipv4addrs = [ { 'ipv4addr' : '0.0.0.0' } ]
+ # preserve MAC address if assigned.
+ if 'mac' in search_result['ipv4addrs'][0]:
+ ipv4addrs[0]['mac'] = search_result['ipv4addrs'][0]['mac']
+ ipv4addrs[0]['configure_for_dhcp'] = True
+ ib_record['disable'] = True
ib_record['ipv4addrs'] = ipv4addrs
@@ -1219,18 +1235,26 @@ def ib_delete_host_ipv6_address(record):
ipv6addrs = [ ]
# preserve DUID if assigned.
if 'ipv6addrs' in search_result and 'duid' in search_result['ipv6addrs'][0]:
+ ipv6addrs[0] = {}
ipv6addrs[0]['duid'] = search_result['ipv6addrs'][0]['duid']
ipv6addrs[0]['configure_for_dhcp'] = True
ib_record['ipv6addrs'] = ipv6addrs
+ # Do we still have a valid v4 address?
+ if 'ipv4addrs' not in search_result:
+ ib_record['ipv4addrs'] = [ { 'ipv4addr' : '0.0.0.0' } ]
+ ib_record['disable'] = True
+ elif 'ipv4addrs' in search_result and search_result['ipv4addrs'][0]['ipv4addr'] == '0.0.0.0':
+ ib_record['disable'] = True
+
ib_ref = search_result['_ref']
ib_url = ib_base_url + '/' + ib_ref
headers = { 'Content-Type' : 'application/json' }
r = requests.put(ib_url, data=json.dumps(ib_record), headers=headers, auth=(ib_user, ib_passwd))
if r.status_code != requests.codes.ok:
- critical_log('Infoblox API call failed in ib_delete_host_ipv6_address for name %s address %s view %s' % (ib_record['name'], address, view))
+ critical_log('Infoblox API call failed in ib_delete_host_ipv6_address for name %s address %s view %s with HTTP return %s: %s' % (ib_record['name'], address, view, r.status_code, r.text))
continue
log('Deleted IPv6 address %s for host %s in view %s: %s' % (address, ib_record['name'], view, r.text))
@@ -1577,31 +1601,33 @@ def do_machine(before, after):
ib_add_aaaa_record(record)
# host records
- for record in get_moira_host_records(hostname):
+ for record in get_moira_hostrecords(hostname):
ib_add_hostrecord(record)
# mach identifiers
- for record in get_moira_mach_identifiers(hostname):
+ for record in get_moira_host_identifiers(hostname):
ib_add_host_identifier(record)
else:
for record in get_moira_hostaliases(hostname):
ib_add_cname(record)
else:
- # active before and after, update host record
- ib_update_host(before, after)
-
- # If hostname changed, need to handle other bits of information
+ # active before and after
before_hostname = before[0]
after_hostname = after[0]
- if before_hostname != after_hostname:
+ canon_before = canonical_for_hostname(before_hostname)
+ canon_after = canonical_for_hostname(after_hostname)
- canon_before = canonical_for_hostname(before_hostname)
- canon_after = canonical_for_hostname(after_hostname)
+ # If hostname changed, need to handle other bits of information
+ if before_hostname != after_hostname:
# If we're no longer canonical, delete the host object.
- if canon_before == True and canon_after == False:
+ if canon_before == True and canon_after == True:
+ ib_update_host(before, after)
+ elif canon_before == False and canon_after == True:
+ ib_create_host(after)
+ elif canon_after == False:
ib_delete_host(before)
# Host records
@@ -1609,8 +1635,9 @@ def do_machine(before, after):
if canon_after == True:
ib_add_hostrecord(record)
if canon_before == True:
- record[0] = before_hostname
- ib_delete_hostrecord(record)
+ recordlist = list(record)
+ recordlist[0] = before_hostname
+ ib_delete_hostrecord(recordlist)
# CNAMEs. Aliases directly associated with the host record
# will have moved as part of ib_update_host()
@@ -1618,13 +1645,15 @@ def do_machine(before, after):
if canon_before == True and canon_after == False:
ib_add_cname(record)
elif canon_before == False and canon_after == True:
+ recordlist = list(record)
+ recordlist[1] = before_hostname
+ ib_delete_cname(recordlist)
ib_add_host_alias(record)
- record[0] = before_hostname
- ib_delete_cname(record)
elif canon_before == False and canon_after == False:
ib_add_cname(record)
- record[0] = before_hostname
- ib_delete_cname(record)
+ recordlist = list(record)
+ recordlist[1] = before_hostname
+ ib_delete_cname(recordlist)
# Host addreses
for record in get_moira_hostaddresses(after_hostname):
@@ -1639,23 +1668,26 @@ def do_machine(before, after):
elif addr_type == 'IPV6':
ib_add_aaaa_record(record)
if canon_before == True:
- record[0] = before_hostname
+ recordlist = list(record)
+ recordlist[0] = before_hostname
if has_ptr == 0:
if addr_type == 'IPV4':
- ib_delete_a_record(record)
+ ib_delete_a_record(recordlist)
elif addr_type == 'IPV6':
- ib_delete_aaaa_record(record)
+ ib_delete_aaaa_record(recordlist)
+ else:
+ ib_update_host(before, after)
# Handle hostalias incremental
def do_hostalias(before, after):
# Add
if before == []:
hostname = after[1]
- if canonical_for_hostname(hostname) == True:
- ib_add_host_alias(after)
- else:
- status = int(get_moira_host_status(hostname))
- if status == 1:
+ status = int(get_moira_host_status(hostname))
+ if status == 1:
+ if canonical_for_hostname(hostname) == True:
+ ib_add_host_alias(after)
+ else:
ib_add_cname(after)
# Delete
elif after == []:
@@ -1663,9 +1695,7 @@ def do_hostalias(before, after):
if canonical_for_hostname(hostname) == True:
ib_delete_host_alias(before)
else:
- status = int(get_moira_host_status(hostname))
- if status == 1:
- ib_delete_cname(before)
+ ib_delete_cname(before)
# update case with both before and after not empty can't happen
# Handle hostaddress incremental
@@ -1675,7 +1705,8 @@ def do_hostaddress(before, after):
hostname = after[0]
has_ptr = int(after[5])
addr_type = after[2]
- if canonical_for_hostname(hostname) == True:
+ status = int(get_moira_host_status(hostname))
+ if status == 1 and canonical_for_hostname(hostname) == True:
if has_ptr == 1:
if addr_type == 'IPV4':
ib_add_host_ipv4_address(after)
@@ -1706,27 +1737,25 @@ def do_hostaddress(before, after):
ib_delete_a_record(before)
elif addr_type == 'IPV6':
ib_delete_aaaa_record(before)
- # Update - TTL or PTR bit might change, but never both at the same time.
+ # Update - TTL, PTR, or address might change, but only one at a time.
else:
hostname = after[0]
before_ptr = int(before[5])
after_ptr = int(after[5])
addr_type = after[2]
+ before_address = before[3]
+ after_address = after[3]
- if before_ptr == after_ptr:
- # if here, ttl must have changed.
- if after_ptr == 1:
- ib_set_host_ttl(after)
- else:
- status = int(get_moira_host_status(hostname))
- if status == 1:
- if addr_type == 'IPV4':
- ib_set_a_record_ttl(after)
- elif addr_type == 'IPV6':
- ib_set_aaaa_record_ttl(after)
- else:
+ status = int(get_moira_host_status(hostname))
+
+ if before_address != after_address:
+ # This can only change if we're upgrading a host to a public address.
+ # Otherwise it would be a delete and an add.
+ if status == 1:
+ ib_delete_host_ipv4_address(before)
+ ib_add_host_ipv4_address(after)
+ elif before_ptr != after_ptr:
# ptr bit changed.
- status = int(get_moira_host_status(hostname))
if status == 1:
if before_ptr == 0 and after_ptr == 1:
if addr_type == 'IPV4':
@@ -1742,6 +1771,16 @@ def do_hostaddress(before, after):
elif addr_type == 'IPV6':
ib_delete_host_ipv6_address(before)
ib_add_aaaa_record(after)
+ else:
+ # if here, ttl must have changed.
+ if status == 1:
+ if after_ptr == 1:
+ ib_set_host_ttl(after)
+ else:
+ if addr_type == 'IPV4':
+ ib_set_a_record_ttl(after)
+ elif addr_type == 'IPV6':
+ ib_set_aaaa_record_ttl(after)
# Handle hostrecord incremental
def do_hostrecord(before, after):
@@ -1766,11 +1805,14 @@ def do_hostrecord(before, after):
log('received incremental for unsupported DNS RR type %s' % (rr_type))
# Update - only thing that can change is TTL
else:
+ hostname = after[0]
rr_type = after[1]
- if rr_type in rr_types:
- ib_set_record_ttl(after)
- else:
- log('received incremental for unsupported DNS RR type %s' % (rr_type))
+ status = int(get_moira_host_status(hostname))
+ if status == 1 and canonical_for_hostname(hostname) == True:
+ if rr_type in rr_types:
+ ib_set_record_ttl(after)
+ else:
+ log('received incremental for unsupported DNS RR type %s' % (rr_type))
# Handle machidentifier incremental
def do_machidentifier(before, after):
diff --git a/moira/man/stella.1 b/moira/man/stella.1
index 257f857..a78a170 100644
--- a/moira/man/stella.1
+++ b/moira/man/stella.1
@@ -42,7 +42,7 @@ specified host. Unlike clusters, a machine may only belong to a
single container.
.IP \fB-addcontainer\ \fIcontainer\ \fRor\ \fB-acn\ \fIcontainer\fR
This will add the specified host to \fIcontainer\fR.
-.IP \fB-deletecontainer\ \fIcontainer\fRor \ \fB-dcn\ \fIcontainer\fR
+.IP \fB-deletecontainer\ \fIcontainer\ \fRor\ \fB-dcn\ \fIcontainer\fR
This will delete the specified host from \fIcontainer\fR.
.IP \fB-listidentifier\ \fRor\ \fB-lid\fR
diff --git a/moira/server/mr_server.h b/moira/server/mr_server.h
index 01d0f96..8a23a93 100644
--- a/moira/server/mr_server.h
+++ b/moira/server/mr_server.h
@@ -172,6 +172,7 @@ int access_adhr(struct query *q, char *argv[], client *cl);
int access_ahal(struct query *q, char *argv[], client *cl);
int access_ahad(struct query *q, char *argv[], client *cl);
int access_machidentifier(struct query *q, char *argv[], client *cl);
+int access_uhp4(struct query *q, char *argv[], client *cl);
int access_snt(struct query *q, char *argv[], client *cl);
int access_printer(struct query *q, char *argv[], client *cl);
int access_zephyr(struct query *q, char *argv[], client *cl);
@@ -270,6 +271,7 @@ int setup_ghst(struct query *q, char *argv[], client *cl);
int setup_ahst(struct query *q, char *argv[], client *cl);
int setup_ahal(struct query *q, char *argv[], client *cl);
int setup_ahad(struct query *q, char *argv[], client *cl);
+int setup_uhp4(struct query *q, char *argv[], client *cl);
int setup_srrt(struct query *q, char *argv[], client *cl);
int setup_shap(struct query *q, char *argv[], client *cl);
int setup_ahid(struct query *q, char *argv[], client *cl);
@@ -294,7 +296,7 @@ int do_user_reservation(struct query *q, char *argv[], client *cl);
int update_container(struct query *q, char *argv[], client *cl);
int set_container_list(struct query *q, char *argv[], client *cl);
int update_user_password_expiration(struct query *q, char *argv[], client *cl);
-
+int upgrade_host_private_ipv4_addr(struct query *q, char *argv[], client *cl);
int get_ace_use(struct query *q, char **argv, client *cl,
int (*action)(int, char *[], void *), void *actarg);
int get_host_by_owner(struct query *q, char **argv, client *cl,
diff --git a/moira/server/qaccess.pc b/moira/server/qaccess.pc
index abc3f58..4aacbbd 100644
--- a/moira/server/qaccess.pc
+++ b/moira/server/qaccess.pc
@@ -1045,6 +1045,39 @@ int access_machidentifier(struct query *q, char *argv[], client *cl)
return MR_PERM;
}
+int access_uhp4(struct query *q, char *argv[], client *cl)
+{
+ EXEC SQL BEGIN DECLARE SECTION;
+ int cnt, mid, sid, moid, soid;
+ char mtype[MACHINE_OWNER_TYPE_SIZE], stype[SUBNET_OWNER_TYPE_SIZE];
+ char address[HOSTADDRESS_ADDRESS_SIZE];
+ EXEC SQL END DECLARE SECTION;
+ int status;
+
+ mid = *(int *)argv[0];
+
+ /* Host owner? */
+ EXEC SQL SELECT m.owner_type, m.owner_id INTO :mtype, :moid FROM machine m where mach_id = :mid;
+ if (dbms_errno)
+ return mr_errcode;
+
+ status = find_member(mtype, moid,cl);
+ if (status)
+ return MR_SUCCESS;
+
+ /* Owner of subnet containing primary v4 address */
+ EXEC SQL SELECT s.owner_type, s.owner_id INTO :stype, :soid FROM hostaddress ha, subnet s
+ WHERE ha.mach_id = :mid AND ha.ptr = 1 AND ha.snet_id = s.snet_id AND s.addr_type = 'IPV4';
+ if (dbms_errno)
+ return mr_errcode;
+
+ status = find_member(stype, soid, cl);
+ if (status)
+ return MR_SUCCESS;
+
+ return MR_PERM;
+}
+
/* access_snt - check for retrieving network structure
*/
diff --git a/moira/server/qsetup.pc b/moira/server/qsetup.pc
index 5ce2f80..a90549a 100644
--- a/moira/server/qsetup.pc
+++ b/moira/server/qsetup.pc
@@ -1362,7 +1362,7 @@ int setup_ahst(struct query *q, char **argv, client *cl)
if (row == 1)
{
EXEC SQL SELECT COUNT(*) INTO :cnt FROM hostrecord
- WHERE mach_id = :id;
+ WHERE mach_id = :id AND rr_type = 'NS';
if (dbms_errno)
return mr_errcode;
if (cnt != 0)
@@ -1410,7 +1410,7 @@ int setup_ahal(struct query *q, char **argv, client *cl)
return MR_EXISTS;
/* No aliases if you have NS records / are a delegated zone */
- EXEC SQL SELECT count(mach_id) INTO :cnt FROM hostrecord hr, machine m
+ EXEC SQL SELECT count(*) INTO :cnt FROM hostrecord hr, machine m
WHERE m.name = UPPER(:name) AND m.mach_id = hr.mach_id AND hr.rr_type = 'NS';
if (dbms_errno)
return mr_errcode;
@@ -1670,6 +1670,26 @@ int setup_ahad(struct query *q, char **argv, client *cl)
return MR_SUCCESS;
}
+int setup_uhp4(struct query *q, char **argv, client *cl)
+{
+ EXEC SQL BEGIN DECLARE SECTION;
+ int cnt, mid;
+ EXEC SQL END DECLARE SECTION;
+
+ mid = *(int *)argv[0];
+
+ /* Host must have 1 IPv4 address marked as primary on a subnet ending in -PRIVATE */
+ EXEC SQL SELECT COUNT(*) INTO :cnt FROM hostaddress ha, subnet s WHERE
+ ha.mach_id = :mid and ha.ptr = 1 AND ha.snet_id = s.snet_id AND s.addr_type = 'IPV4'
+ AND s.name LIKE '%-PRIVATE';
+ if (dbms_errno)
+ return mr_errcode;
+ if (cnt != 1)
+ return MR_ADDRESS;
+
+ return MR_SUCCESS;
+}
+
int setup_srrt(struct query *q, char **argv, client *cl)
{
char *p;
diff --git a/moira/server/qsupport.pc b/moira/server/qsupport.pc
index d690a03..04843b2 100644
--- a/moira/server/qsupport.pc
+++ b/moira/server/qsupport.pc
@@ -2966,3 +2966,125 @@ int add_dynamic_host_record(struct query *q, char *argv[], client *cl,
return MR_SUCCESS;
}
+
+int upgrade_host_private_ipv4_addr(struct query *q, char *argv[], client *cl)
+{
+ EXEC SQL BEGIN DECLARE SECTION;
+ int cnt, mid, sid, public_sid, mask, table, ttl;
+ char sname[SUBNET_NAME_SIZE], public_sname[SUBNET_NAME_SIZE];
+ char address[HOSTADDRESS_ADDRESS_SIZE], public_address[HOSTADDRESS_ADDRESS_SIZE];
+ char saddr[SUBNET_SADDR_SIZE], high[SUBNET_HIGH_SIZE], low[SUBNET_LOW_SIZE];
+ char buf[INET_ADDRSTRLEN];
+ EXEC SQL END DECLARE SECTION;
+ struct sockaddr_in sa, saddr_sa, mask_sa, low_sa, high_sa;
+ unsigned int isaddr, imask, ihigh, ilow, value;
+ int status;
+ char *maskstr, *incr_argv[3];;
+
+ mid = *(int *)argv[0];
+ table = q->rtable;
+
+ /* Get existing private address. This must return only one row if we got this far. */
+ EXEC SQL SELECT ha.address, s.name, s.snet_id, ha.ttl INTO :address, :sname, :sid, :ttl
+ FROM hostaddress ha, subnet s WHERE ha.mach_id = :mid AND ha.ptr = 1
+ AND ha.snet_id = s.snet_id AND s.addr_type = 'IPV4'
+ AND s.name LIKE '%-PRIVATE';
+ if (dbms_errno)
+ return mr_errcode;
+
+ strmove(address, strtrim(address));
+ strmove(sname, strtrim(sname));
+
+ /* Get informtion for corresponding public subnet */
+ strcpy(public_sname, sname);
+ public_sname[strlen(sname) - strlen("-PRIVATE")] = '\0';
+ EXEC SQL SELECT snet_id INTO :public_sid FROM SUBNET WHERE name = :public_sname;
+ if (dbms_errno)
+ return mr_errcode;
+
+ /* Generate a unique address on the public subnet */
+ EXEC SQL SELECT saddr, mask, low, high INTO :saddr, :mask, :low, :high FROM subnet
+ WHERE snet_id = :public_sid;
+ if (dbms_errno)
+ return mr_errcode;
+
+ /* First, convert subnet strings into something we can work with */
+ if (inet_pton(AF_INET, strtrim(saddr), &(saddr_sa.sin_addr)) < 1)
+ return MR_ADDRESS;
+
+ /* mask - bit size, not string */
+ maskstr = masksize_to_mask("IPV4", mask);
+ if (!maskstr)
+ return MR_ADDRESS;
+
+ if (inet_pton(AF_INET, maskstr, &(mask_sa.sin_addr)) < 1)
+ return MR_ADDRESS;
+
+ if (inet_pton(AF_INET, strtrim(low), &(low_sa.sin_addr)) < 1)
+ return MR_ADDRESS;
+
+ if (inet_pton(AF_INET, strtrim(high), &(high_sa.sin_addr)) < 1)
+ return MR_ADDRESS;
+
+ isaddr = ntohl(saddr_sa.sin_addr.s_addr);
+ imask = ntohl(mask_sa.sin_addr.s_addr);
+ ilow = ntohl(low_sa.sin_addr.s_addr);
+ ihigh = ntohl(high_sa.sin_addr.s_addr);
+
+ for (value = ilow; value <= ihigh; value++)
+ {
+ if (((value & 0xff) == 0) || ((value & 0xff) == 255))
+ continue;
+
+ sa.sin_addr.s_addr = htonl(value);
+ if (inet_ntop(AF_INET, &(sa.sin_addr), buf, INET_ADDRSTRLEN) == NULL)
+ return MR_ADDRESS;
+
+ EXEC SQL SELECT COUNT(mach_id) INTO :cnt FROM hostaddress
+ WHERE address = :buf;
+ if (dbms_errno)
+ return mr_errcode;
+ if (cnt == 0)
+ break;
+ }
+
+ if (cnt != 0)
+ return MR_NO_ID;
+ else
+ strcpy(public_address, buf);
+
+ /* Build "before" incremental argv */
+ incr_argv[0] = xmalloc(0);
+ status = id_to_name(mid, MACHINE_TABLE, &incr_argv[0]);
+ if (status)
+ return status;
+
+ incr_argv[1] = address;
+ incr_argv[2] = sname;
+
+ incremental_before(table, NULL, incr_argv);
+
+ /* Delete old host address record */
+ EXEC SQL DELETE FROM hostaddress WHERE mach_id = :mid
+ AND address = :address AND snet_id = :sid;
+ if (dbms_errno)
+ return mr_errcode;
+
+ /* Insert new record */
+ EXEC SQL INSERT INTO HOSTADDRESS (mach_id, snet_id, address, ttl, ptr)
+ VALUES (:mid, :public_sid, :public_address, :ttl, 1);
+ if (dbms_errno)
+ return mr_errcode;
+
+ /* Build "after" incremental argv, argv[0] remains the same */
+ incr_argv[1] = public_address;
+ incr_argv[2] = public_sname;
+
+ incremental_after(table, NULL, incr_argv);
+
+ status = set_mach_modtime_by_id(q, argv, cl);
+ if (status)
+ return status;
+
+ return MR_SUCCESS;
+}
diff --git a/moira/server/queries2.c b/moira/server/queries2.c
index 9d7314f..26384bb 100644
--- a/moira/server/queries2.c
+++ b/moira/server/queries2.c
@@ -2305,6 +2305,22 @@ static struct validate dhad_validate = {
followup_dhad,
};
+static char *uhp4_fields[] = {
+ "name",
+};
+
+static struct validate uhp4_validate = {
+ VOmach0,
+ 1,
+ 0,
+ 0,
+ 0,
+ "mach_id",
+ access_uhp4,
+ setup_uhp4,
+ upgrade_host_private_ipv4_addr,
+};
+
static char *ghrr_fields[] = {
"name", "rr_type",
"name", "rr_type", "rr_value", "ttl",
@@ -7700,6 +7716,24 @@ struct query Queries[] = {
},
{
+ /* Q_UPGRADE_HOST_PRIVATE_IPV4_ADDR */
+ "upgrade_host_private_ipv4_addr",
+ "uhp4",
+ 17,
+ MR_Q_UPDATE,
+ 0,
+ HOSTADDRESS_TABLE,
+ 0,
+ uhp4_fields,
+ 1,
+ 1,
+ NULL,
+ 0,
+ NULL,
+ &uhp4_validate,
+ },
+
+ {
/* Q_DHAD - DELETE_HOST_ADDRESS */
"delete_host_address",
"dhad",