def update_network(self, context, id, network): """Update Quantum network. Update an existing Quantum network and its corresponding MidoNet bridge. """ LOG.debug( _("MidonetPluginV2.update_network called: id=%(id)r, " "network=%(network)r"), { 'id': id, 'network': network }) # Reject admin_state_up=False if network['network'].get('admin_state_up') and network['network'][ 'admin_state_up'] is False: raise q_exc.NotImplementedError( _('admin_state_up=False ' 'networks are not ' 'supported.')) session = context.session with session.begin(subtransactions=True): net = super(MidonetPluginV2, self).update_network(context, id, network) self.client.update_bridge(id, net['name']) self._extend_network_dict_l3(context, net) LOG.debug(_("MidonetPluginV2.update_network exiting: net=%r"), net) return net
def _port_view(self, request, tenant_id, network_id, port_id): """Returns udp port info for a given port""" if not hasattr(self._plugin, "get_udp_port"): return faults.Quantum11HTTPError( qexception.NotImplementedError("get_udp_port")) udp_port = self._plugin.get_udp_port(tenant_id, network_id, port_id) return dict(udp_port)
def _port_view(self, request, tenant_id, network_id, port_id): """Returns udp port info for a given port""" if not hasattr(self._plugin, "get_port_attrs"): return faults.Quantum11HTTPError( qexception.NotImplementedError("get_port_attrs")) meta = self._plugin.get_port_attrs(tenant_id, network_id, port_id) return {'attributes': meta, 'id': port_id}
def create_subnet(self, context, subnet): """Create Quantum subnet. Creates a Quantum subnet and a DHCP entry in MidoNet bridge. """ LOG.debug(_("MidonetPluginV2.create_subnet called: subnet=%r"), subnet) if subnet['subnet']['ip_version'] == 6: raise q_exc.NotImplementedError(_("MidoNet doesn't support IPv6.")) net = super(MidonetPluginV2, self).get_network(context, subnet['subnet']['network_id'], fields=None) if net['subnets']: raise q_exc.NotImplementedError( _("MidoNet doesn't support multiple subnets " "on the same network.")) session = context.session with session.begin(subtransactions=True): sn_entry = super(MidonetPluginV2, self).create_subnet(context, subnet) bridge = self.client.get_bridge(sn_entry['network_id']) gateway_ip = subnet['subnet']['gateway_ip'] network_address, prefix = subnet['subnet']['cidr'].split('/') self.client.create_dhcp(bridge, gateway_ip, network_address, prefix) # For external network, link the bridge to the provider router. self._extend_network_dict_l3(context, net) if net['router:external']: gateway_ip = sn_entry['gateway_ip'] network_address, length = sn_entry['cidr'].split('/') self.client.link_bridge_to_provider_router( bridge, self.provider_router, gateway_ip, network_address, length) LOG.debug(_("MidonetPluginV2.create_subnet exiting: sn_entry=%r"), sn_entry) return sn_entry
def _show(self, request, tenant_id, network_id, port_id): """Returns port statistics for a given port""" if not hasattr(self._plugin, "get_port_stats"): return faults.QuantumHTTPError( qexception.NotImplementedError("get_port_stats")) stats = self._plugin.get_port_stats(tenant_id, network_id, port_id) builder = portstats_view.get_view_builder(request) result = builder.build(stats, True) return dict(stats=result)
def test_create_network_quota_no_counts(self): cfg.CONF.set_override('quota_network', 1, group='QUOTAS') initial_input = {'network': {'name': 'net1', 'tenant_id': _uuid()}} full_input = {'network': {'admin_state_up': True, 'subnets': []}} full_input['network'].update(initial_input['network']) instance = self.plugin.return_value instance.get_networks_count.side_effect = (q_exc.NotImplementedError()) instance.get_networks.return_value = ["foo"] res = self.api.post_json(_get_path('networks'), initial_input, expect_errors=True) instance.get_networks_count.assert_called_with(mock.ANY, filters=mock.ANY) self.assertTrue( "Quota exceeded for resources" in res.json['QuantumError'])
def get_ports_count(self, context, filters=None): """Return the number of ports. The result depends on the identity of the user making the request (as indicated by the context) as well as any filters. : param context: quantum api request context : param filters: a dictionary with keys that are valid keys for a network as listed in the RESOURCE_ATTRIBUTE_MAP object in quantum/api/v2/attributes.py. Values in this dictiontary are an iterable containing values that will be used for an exact match comparison for that value. Each result returned by this function will have matched one of the values for each key in filters. NOTE: this method is optional, as it was not part of the originally defined plugin API. """ raise exceptions.NotImplementedError()
def update_network(self, context, id, network): """ Updates the properties of a particular Virtual Network. :returns: a sequence of mappings with the following signature: {'id': UUID representing the network. 'name': Human-readable name identifying the network. 'tenant_id': Owner of network. only admin user can specify a tenant_id other than its own. 'admin_state_up': Sets admin state of network. if down, network does not forward packets. 'status': Indicates whether network is currently operational (limit values to "ACTIVE", "DOWN", "BUILD", and "ERROR"? 'subnets': Subnets associated with this network. Plan to allow fully specified subnets as part of network create. } :raises: exception.NetworkNotFound :raises: exception.NoImplementedError """ if network["network"].get("admin_state_up"): if network['network']["admin_state_up"] is False: raise exception.NotImplementedError("admin_state_up=False " "networks are not " "supported.") params = {} params["network"] = network["network"] pairs = self._get_lswitch_cluster_pairs(id, context.tenant_id) #Only field to update in NVP is name if network['network'].get("name"): for (cluster, switches) in pairs: for switch in switches: result = nvplib.update_network(cluster, switch, **params) LOG.debug("update_network() completed for tenant: %s" % context.tenant_id) return super(NvpPluginV2, self).update_network(context, id, network)
def get_floatingips_count(self, context, filters=None): raise qexception.NotImplementedError()
def update_router(self, context, id, router): LOG.debug( _("MidonetPluginV2.update_router called: id=%(id)s " "router=%(router)r"), router) if router['router'].get('admin_state_up') is False: raise q_exc.NotImplementedError( _('admin_state_up=False ' 'routers are not ' 'supported.')) op_gateway_set = False op_gateway_clear = False # figure out which operation it is in if ('external_gateway_info' in router['router'] and 'network_id' in router['router']['external_gateway_info']): op_gateway_set = True elif ('external_gateway_info' in router['router'] and router['router']['external_gateway_info'] == {}): op_gateway_clear = True qports = super(MidonetPluginV2, self).get_ports(context, { 'device_id': [id], 'device_owner': ['network:router_gateway'] }) assert len(qports) == 1 qport = qports[0] snat_ip = qport['fixed_ips'][0]['ip_address'] qport['network_id'] session = context.session with session.begin(subtransactions=True): qrouter = super(MidonetPluginV2, self).update_router(context, id, router) changed_name = router['router'].get('name') if changed_name: self.client.update_router(id, changed_name) if op_gateway_set: # find a qport with the network_id for the router qports = super(MidonetPluginV2, self).get_ports(context, { 'device_id': [id], 'device_owner': ['network:router_gateway'] }) assert len(qports) == 1 qport = qports[0] snat_ip = qport['fixed_ips'][0]['ip_address'] self.client.set_router_external_gateway( id, self.provider_router, snat_ip) if op_gateway_clear: self.client.clear_router_external_gateway(id) LOG.debug(_("MidonetPluginV2.update_router exiting: qrouter=%r"), qrouter) return qrouter
def notimplemented_function(self, request, id): return faults.Quantum10HTTPError( exceptions.NotImplementedError("notimplemented_function"))
def create_subnet(self, context, subnet): """Create Quantum subnet. Creates a Quantum subnet and a DHCP entry in MidoNet bridge. """ LOG.debug(_("MidonetPluginV2.create_subnet called: subnet=%r"), subnet) if subnet['subnet']['ip_version'] == 6: raise q_exc.NotImplementedError(_("MidoNet doesn't support IPv6.")) net = super(MidonetPluginV2, self).get_network(context, subnet['subnet']['network_id'], fields=None) if net['subnets']: raise q_exc.NotImplementedError( _("MidoNet doesn't support multiple subnets " "on the same network.")) session = context.session with session.begin(subtransactions=True): sn_entry = super(MidonetPluginV2, self).create_subnet(context, subnet) try: bridge = self.mido_api.get_bridge(sn_entry['network_id']) except w_exc.HTTPNotFound: raise MidonetResourceNotFound(resource_type='Bridge', id=sn_entry['network_id']) gateway_ip = subnet['subnet']['gateway_ip'] network_address, prefix = subnet['subnet']['cidr'].split('/') bridge.add_dhcp_subnet().default_gateway(gateway_ip).subnet_prefix( network_address).subnet_length(prefix).create() # If the network is external, link the bridge to MidoNet provider # router self._extend_network_dict_l3(context, net) if net['router:external']: gateway_ip = sn_entry['gateway_ip'] network_address, length = sn_entry['cidr'].split('/') # create a interior port in the MidoNet provider router in_port = self.provider_router.add_interior_port() pr_port = in_port.port_address(gateway_ip).network_address( network_address).network_length(length).create() # create a interior port in the bridge, then link # it to the provider router. br_port = bridge.add_interior_port().create() pr_port.link(br_port.get_id()) # add a route for the subnet in the provider router self.provider_router.add_route().type( 'Normal').src_network_addr('0.0.0.0').src_network_length( 0).dst_network_addr( network_address).dst_network_length(length).weight( 100).next_hop_port(pr_port.get_id()).create() LOG.debug(_("MidonetPluginV2.create_subnet exiting: sn_entry=%r"), sn_entry) return sn_entry
def update_router(self, context, id, router): LOG.debug( _("MidonetPluginV2.update_router called: id=%(id)s " "router=%(router)r"), router) if router['router'].get('admin_state_up') is False: raise q_exc.NotImplementedError( _('admin_state_up=False ' 'routers are not ' 'supported.')) op_gateway_set = False op_gateway_clear = False # figure out which operation it is in if ('external_gateway_info' in router['router'] and 'network_id' in router['router']['external_gateway_info']): op_gateway_set = True elif ('external_gateway_info' in router['router'] and router['router']['external_gateway_info'] == {}): op_gateway_clear = True qports = super(MidonetPluginV2, self).get_ports(context, { 'device_id': [id], 'device_owner': ['network:router_gateway'] }) assert len(qports) == 1 qport = qports[0] snat_ip = qport['fixed_ips'][0]['ip_address'] qport['network_id'] session = context.session with session.begin(subtransactions=True): qrouter = super(MidonetPluginV2, self).update_router(context, id, router) changed_name = router['router'].get('name') if changed_name: self.mido_api.get_router(id).name(changed_name).update() tenant_router = self.mido_api.get_router(id) if op_gateway_set: # find a qport with the network_id for the router qports = super(MidonetPluginV2, self).get_ports(context, { 'device_id': [id], 'device_owner': ['network:router_gateway'] }) assert len(qports) == 1 qport = qports[0] snat_ip = qport['fixed_ips'][0]['ip_address'] in_port = self.provider_router.add_interior_port() pr_port = in_port.network_address( '169.254.255.0').network_length(30).port_address( '169.254.255.1').create() # Create a port in the tenant router tr_port = tenant_router.add_interior_port().network_address( '169.254.255.0').network_length(30).port_address( '169.254.255.2').create() # Link them pr_port.link(tr_port.get_id()) # Add a route for snat_ip to bring it down to tenant self.provider_router.add_route().type( 'Normal').src_network_addr('0.0.0.0').src_network_length( 0).dst_network_addr(snat_ip).dst_network_length( 32).weight(100).next_hop_port( pr_port.get_id()).create() # Add default route to uplink in the tenant router tenant_router.add_route().type('Normal').src_network_addr( '0.0.0.0').src_network_length(0).dst_network_addr( '0.0.0.0').dst_network_length(0).weight( 100).next_hop_port(tr_port.get_id()).create() # ADD SNAT(masquerade) rules chains = self.chain_manager.get_router_chains( tenant_router.get_tenant_id(), tenant_router.get_id()) chains['in'].add_rule().nw_dst_address(snat_ip).nw_dst_length( 32).type('rev_snat').flow_action('accept').in_ports([ tr_port.get_id() ]).properties(SNAT_RULE_PROPERTY).position(1).create() nat_targets = [] nat_targets.append({ 'addressFrom': snat_ip, 'addressTo': snat_ip, 'portFrom': 1, 'portTo': 65535 }) chains['out'].add_rule().type('snat').flow_action( 'accept').nat_targets(nat_targets).out_ports([ tr_port.get_id() ]).properties(SNAT_RULE_PROPERTY).position(1).create() if op_gateway_clear: # delete the port that is connected to provider router for p in tenant_router.get_ports(): if p.get_port_address() == '169.254.255.2': peer_port_id = p.get_peer_id() p.unlink() self.mido_api.get_port(peer_port_id).delete() p.delete() # delete default route for r in tenant_router.get_routes(): if (r.get_dst_network_addr() == '0.0.0.0' and r.get_dst_network_length() == 0): r.delete() # delete SNAT(masquerade) rules chains = self.chain_manager.get_router_chains( tenant_router.get_tenant_id(), tenant_router.get_id()) for r in chains['in'].get_rules(): if OS_TENANT_ROUTER_RULE_KEY in r.get_properties(): if r.get_properties( )[OS_TENANT_ROUTER_RULE_KEY] == SNAT_RULE: r.delete() for r in chains['out'].get_rules(): if OS_TENANT_ROUTER_RULE_KEY in r.get_properties(): if r.get_properties( )[OS_TENANT_ROUTER_RULE_KEY] == SNAT_RULE: r.delete() LOG.debug(_("MidonetPluginV2.update_router exiting: qrouter=%r"), qrouter) return qrouter