def create_network(self, net_view_name, cidr, nameservers=None, members=None, gateway_ip=None, dhcp_trel_ip=None, network_extattrs=None): """Create NIOS Network.""" options = [] if nameservers: options.append( obj.DhcpOption(name='domain-name-servers', value=",".join(nameservers))) if gateway_ip: options.append(obj.DhcpOption(name='routers', value=gateway_ip)) if dhcp_trel_ip: options.append( obj.DhcpOption(name='dhcp-server-identifier', num=54, value=dhcp_trel_ip)) return obj.Network.create(self.connector, network_view=net_view_name, cidr=cidr, members=members, options=options, extattrs=network_extattrs, check_if_exists=False)
def create_network(self, net_view_name, cidr, nameservers=None, members=None, gateway_ip=None, dhcp_trel_ip=None, network_extattrs=None): """Create NIOS Network.""" # NIOS does not allow to set Dhcp options for IPv6 over WAPI, # so limit options usage with IPv4 only ipv4 = ib_utils.determine_ip_version(cidr) == 4 options = [] if nameservers: options.append( obj.DhcpOption(name='domain-name-servers', value=",".join(nameservers))) if ipv4 and gateway_ip: options.append(obj.DhcpOption(name='routers', value=gateway_ip)) if ipv4 and dhcp_trel_ip: options.append( obj.DhcpOption(name='dhcp-server-identifier', num=54, value=dhcp_trel_ip)) return obj.Network.create(self.connector, network_view=net_view_name, cidr=cidr, members=members, options=options, extattrs=network_extattrs, check_if_exists=False)
def update_subnet_details(self, ib_network): ea_network = eam.get_ea_for_network(self.ib_cxt.user_id, self.ib_cxt.tenant_id, self.ib_cxt.tenant_name, self.ib_cxt.network, self.ib_cxt.subnet) nameservers = self.ib_cxt.mapping.ib_nameservers if nameservers: nameservers_option_val = ','.join(nameservers) opt_dns = [ opt for opt in ib_network.options if opt.name == 'domain-name-servers' ] if opt_dns: opt_dns[0].value = nameservers_option_val else: ib_network.options.append( ib_objects.DhcpOption(name='domain-name-servers', value=nameservers_option_val)) else: ib_network.options = [ opt for opt in ib_network.options if opt.name != 'domain-name-servers' ] self.ib_cxt.ibom.update_network_options(ib_network, ea_network) self._restart_services()
def update_nameservers(self, dhcp_port_ip): # if user provies nameservers, no need to do anything nameservers = self.subnet.get('dns_nameservers') or [] if nameservers: return if (self.grid_config.relay_support is False or utils.is_valid_ip(dhcp_port_ip) is False): return cidr = self.subnet['cidr'] ib_network = self.ibom.get_network(self.mapping.network_view, cidr) if not ib_network: LOG.error("Infoblox network with %s does not exist.", cidr) return opt_dns = [ opt for opt in ib_network.options if opt.name == 'domain-name-servers' ] if not opt_dns: ib_network.options.append( ib_objects.DhcpOption(name='domain-name-servers', value=dhcp_port_ip)) else: opt_dns[0].value = dhcp_port_ip ib_network.update()
def create_network(self, net_view_name, cidr, nameservers=None, members=None, gateway_ip=None, dhcp_trel_ip=None, network_extattrs=None): """Create NIOS Network and prepare DHCP options. Some DHCP options are valid for IPv4 only, so just skip processing them for IPv6 case. :param net_view_name: network view name :param cidr: network to allocate, example '172.23.23.0/24' :param nameservers: list of name servers hosts/ip :param members: list of objects.AnyMember objects that are expected to serve dhcp for created network :param gateway_ip: gateway ip for the network (valid for IPv4 only) :param dhcp_trel_ip: ip address of dhcp relay (valid for IPv4 only) :param network_extattrs: extensible attributes for network (instance of objects.EA) :returns: created network (instance of objects.Network) """ ipv4 = ib_utils.determine_ip_version(cidr) == 4 options = [] if nameservers: options.append( obj.DhcpOption(name='domain-name-servers', value=",".join(nameservers))) if ipv4 and gateway_ip: options.append(obj.DhcpOption(name='routers', value=gateway_ip)) if ipv4 and dhcp_trel_ip: options.append( obj.DhcpOption(name='dhcp-server-identifier', num=54, value=dhcp_trel_ip)) return obj.Network.create(self.connector, network_view=net_view_name, cidr=cidr, members=members, options=options, extattrs=network_extattrs, check_if_exists=False)
def test_get_router_ips_from_ib_network(self): connector = mock.Mock() test_ib_network = ib_objects.NetworkV4(connector, network_view='test-view', cidr='12.12.1.0/24') test_ib_network.options = [ ib_objects.DhcpOption(name='routers', value='192.168.1.1,192.168.1.2')] member_ips = utils.get_router_ips(test_ib_network) self.assertEqual("192.168.1.1", member_ips[0]) self.assertEqual("192.168.1.2", member_ips[1])
def _test_reserve_service_members_with_ib_network_without_dhcp_member( self, dns_support): user_id = 'test user' tenant_id = '90fbad5a098a4b7cb98826128d5b40b3' # prepare network network_name = 'Test Network' network = self.plugin_stub.create_network(tenant_id, network_name) # prepare subnet subnet_name = 'Test Subnet' subnet_cidr = '11.11.1.0/24' subnet = self.plugin_stub.create_subnet(tenant_id, subnet_name, network['id'], subnet_cidr) self.grid_config.dhcp_support = True self.grid_config.dns_support = dns_support ib_cxt = ib_context.InfobloxContext(self.ctx, user_id, network, subnet, self.grid_config, self.plugin) ib_cxt._register_services = mock.Mock() # ib network with dhcp member and gateway ips assigned connector = mock.Mock() test_ib_network = ib_objects.NetworkV4(connector, network_view='test-view', cidr='12.12.1.0/24') test_ib_network.members = [ ib_objects.AnyMember( _struct='dhcpmember', name=ib_cxt.mapping.authority_member.member_name) ] test_gateway_ip = '12.12.1.1' test_ib_network.options = [ ib_objects.DhcpOption(name='routers', value=test_gateway_ip) ] ib_cxt.reserve_service_members(test_ib_network) expected_dns_members = ([ib_cxt.mapping.authority_member] if dns_support else []) # authority member is CPM, so dhcp/dns member should be the same as # authority member self.assertEqual([ib_cxt.mapping.authority_member], ib_cxt.mapping.dhcp_members) self.assertEqual(expected_dns_members, ib_cxt.mapping.dns_members) actual_opt_router = [ opt for opt in test_ib_network.options if opt.name == 'routers' ] self.assertEqual(subnet['gateway_ip'] + ',' + test_gateway_ip, actual_opt_router[0].value)
def _test_reserve_service_members_with_ib_network_with_dhcp_member( self, test_dhcp_member, dns_support, expected_dns_members): user_id = 'test user' tenant_id = '90fbad5a098a4b7cb98826128d5b40b3' # prepare network network_name = 'Test Network' network = self.plugin_stub.create_network(tenant_id, network_name) # prepare subnet subnet_name = 'Test Subnet' subnet_cidr = '11.11.1.0/24' subnet = self.plugin_stub.create_subnet(tenant_id, subnet_name, network['id'], subnet_cidr) self.grid_config.dhcp_support = True self.grid_config.dns_support = dns_support ib_cxt = ib_context.InfobloxContext(self.ctx, user_id, network, subnet, self.grid_config, self.plugin) ib_cxt._register_services = mock.Mock() ib_cxt._get_dhcp_members = mock.Mock(return_value=[test_dhcp_member]) ib_cxt._get_dns_members = mock.Mock(return_value=[test_dhcp_member]) # ib network with dhcp member assigned connector = mock.Mock() test_ib_network = ib_objects.NetworkV4(connector, network_view='test-view', cidr='12.12.1.0/24') test_ib_network.members = [ ib_objects.AnyMember(_struct='dhcpmember', name=test_dhcp_member.member_name, ipv4addr=test_dhcp_member.member_ip) ] test_ib_network.options = [ ib_objects.DhcpOption(name='domain-name-servers', value=test_dhcp_member.member_ip) ] ib_cxt.reserve_service_members(test_ib_network) self.assertEqual([test_dhcp_member], ib_cxt.mapping.dhcp_members) self.assertEqual(expected_dns_members, ib_cxt.mapping.dns_members) actual_opt_router = [ opt for opt in test_ib_network.options if opt.name == 'routers' ] self.assertEqual(subnet['gateway_ip'], actual_opt_router[0].value)
def reserve_service_members(self, ib_network=None): """Reserve DHCP and DNS service members. For the predefined network, dhcp member(s) may be assigned. If assigned, then we need to get them from ib_network.members. For dns member(s), ib_network.options may contain them. If no dhcp member is assigned, then we will pick an available member. If no dns member is assigned, the dhcp member will serve dns as well. If network is not predefined, we need to assign service members. If the authority member is CPM, dhcp/dns members are the same as the authority member. If the authority member is GM, we need to pick an available dhcp member. For simplicity, we will use the dhcp member to serve dns as well. More detailed reason for such dns member assignment logic is explained below. For a host record, a primary dns member must be the same as dhcp member because both dhcp and dns record must be created under the same parent which is the network view. To simplify dns member assignment logic, we will always pick the dns member to be the same as dhcp member. Only exception to this would be the predefined networks that are created from NIOS side. """ if self.grid_config.dhcp_support is False: return if self.mapping.authority_member is None: raise exc.InfobloxAuthorityMemberNotReserved( network_view=self.mapping.network_view) dhcp_members = [] dns_members = [] nameservers = [] if ib_network is None: # service member assignment for a new network dhcp_member = self._reserve_dhcp_member() dhcp_members = [dhcp_member] if self.grid_config.dns_support: dns_members = dhcp_members nameservers = self._get_nameservers(dhcp_members) else: # service member assignment for the predefined network # - first set dhcp servers option dhcp_members = self._get_dhcp_members(ib_network) if not dhcp_members: dhcp_member = self._reserve_dhcp_member() dhcp_ip = dhcp_member.member_dhcp_ip or dhcp_member.member_ip dhcp_members = [dhcp_member] # assign dhcp member ib_network.members = [ ib_objects.AnyMember(_struct='dhcpmember', name=dhcp_member.member_name, ipv4addr=dhcp_ip) ] if self.grid_config.dns_support: # - then set dns servers option dns_members = self._get_dns_members(ib_network) if not dns_members: # for CPM as authority member, only one dhcp member can be # assigned and dns member needs to be the same as dhcp # member for host record. # for GM as authority member, multiple dhcp members can be # assigned but the first dhcp member will serve as the grid # primary and the rest will serve as the grid secondaries. dns_members = dhcp_members nameservers = self._get_nameservers(dns_members) else: nameservers = self._get_nameservers(dhcp_members) nameservers_option_val = ','.join(nameservers) opt_dns = [ opt for opt in ib_network.options if opt.name == 'domain-name-servers' ] if not opt_dns: ib_network.options.append( ib_objects.DhcpOption(name='domain-name-servers', value=nameservers_option_val)) else: opt_dns[0].value = nameservers_option_val # - lastly set routers option if self.subnet['ip_version'] == 4: gateway_ip_str = str(self.subnet.get('gateway_ip')) opt_routers = [ opt for opt in ib_network.options if opt.name == 'routers' ] if not opt_routers: ib_network.options.append( ib_objects.DhcpOption(name='routers', value=gateway_ip_str)) else: router_ips = opt_routers[0].value.split(',') router_ips_all = ( [gateway_ip_str] + [ip for ip in router_ips if ip != gateway_ip_str]) opt_routers[0].value = ','.join(router_ips_all) ib_dhcp_members = [] for m in dhcp_members: dhcp_ip = m.member_dhcp_ip or m.member_ip ib_dhcp_members.append( ib_objects.AnyMember(_struct='dhcpmember', name=m.member_name, ipv4addr=dhcp_ip)) self.mapping.dhcp_members = dhcp_members self.mapping.dns_members = dns_members self.mapping.ib_dhcp_members = ib_dhcp_members self.mapping.ib_nameservers = nameservers self._register_services()