Merge pull request #6 from mdr78/main

build: fix python load paths
This commit is contained in:
Pim van Pelt
2022-07-12 17:19:29 +02:00
committed by GitHub
26 changed files with 146 additions and 72 deletions

View File

@ -25,6 +25,10 @@ install:
pkg-deb:
dpkg-buildpackage -uc -us -b
.PHONY: check-style
check-style:
PYTHONPATH=./$(VPPCFG) pylint ./$(VPPCFG)
.PHONY: uninstall
uninstall:
sudo $(PIP) uninstall $(VPPCFG)

1
debian/rules vendored
View File

@ -3,4 +3,5 @@
%:
dh $@ --with python3 --buildsystem=pybuild --with systemd
# TODO: fix test.py to that unit tests can be automagically called.
override_dh_auto_test:

View File

@ -13,7 +13,7 @@ types of validation:
to a running VPP. *Note*: Some semantic checks are stricter than VPP, because applying
them may leave the dataplane in a non-recoverable state.
For the curious, the Yamale syntax validation lives in [this schema](../schema.yaml).
For the curious, the Yamale syntax validation lives in [this schema](../vppcfg/schema.yaml).
If you want to get started quickly and don't mind cargo-culting, take a look at [this example](../example.yaml).
### Basic structure

View File

@ -1,4 +1,5 @@
from setuptools import setup, find_packages
"""vppcfg setuptools setup.py for pip and deb pkg installations"""
from setuptools import setup
setup(
name="vppcfg",
@ -17,5 +18,5 @@ setup(
"vppcfg = vppcfg.vppcfg:main",
]
},
include_package_data=True,
package_data={"vppcfg": ["*.yaml"]},
)

View File

@ -1,9 +1,16 @@
import os, sys
ROOT_DIR = os.path.dirname(__file__)
# fix the module load path
sys.path.insert(0, ROOT_DIR)
# fix the yaml search path
os.chdir(ROOT_DIR)
#!/usr/bin/env python
#
# Copyright (c) 2022 Ray Kinsella
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at:
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# -*- coding: utf-8 -*-
""" __init__.py added to suppress pylint error """

View File

@ -32,12 +32,12 @@ except ImportError:
sys.exit(-2)
from yamale.validators import DefaultValidators, Validator
from config.loopback import validate_loopbacks
from config.bondethernet import validate_bondethernets
from config.interface import validate_interfaces
from config.bridgedomain import validate_bridgedomains
from config.vxlan_tunnel import validate_vxlan_tunnels
from config.tap import validate_taps
from .loopback import validate_loopbacks
from .bondethernet import validate_bondethernets
from .interface import validate_interfaces
from .bridgedomain import validate_bridgedomains
from .vxlan_tunnel import validate_vxlan_tunnels
from .tap import validate_taps
class IPInterfaceWithPrefixLength(Validator):
@ -104,13 +104,12 @@ class Validator:
if self.schema:
fname = self.schema
self.logger.debug(f"Validating against --schema {fname}")
elif hasattr(sys, "_MEIPASS"):
## See vppcfg.spec data_files that includes schema.yaml into the bundle
self.logger.debug("Validating against built-in schema")
fname = os.path.join(sys._MEIPASS, "schema.yaml")
else:
fname = "./schema.yaml"
self.logger.debug(f"Validating against fallthrough default schema {fname}")
## See setup.py data files that includes schema.yaml into the bundle
self.logger.debug("Validating against built-in schema")
fname = os.path.abspath(
os.path.join(os.path.dirname(__file__), "..", "schema.yaml")
)
if not os.path.isfile(fname):
self.logger.error(f"Cannot file schema file: {fname}")

View File

@ -13,8 +13,8 @@
#
""" A vppcfg configuration module that handles bondethernets """
import logging
from config import interface
from config import mac
from . import interface
from . import mac
def get_bondethernets(yaml):

View File

@ -13,8 +13,8 @@
#
""" A vppcfg configuration module that handles bridgedomains """
import logging
from config import interface
from config import loopback
from . import interface
from . import loopback
def get_bridgedomains(yaml):

View File

@ -13,14 +13,14 @@
#
""" A vppcfg configuration module that validates interfaces """
import logging
from config import bondethernet
from config import bridgedomain
from config import loopback
from config import vxlan_tunnel
from config import lcp
from config import address
from config import mac
from config import tap
from . import bondethernet
from . import bridgedomain
from . import loopback
from . import vxlan_tunnel
from . import lcp
from . import address
from . import mac
from . import tap
def get_qinx_parent_by_name(yaml, ifname):

View File

@ -13,9 +13,9 @@
#
""" A vppcfg configuration module that validates loopbacks """
import logging
from config import lcp
from config import address
from config import mac
from . import lcp
from . import address
from . import mac
def get_loopbacks(yaml):

View File

@ -13,7 +13,7 @@
#
""" A vppcfg configuration module that validates taps """
import logging
from config import mac
from . import mac
def get_taps(yaml):

View File

@ -15,12 +15,13 @@
""" Unit tests for bondethernet """
import unittest
import yaml
import config.bondethernet as bondethernet
from . import bondethernet
from .unittestyaml import UnitTestYaml
class TestBondEthernetMethods(unittest.TestCase):
def setUp(self):
with open("unittest/test_bondethernet.yaml", "r") as f:
with UnitTestYaml("test_bondethernet.yaml") as f:
self.cfg = yaml.load(f, Loader=yaml.FullLoader)
def test_get_by_name(self):

View File

@ -15,12 +15,13 @@
""" Unit tests for bridgedomains """
import unittest
import yaml
import config.bridgedomain as bridgedomain
from . import bridgedomain
from .unittestyaml import UnitTestYaml
class TestBridgeDomainMethods(unittest.TestCase):
def setUp(self):
with open("unittest/test_bridgedomain.yaml", "r") as f:
with UnitTestYaml("test_bridgedomain.yaml") as f:
self.cfg = yaml.load(f, Loader=yaml.FullLoader)
def test_get_by_name(self):

View File

@ -15,12 +15,13 @@
""" Unit tests for interfaces """
import unittest
import yaml
import config.interface as interface
from . import interface
from .unittestyaml import UnitTestYaml
class TestInterfaceMethods(unittest.TestCase):
def setUp(self):
with open("unittest/test_interface.yaml", "r") as f:
with UnitTestYaml("test_interface.yaml") as f:
self.cfg = yaml.load(f, Loader=yaml.FullLoader)
def test_enumerators(self):

View File

@ -15,13 +15,14 @@
""" Unit tests for LCPs """
import unittest
import yaml
import config.lcp as lcp
import config.interface as interface
from . import lcp
from . import interface
from .unittestyaml import UnitTestYaml
class TestLCPMethods(unittest.TestCase):
def setUp(self):
with open("unittest/test_lcp.yaml", "r") as f:
with UnitTestYaml("test_lcp.yaml") as f:
self.cfg = yaml.load(f, Loader=yaml.FullLoader)
def test_enumerators(self):

View File

@ -15,12 +15,13 @@
""" Unit tests for loopbacks """
import unittest
import yaml
import config.loopback as loopback
from . import loopback
from .unittestyaml import UnitTestYaml
class TestLoopbackMethods(unittest.TestCase):
def setUp(self):
with open("unittest/test_loopback.yaml", "r") as f:
with UnitTestYaml("test_loopback.yaml") as f:
self.cfg = yaml.load(f, Loader=yaml.FullLoader)
def test_get_by_lcp_name(self):

View File

@ -14,7 +14,7 @@
# -*- coding: utf-8 -*-
""" Unit tests for MAC addresses """
import unittest
import config.mac as mac
from . import mac
class TestMACMethods(unittest.TestCase):

View File

@ -15,12 +15,13 @@
""" Unit tests for taps """
import unittest
import yaml
import config.tap as tap
from . import tap
from .unittestyaml import UnitTestYaml
class TestTAPMethods(unittest.TestCase):
def setUp(self):
with open("unittest/test_tap.yaml", "r") as f:
with UnitTestYaml("test_tap.yaml") as f:
self.cfg = yaml.load(f, Loader=yaml.FullLoader)
def test_get_by_name(self):

View File

@ -15,12 +15,13 @@
""" Unit tests for vxlan_tunnels """
import unittest
import yaml
import config.vxlan_tunnel as vxlan_tunnel
from . import vxlan_tunnel
from .unittestyaml import UnitTestYaml
class TestVXLANMethods(unittest.TestCase):
def setUp(self):
with open("unittest/test_vxlan_tunnel.yaml", "r") as f:
with UnitTestYaml("test_vxlan_tunnel.yaml") as f:
self.cfg = yaml.load(f, Loader=yaml.FullLoader)
def test_get_by_name(self):

View File

@ -0,0 +1,41 @@
""" module to help locate unittest resources """
#!/usr/bin/env python
#
# Copyright (c) 2022 Ray Kinsella
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at:
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# -*- coding: utf-8 -*-
import os
class UnitTestYaml:
"""Helper classes to find and load unit test yaml resources"""
def __init__(self, fpath):
self.file = None
self.filename = fpath
self.resdir = os.path.abspath(
os.path.join(os.path.dirname(__file__), "../unittest")
)
def __enter__(self):
self.file = open(
os.path.join(self.resdir, self.filename), "r", encoding="utf-8"
)
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
self.file.close()
def __str__(self):
return self.file

View File

@ -14,13 +14,19 @@
#
# -*- coding: utf-8 -*-
""" This is a unit test suite for vppcfg """
# pylint: disable=duplicate-code
import os
import sys
import glob
import re
import unittest
import yaml
from config import Validator
try:
from vppcfg.config import Validator
except ModuleNotFoundError:
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
from vppcfg.config import Validator
try:
import argparse

View File

@ -17,7 +17,7 @@ The functions in this file interact with the VPP API to modify certain
interface metadata.
"""
from vpp.vppapi import VPPApi
from .vppapi import VPPApi
class Applier(VPPApi):

View File

@ -19,8 +19,8 @@ interface metadata and write it to a YAML file.
import sys
import yaml
from vpp.vppapi import VPPApi
from config import bondethernet
from vppcfg.config import bondethernet
from .vppapi import VPPApi
class Dumper(VPPApi):

View File

@ -19,14 +19,14 @@ metadata, and plan configuration changes towards a given YAML target configurati
"""
import sys
import logging
from config import loopback
from config import interface
from config import bondethernet
from config import bridgedomain
from config import vxlan_tunnel
from config import lcp
from config import tap
from vpp.vppapi import VPPApi
from vppcfg.config import loopback
from vppcfg.config import interface
from vppcfg.config import bondethernet
from vppcfg.config import bridgedomain
from vppcfg.config import vxlan_tunnel
from vppcfg.config import lcp
from vppcfg.config import tap
from .vppapi import VPPApi
class Reconciler:

View File

@ -15,12 +15,20 @@
# -*- coding: utf-8 -*-
"""vppcfg is a utility to configure a running VPP Dataplane using YAML
config files. See http://github.com/pimvanpelt/vppcfg/README.md for details. """
# pylint: disable=duplicate-code
import os
import sys
import logging
import yaml
from config import Validator
from vpp.reconciler import Reconciler
from vpp.dumper import Dumper
# Ensure the paths are correct when we execute from the source tree
try:
from vppcfg.config import Validator
except ModuleNotFoundError:
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
from vppcfg.config import Validator
from vppcfg.vpp.reconciler import Reconciler
from vppcfg.vpp.dumper import Dumper
try:
import argparse