Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: create VNIs inside of Nautobot when neutron networks are created #351

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions python/neutron-understack/neutron_understack/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
from oslo_config import cfg

type_understack_opts = [
cfg.StrOpt(
"provisioning_network",
help="provisioning_network ID as configured in ironic.conf",
),
cfg.StrOpt(
"argo_workflow_sa",
default="workflow",
help="ServiceAccount to submit Workflow as",
),
cfg.StrOpt(
"argo_api_url",
default="https://argo-server.argo.svc.cluster.local:2746",
help="URL of the Argo Server API",
),
cfg.StrOpt(
"argo_namespace",
default="argo-events",
help="Namespace to submit the Workflows to",
),
cfg.IntOpt(
"argo_max_attempts",
default=15,
help="Number of tries to retrieve the Workflow run result. "
"Sleeps 5 seconds between attempts.",
),
cfg.BoolOpt("argo_dry_run", default=True, help="Call Undersync with dry-run mode"),
cfg.BoolOpt("argo_force", default=False, help="Call Undersync with force mode"),
]

mech_understack_opts = [
cfg.StrOpt(
"nb_url",
help="Nautobot URL",
),
cfg.StrOpt(
"nb_token",
help="Nautobot API token",
),
cfg.StrOpt(
"ucvni_group",
help="hack",
),
]


def register_ml2_type_understack_opts(config):
config.register_opts(type_understack_opts, "ml2_type_understack")


def register_ml2_understack_opts(config):
config.register_opts(mech_understack_opts, "ml2_understack")
31 changes: 31 additions & 0 deletions python/neutron-understack/neutron_understack/nautobot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from urllib.parse import urljoin

import requests
from oslo_log import log

LOG = log.getLogger(__name__)


class Nautobot:
def __init__(self, nb_url: str, nb_token: str):
"""Basic Nautobot wrapper because pynautobot doesn't expose plugin APIs."""
self.base_url = nb_url
self.s = requests.Session()
self.s.headers.update({"Authorization": f"Token {nb_token}"})

def ucvni_create(
self, network_id: str, segment_id: int, ucvni_group: str, network_name: str
):
payload = {
"id": network_id,
"ucvni_id": segment_id,
"name": network_name,
"ucvni_group": ucvni_group,
"status": "Active",
}

url = urljoin(self.base_url, "/api/plugins/undercloud-vni/ucvnis/")
LOG.debug("ucvni_create payload: %(payload)s", {"payload": payload})
resp = self.s.post(url, json=payload, timeout=10)
LOG.debug("ucvni_create resp: %(resp)s", {"resp": resp.json()})
resp.raise_for_status()
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import neutron_lib.api.definitions.portbindings as portbindings
from neutron_lib import constants as p_const
from neutron_lib import exceptions as exc
from neutron_lib.plugins.ml2 import api
from neutron_lib.plugins.ml2.api import (
MechanismDriver,
Expand All @@ -14,49 +15,14 @@
)
from oslo_config import cfg

from neutron_understack import config
from neutron_understack.argo.workflows import ArgoClient
from neutron_understack.nautobot import Nautobot

LOG = logging.getLogger(__name__)


def setup_conf():
grp = cfg.OptGroup("ml2_type_understack")
opts = [
cfg.StrOpt(
"provisioning_network",
help="provisioning_network ID as configured in ironic.conf",
),
cfg.StrOpt(
"argo_workflow_sa",
default="workflow",
help="ServiceAccount to submit Workflow as",
),
cfg.StrOpt(
"argo_api_url",
default="https://argo-server.argo.svc.cluster.local:2746",
help="URL of the Argo Server API",
),
cfg.StrOpt(
"argo_namespace",
default="argo-events",
help="Namespace to submit the Workflows to",
),
cfg.IntOpt(
"argo_max_attempts",
default=15,
help="Number of tries to retrieve the Workflow run result. "
"Sleeps 5 seconds between attempts.",
),
cfg.BoolOpt(
"argo_dry_run", default=True, help="Call Undersync with dry-run mode"
),
cfg.BoolOpt("argo_force", default=False, help="Call Undersync with force mode"),
]
cfg.CONF.register_group(grp)
cfg.CONF.register_opts(opts, group=grp)


setup_conf()
config.register_ml2_type_understack_opts(cfg.CONF)
config.register_ml2_understack_opts(cfg.CONF)


def dump_context(
Expand Down Expand Up @@ -143,14 +109,41 @@ class UnderstackDriver(MechanismDriver):
resource_provider_uuid5_namespace = UUID("6eae3046-4072-11ef-9bcf-d6be6370a162")

def initialize(self):
pass
conf = cfg.CONF.ml2_understack
self.nb = Nautobot(conf.nb_url, conf.nb_token)

def create_network_precommit(self, context):
log_call("create_network_precommit", context)

def create_network_postcommit(self, context):
log_call("create_network_postcommit", context)

network = context.current
network_id = network["id"]
network_name = network["name"]
provider_type = network.get("provider:network_type")
segmentation_id = network.get("provider:segmentation_id")
physnet = network.get("provider:physical_network")

if provider_type == p_const.TYPE_VXLAN and segmentation_id:
conf = cfg.CONF.ml2_understack
ucvni_group = conf.ucvni_group
try:
self.nb.ucvni_create(
network_id, segmentation_id, ucvni_group, network_name
)
except Exception as e:
LOG.exception(
"unable to create network %(net_id)s", {"net_id": network_id}
)
raise exc.NetworkNotFound(net_id=network_id) from e

LOG.info(
"network %(net_id)s has been added on ucvni_group %(ucvni_group), "
"physnet %(physnet)",
{"net_id": network_id, "ucvni_group": ucvni_group, "physnet": physnet},
)

def update_network_precommit(self, context):
log_call("update_network_precommit", context)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from neutron_lib import constants as p_const
from neutron_lib.plugins.ml2 import api
from oslo_log import log

LOG = log.getLogger(__name__)


class UnderstackVxlanTypeDriver(api.ML2TypeDriver):
def __init__(self):
"""Understack based type driver."""
super().__init__()
LOG.info("ML2 Understack VXLAN Type initialization complete")

def get_type(self):
return p_const.TYPE_VXLAN

def initialize(self):
pass

def initialize_network_segment_range_support(self):
pass

def update_network_segment_range_allocations(self):
pass

def get_network_segment_ranges(self):
pass

def is_partial_segment(self, segment):
return False

def validate_provider_segment(self, segment):
pass

def reserve_provider_segment(self, context, segment, filters=None):
return segment

def allocate_tenant_segment(self, context, filters=None):
return {api.NETWORK_TYPE: p_const.TYPE_VXLAN}

def release_segment(self, context, segment):
pass

def get_mtu(self, physical_network=None):
pass
3 changes: 3 additions & 0 deletions python/neutron-understack/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,6 @@ convention = "google"

[tool.poetry.plugins."neutron.ml2.mechanism_drivers"]
understack = "neutron_understack.neutron_understack_mech:UnderstackDriver"

[tool.poetry.plugins."neutron.ml2.type_drivers"]
understack_vxlan = "neutron_understack.type_understack_vxlan:UnderstackVxlanTypeDriver"
Loading