Implemented AdvNetworking scenarios via Neutron
Added a new package ( io.murano.lib.networks.Neutron) to handle networking via Neutron The package introduces a class 'NewNetwork' (io.murano.lib.networks.neutron.NewNetwork) This class is capable of the following: - Create a new Network (L2 segment) - Use NetworkExplorer class to allocate an available CIDR - Create a new Subnet (L3 segment) in the created Network with the allocated CIDR - Use NetworkExplorer class to locate an available router - Use NetworkExplorer class to detect the default DNS nameserver - Uplink the created subnet to the located router Also, as this class extends io.murano.resources.Network, it implements the addHostToNetwork method The implementation creates a Neutron Port and connects that port to a created network and intance This commit also modifies the environment-creation logic of the API, allowing to add default networks to the Environment object. This is a temporary solution: in future the instantiation of this object(s) should be done in MuranoPL This commit concludes the minimum set of functionality needed to implement AdvancedNetworking in 0.4.x feature set. Closes-bug: #1308921 Change-Id: I885620099995b0d402a23def3ff428fb902973d2
This commit is contained in:
parent
b7aec89493
commit
b7c2aac9a2
etc/murano
meta/io.murano.lib.networks.Neutron
muranoapi
@ -169,3 +169,6 @@ max_hosts = 250
|
||||
|
||||
# Template IP address for generating environment subnet cidrs
|
||||
env_ip_template = 10.0.0.0
|
||||
|
||||
# Default DNS nameserver to be assigned to created Networks
|
||||
default_dns = 8.8.8.8
|
||||
|
131
meta/io.murano.lib.networks.Neutron/Classes/NewNetwork.yaml
Normal file
131
meta/io.murano.lib.networks.Neutron/Classes/NewNetwork.yaml
Normal file
@ -0,0 +1,131 @@
|
||||
Namespaces:
|
||||
=: io.murano.lib.networks.neutron
|
||||
res: io.murano.resources
|
||||
std: io.murano
|
||||
sys: io.murano.system
|
||||
|
||||
Name: NewNetwork
|
||||
|
||||
Extends: res:Network
|
||||
|
||||
Properties:
|
||||
name:
|
||||
Contract: $.string().notNull()
|
||||
|
||||
externalRouterId:
|
||||
Contract: $.string()
|
||||
Usage: InOut
|
||||
|
||||
autoUplink:
|
||||
Contract: $.bool().notNull()
|
||||
Default: true
|
||||
|
||||
autogenerateSubnet:
|
||||
Contract: $.bool().notNull()
|
||||
Default: true
|
||||
|
||||
subnetCidr:
|
||||
Contract: $.string()
|
||||
Usage: InOut
|
||||
|
||||
dnsNameserver:
|
||||
Contract: $.string()
|
||||
Usage: InOut
|
||||
|
||||
useDefaultDns:
|
||||
Contract: $.bool().notNull()
|
||||
Default: true
|
||||
|
||||
Workflow:
|
||||
initialize:
|
||||
Body:
|
||||
- $.environment: $.find(std:Environment).require()
|
||||
- $.netExplorer: new(sys:NetworkExplorer)
|
||||
|
||||
deploy:
|
||||
Body:
|
||||
- $.ensureNetworkConfigured()
|
||||
- $.environment.instanceNotifier.untrackApplication($this)
|
||||
|
||||
addHostToNetwork:
|
||||
Arguments:
|
||||
- instance:
|
||||
Contract: $.class(res:Instance).notNull()
|
||||
Body:
|
||||
- $.ensureNetworkConfigured()
|
||||
- $portname: $instance.name + '-port-to-' + $.id()
|
||||
- $template:
|
||||
Resources:
|
||||
$portname:
|
||||
Type: 'OS::Neutron::Port'
|
||||
Properties:
|
||||
network_id: {Ref: $.net_res_name}
|
||||
fixed_ips: [{subnet_id: {Ref: $.subnet_res_name}}]
|
||||
$instance.name:
|
||||
Properties:
|
||||
NetworkInterfaces:
|
||||
- Ref: $portname
|
||||
- $.environment.stack.updateTemplate($template)
|
||||
|
||||
|
||||
ensureNetworkConfigured:
|
||||
Body:
|
||||
- If: !yaql "not bool($.getAttr(networkConfigured))"
|
||||
Then:
|
||||
- If: $.useDefaultDns and (not bool($.dnsNameserver))
|
||||
Then:
|
||||
- $.dnsNameserver: $.netExplorer.getDefaultDns()
|
||||
|
||||
- $.net_res_name: $.name + '-net-' + $.id()
|
||||
- $.subnet_res_name: $.name + '-subnet-' + $.id()
|
||||
- $.createNetwork()
|
||||
- If: $.autoUplink and (not bool($.externalRouterId))
|
||||
Then:
|
||||
- $.externalRouterId: $.netExplorer.getDefaultRouter()
|
||||
- If: $.autogenerateSubnet and (not bool($.subnetCidr))
|
||||
Then:
|
||||
- $.subnetCidr: $.netExplorer.getAvailableCidr($.externalRouterId, $.id())
|
||||
- $.createSubnet()
|
||||
- If: !yaql "bool($.externalRouterId)"
|
||||
Then:
|
||||
- $.createRouterInterface()
|
||||
|
||||
- $.environment.stack.push()
|
||||
- $.setAttr(networkConfigured, true)
|
||||
|
||||
|
||||
createNetwork:
|
||||
Body:
|
||||
- $template:
|
||||
Resources:
|
||||
$.net_res_name:
|
||||
Type: 'OS::Neutron::Net'
|
||||
Properties:
|
||||
name: $.name
|
||||
- $.environment.stack.updateTemplate($template)
|
||||
|
||||
createSubnet:
|
||||
Body:
|
||||
- $template:
|
||||
Resources:
|
||||
$.subnet_res_name:
|
||||
Type: 'OS::Neutron::Subnet'
|
||||
Properties:
|
||||
network_id: {Ref: $.net_res_name}
|
||||
ip_version: 4
|
||||
dns_nameservers: [$.dnsNameserver]
|
||||
cidr: $.subnetCidr
|
||||
- $.environment.stack.updateTemplate($template)
|
||||
|
||||
createRouterInterface:
|
||||
Body:
|
||||
- $template:
|
||||
Resources:
|
||||
$.name + '-ri-' + $.id():
|
||||
Type: 'OS::Neutron::RouterInterface'
|
||||
Properties:
|
||||
router_id: $.externalRouterId
|
||||
subnet_id: {Ref: $.subnet_res_name}
|
||||
- $.environment.stack.updateTemplate($template)
|
||||
|
||||
|
10
meta/io.murano.lib.networks.Neutron/manifest.yaml
Normal file
10
meta/io.murano.lib.networks.Neutron/manifest.yaml
Normal file
@ -0,0 +1,10 @@
|
||||
Format: 1.0
|
||||
Type: Library
|
||||
FullName: io.murano.lib.networks.Neutron
|
||||
Name: Neutron Networking library
|
||||
Description: |
|
||||
A library defining various classes to create and manage networking resources via Neutron
|
||||
Author: 'Mirantis, Inc'
|
||||
Tags: [Networking, Neutron]
|
||||
Classes:
|
||||
io.murano.lib.networks.neutron.NewNetwork: NewNetwork.yaml
|
@ -91,6 +91,7 @@ networking_opts = [
|
||||
cfg.IntOpt('max_environments', default=20),
|
||||
cfg.IntOpt('max_hosts', default=250),
|
||||
cfg.StrOpt('env_ip_template', default='10.0.0.0'),
|
||||
cfg.StrOpt('default_dns', default='8.8.8.8')
|
||||
]
|
||||
|
||||
stats_opt = [
|
||||
|
@ -16,6 +16,7 @@ import collections
|
||||
|
||||
from muranoapi.common import rpc
|
||||
from muranoapi.common import uuidutils
|
||||
|
||||
from muranoapi.db import models
|
||||
from muranoapi.db.services import sessions
|
||||
from muranoapi.db import session as db_session
|
||||
@ -27,6 +28,11 @@ EnvironmentStatus = collections.namedtuple('EnvironmentStatus', [
|
||||
ready='ready', pending='pending', deploying='deploying'
|
||||
)
|
||||
|
||||
DEFAULT_NETWORKS = {
|
||||
'environment': 'io.murano.lib.networks.neutron.NewNetwork',
|
||||
# 'flat': 'io.murano.lib.networks.ExistingNetworkConnector'
|
||||
}
|
||||
|
||||
|
||||
class EnvironmentServices(object):
|
||||
@staticmethod
|
||||
@ -88,6 +94,8 @@ class EnvironmentServices(object):
|
||||
'id': uuidutils.generate_uuid(),
|
||||
}}
|
||||
objects.update(environment_params)
|
||||
objects.update(
|
||||
EnvironmentServices.generate_default_networks(objects['name']))
|
||||
objects['?']['type'] = 'io.murano.Environment'
|
||||
environment_params['tenant_id'] = tenant_id
|
||||
|
||||
@ -192,3 +200,23 @@ class EnvironmentServices(object):
|
||||
else:
|
||||
session.description = environment
|
||||
session.save(unit)
|
||||
|
||||
@staticmethod
|
||||
def generate_default_networks(env_name):
|
||||
# TODO(ativelkov):
|
||||
# This is a temporary workaround. Need to find a better way:
|
||||
# These objects have to be created in runtime when the environment is
|
||||
# deployed for the first time. Currently there is no way to persist
|
||||
# such changes, so we have to create the objects on the API side
|
||||
return {
|
||||
'defaultNetworks': {
|
||||
'environment': {
|
||||
'?': {
|
||||
'id': uuidutils.generate_uuid(),
|
||||
'type': DEFAULT_NETWORKS['environment']
|
||||
},
|
||||
'name': env_name + '-network'
|
||||
},
|
||||
'flat': None
|
||||
}
|
||||
}
|
||||
|
@ -98,6 +98,10 @@ class NetworkExplorer(murano_object.MuranoObject):
|
||||
return str(cidr)
|
||||
return None
|
||||
|
||||
# noinspection PyPep8Naming
|
||||
def getDefaultDns(self):
|
||||
return self._settings.default_dns
|
||||
|
||||
def _get_cidrs_taken_by_router(self, router_id):
|
||||
if not router_id:
|
||||
return []
|
||||
|
Loading…
Reference in New Issue
Block a user