Skip to content

Latest commit

 

History

History
136 lines (100 loc) · 7.28 KB

File metadata and controls

136 lines (100 loc) · 7.28 KB

Contributing

Cohesivenet module structure

The main objects that users will interact with are the cohesivenet.VNS3Client and the cohesivenet.MSClient for interacting with the VNS3 API and MS API respectively. Each of these inherit from cohesivenet.api_client and require a cohesivenet.configuration#Configuration object when instantiating.

API method functions:

  • located in cohesivenet.api.vns3 and cohesivenet.api.vns3ms
  • grouped into named modules. These are reflected in the API specifications by the x-sdk-module property defined on the method specifications.

Note this code was initially generated by OpenAPI Generator but then heavily edited to improve user experience such that generating with OpenAPI Generator based on spec now, while it could still be useful, will not provide you with the exact same code

Client submodules

The API clients house their methods in submodules defined on the clients. For example, the get_routes call is located in the routing submodule: VNS3Client.routing.get_routes. Each time a submodule is called, the API method in the corresponding module is determined based on the current VNS3 version. Each API submodule exports a ApiRouter that defines the functions for the submodule's API and the versions of VNS3 that the API function applies to.

Supporting Version switching

The goal of version switching is for a user of the SDK to call a method on a submodule and have the correct API method based on the VNS3 version correctly be called.

Here is an example of the overlay_network module:

class OverlayNetworkApiRouter(VersionRouter):
    function_library = {
        "put_update_all_clientpacks": {
            "4.8.4-6.x.x": put_update_all_clientpacks
        },
        "get_global_link_policies": {
            "5.1.1-6.x.x": get_global_link_policies
        }
    }

Here the put_update_all_clientpacks funtion is support from 4.8.4 through 6. The links API wasn't added until version 5.1.1.

Here is an example of a method defined on the Firewall API which changed starting with v6:


```python
...
        "put_firewall_action": {
            "6.0.0-x.x.x": put_firewall_action_v2,
            "5.0.2-6.x.x": put_firewall_action_v1
        }

Now, we actually are typically backwards compatible with our API. So we want the user to be able to call the OLD api endpoint if they want to, even if they are on a newer version of VNS3. This is accomplished with code like the following:

        "get_firewall_rules": OrderedDict(
            [
                (
                    "6.0.0-",
                    vapi_switch(
                        "get_firewall_rules",
                        v1=get_firewall_rules_v1,
                        v2=get_firewall_rules_v2,
                    ),
                ),
                ("4.8.4-6.x.x", get_firewall_rules_v1),
            ]
        )

## This allows a user to do this:

# vns3 version is 5.x
resp_v1 = vns3.firewall.get_firewall_rules()
# vns3 version is 6.x
resp_v2 = vns3.firewall.get_firewall_rules()
# vns3 version is 6.x
resp_also_v1 = vns3.firewall.get_firewall_rules(api_version=1)

Note on version parsing

Version parsing syntax: [integer].[integer or x].[integer or x]. The VersionRouter code handles finding the correct functions based on the current clients version. The version set on the client will default to the latest defined but can be set by calling VNS3Client.set_vns3_version().

Adding a new API method to the SDK

  1. Start with the API specification as defined in the API spec repo. Add specification for API method there if it does not exist. This is important as python section on the API docs is built automatically using the API spec
  1. Locating the API spec for method and find (or create) the corresponding module in the SDK (e.g. cohesivenet.api.vns3.overlay_api). This is where you will define the method
  2. Write your function by starting with a function that is similar (same HTTP method, requires json body etc) and copy and pasting it and then editing it. Be sure to set the correct api_version param on the api_client.call_api call as this will build the correct API path for you
  3. After writing function, add it to ModuleApiRouter at the bottom of the module. Each key in the function_library is the name of the method and each valid is an object of [version range] -> function pairs.
  4. Instantiate a client and test your function

Adding macros

Macros in cohesivenet.macros are functions that perform common tasks as a series of API calls, potentially across multiple controllers. They are grouped in modules loosely conforming to the same submodules for the API clients.

Another important module: api_operations

The functions in cohesivenet.macros.api_operations provide some async operations that allow users to parallelize API calls across controllers. The main functions are bulk_call_api and bulk_call_client where the latter expects a function that accepts a VNS3Client as the first arg and the former simply expects a method:

from functools import partial

# api_method_baz: function(VNS3Client) -> Any

vns3_client_foo = VNS3Client(Foo)
vns3_client_bar = VNS3Client(Bar)
vns3_clients = [vns3_client_foo, vns3_client_bar]

# bind method with client arg
api_calls = [partial(api_method_baz, vns3_client_foo), partial(api_method, vns3_client_bar)]
operation_results = bulk_call_api(api_calls, parallelize=True)

# method calls api_method_baz with each client in vns3_clients
operation_results = bulk_call_client(vns3_clients, api_method_baz, parallelize=True)

Formatting the Code

Please regularly format the code with make fmt. This will ensure a consistency in code for readability

Building a new installable

Simply run make build. This will create a build directory and a dist directory. The dist directory will contain a pip installable tar.gz called cohesivenet-[version].tar.gz which can be distributed via a url and installed via pip install [url]. This is useful for testing on other systems

Releasing to Pypi

NOTE! If you make a release and upload it to Pypi there is no turning back! If you find there is a bug or something missed, you will have to update the version to the next PATCH version and upload a new version

  • Verify the release, test it, format code
  • update the version file at cohesivenet.version with new version info
  • run release.sh (--test)
    • this will create a git tag for the current commit if the cohesivenet module
    • it will push the tag to origin server (github)
    • it will upload the version to Pypi. For this you will need a Pypi API token
    • IF a tag for the current version already exists it will ask if you want to retag the current commit with the current version (defined in version.py)
    • test param runs against testpypi: https://test.pypi.org

Testing

The testing harness can be run with make test. Tests are located in tests/ directory and run with pytest. The configuration file is tests/conftest.py

  • The testing harness pulls down the API spec defined in cohesivenet.version and uses it to verify API method inputs and outputs.
  • Note testing is a bit out of date. Please write tests when they make sense