-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Major update for v2. Restructure of libraries to use objects and factories. Several files migrated to a different naming schema or removed until supported in v2. See RELEASE-NOTES.md for more information. Solved merge conflicts and removed nae.py until supported.
- Loading branch information
Showing
71 changed files
with
15,321 additions
and
14,785 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
# Contribution Guidelines | ||
|
||
If you're reading this, you're probably thinking about contributing to this repository. We really appreciate that--thank you! | ||
|
||
This document provides guidelines on contributing to this repository. Please follow these guidelines when creating issues, making commits, and submitting pull requests. The repository maintainers review all pull requests and verify that they conform to these guidelines before approving and merging. | ||
|
||
#### Table Of Contents | ||
[How Can I Contribute?](#how-can-i-contribute) | ||
* [Contribution Ideas](#contribution-ideas) | ||
* [What should I know before I get started?](#what-should-i-know-before-i-get-started) | ||
|
||
[Licensing](#licensing) | ||
* [Developer's Certificate of Origin](#developers-certificate-of-origin) | ||
* [Sign Your Work](#sign-your-work) | ||
|
||
[Coding Conventions](#coding-conventions) | ||
|
||
[Additional Notes](#additional-notes) | ||
* [Resources](#resources) | ||
|
||
## How Can I Contribute? | ||
|
||
### Contribution Ideas | ||
|
||
1. Raise issues for bugs, features, and enhancements. | ||
1. Submit updates and improvements to the documentation. | ||
1. Submit articles and guides, which are also part of the documentation. | ||
1. Help out repo maintainers by answering questions in [Airheads Developer Community][airheads-link]. | ||
1. Share feedback and let us know about interesting use cases in [Airheads Developer Community][airheads-link]. | ||
|
||
### What should I know before I get started? | ||
|
||
The best way to directly collaborate with the project contributors is through GitHub. | ||
|
||
* If you want to raise an issue such as a defect, an enhancement request, feature request, or a general issue, please open a GitHub issue. | ||
* If you want to contribute to our code by either fixing a problem, enhancing some code, or creating a new feature, please open a GitHub pull request against the development branch. | ||
> **Note:** All pull requests require an associated issue number, must be made against the **development** branch, and require acknowledgement of the DCO. See the [Licensing](#licensing) section below. | ||
Before you start to code, we recommend discussing your plans through a GitHub issue, especially for more ambitious contributions. This gives other contributors a chance to point you in the right direction, give you feedback on your design, and help you find out if someone else is working on the same thing. | ||
|
||
It is your responsibility to test and verify, prior to submitting a pull request, that your updated code doesn't introduce any bugs. Please write a clear commit message for each commit. Brief messages are fine for small changes, but bigger changes warrant a little more detail (at least a few sentences). | ||
Note that all patches from all contributors get reviewed. | ||
After a pull request is made, other contributors will offer feedback. If the patch passes review, a maintainer will accept it with a comment. | ||
When a pull request fails review, the author is expected to update the pull request to address the issue until it passes review and the pull request merges successfully. | ||
|
||
At least one review from a maintainer is required for all patches. | ||
|
||
### Contribution Guidelines | ||
This repo is maintained on a best-effort basis. The burden is on the submitter and not the repo maintainers to ensure the following criteria are met when code is submitted. | ||
1. All code submissions must adhere to the structure of the repo: | ||
* Lower-level functions and API calls must be saved in the /pyaoscx folder. | ||
* High-level process-focused functions must be saved in the /workflows folder. | ||
* Do not create new separate folders for submitted projects. | ||
* Do not make copies of existing files to be saved in different folders. | ||
* The objective is that all submissions build on the repo as a whole, rather than creating multiple sub-projects housed in the repo. | ||
2. All Python code should conform to PEP-8 standards. The maintainers use Pycharm IDE to perform this check. That does not require submitters to use Pycharm, but regardless of the code editor used, the PEP-8 check must be successful. | ||
3. All functions should have explanatory docstrings using the reStructuredText format. | ||
4. All workflows should have a comment at the top explaining the configuration steps the workflow performs, and any preconditions that need to be met before running the script. | ||
5. All git commits should have clear, concise messages which explain the changes made in the commit. All Pull Requests (PRs) should contain a title and comments that explain the impact of the PR. | ||
6. All code submitted for merge consideration must be tested by the submitter. | ||
|
||
## Licensing | ||
|
||
All contributions must include acceptance of the DCO: | ||
|
||
### Developer’s Certificate of Origin | ||
|
||
> Developer Certificate of Origin Version 1.1 | ||
> | ||
> Copyright (C) 2004, 2006 The Linux Foundation and its contributors. 660 | ||
> York Street, Suite 102, San Francisco, CA 94110 USA | ||
> | ||
> Everyone is permitted to copy and distribute verbatim copies of this | ||
> license document, but changing it is not allowed. | ||
> | ||
> Developer's Certificate of Origin 1.1 | ||
> | ||
> By making a contribution to this project, I certify that: | ||
> | ||
> \(a) The contribution was created in whole or in part by me and I have | ||
> the right to submit it under the open source license indicated in the | ||
> file; or | ||
> | ||
> \(b) The contribution is based upon previous work that, to the best of my | ||
> knowledge, is covered under an appropriate open source license and I | ||
> have the right under that license to submit that work with | ||
> modifications, whether created in whole or in part by me, under the same | ||
> open source license (unless I am permitted to submit under a different | ||
> license), as indicated in the file; or | ||
> | ||
> \(c) The contribution was provided directly to me by some other person | ||
> who certified (a), (b) or (c) and I have not modified it. | ||
> | ||
> \(d) I understand and agree that this project and the contribution are | ||
> public and that a record of the contribution (including all personal | ||
> information I submit with it, including my sign-off) is maintained | ||
> indefinitely and may be redistributed consistent with this project or | ||
> the open source license(s) involved. | ||
### Sign Your Work | ||
|
||
To accept the DCO, simply add this line to each commit message with your | ||
name and email address (`git commit -s` will do this for you): | ||
|
||
Signed-off-by: Jane Example <[email protected]> | ||
|
||
For legal reasons, no anonymous or pseudonymous contributions are | ||
accepted. | ||
|
||
## Coding Conventions | ||
|
||
1. Python code should conform to PEP-8. PyCharm editor has a built-in PEP-8 checker. | ||
1. Since this is a collaborative project, document your code with comments that will help other contributors understand the code you write. | ||
1. When in doubt, follow conventions you see used in the source already. | ||
|
||
## Additional Notes | ||
|
||
> **Note:** Please don't file an issue to ask a question. Please reach out to us via email or disucssion forums. | ||
### Resources | ||
|
||
| Resource | Description | | ||
| --- | --- | | ||
| [Airheads Developer Community][airheads-link] | Aruba Airheads forum to discuss all things network automation. | | ||
| [Aruba Bots Automate Videos][aruba-bots-playlist-link]| YouTube playlist containing instructional videos for Ansible and Python automation repositories. | | ||
| [[email protected]][email-link] | Distribution list email to contact the switching automation technical marketing engineering team. | | ||
|
||
|
||
[airheads-link]: https://community.arubanetworks.com/community-home?CommunityKey=ea467413-8db4-4c49-b5f8-1a12f193e959 | ||
[aruba-bots-playlist-link]: https://www.youtube.com/watch?v=_QxwUiXkJpA&list=PLsYGHuNuBZcY02FUh95ZpOB5VFkPurVaX | ||
[email-link]: mailto:[email protected] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,180 @@ | ||
# pyaoscx | ||
|
||
## Overview | ||
|
||
The pyaoscx (a.k.a. AOS-CX Python SDK) is a framework created to ease the access to | ||
the Aruba switches running AOS-CX, using the REST API interface. The framework is | ||
not intended to be a Network Management System (NMS). Instead, it is meant to | ||
provide functions and classes to perform basic operations on the devices, | ||
including the following: | ||
|
||
1. Handling the session and remote connection. | ||
1. Handling the allowed operations depending on their capabilities. | ||
1. Handling the responses depending on the API version. | ||
1. Basic data validation. | ||
1. Raising meaningful errors. | ||
|
||
And, also, if needed: | ||
|
||
1. Caching data. | ||
1. Handling notifications. | ||
|
||
## Design drivers | ||
|
||
pyaoscx uses the object-oriented approach. Instead of having separate modules to | ||
perform specific operations, it connect several features together to represent | ||
the operational state of the switch. Such pattern allows the client to keep track | ||
of the switch configuration in its internal data structures. | ||
|
||
|
||
Every single feature must be represented in a class. Such a class may or may not | ||
be contained in another class or a collection. For example, the `Interface` | ||
represents a specific Interface, and it may contain references to other `VLANs`, `VRFs`, | ||
and depending on the use case, the `VSF` or `VSX` configuration. Also, an | ||
`Interface` may be represented as a `LAG`, meaning that it may contain | ||
references to more than a single physical port. | ||
|
||
### pyaoscx Modules | ||
Each pyaoscx module is defined as a Python Class, in which it contains method | ||
definitions to generate and manage a module through REST API call or multiple | ||
REST API calls. All module creation is managed through a flag attribute materialized. | ||
This attribute will be True if the module exists within the Switch Device, False otherwise. | ||
This will be updated whenever a POST or GET called is done. | ||
|
||
Each pyaoscx Module has a list of important attributes besides materialized: | ||
* session: use to make the HTTP requests, among other things. | ||
* config_attrs: list of attributes writable to each specific object | ||
* original_attributes: dictionary with object information and attributes right | ||
after performing a GET request. | ||
* modified: Flag to verify if object was modified, in case it was not the PUT | ||
request is not made. | ||
|
||
### Materialized objects | ||
|
||
The attributes for a local object in the SDK may not match the current configuration on the switch. | ||
Creating a local object in the SDK does not mean the object was created in the device. | ||
The internal attributes can be filled with _artificial_ data, which cannot be | ||
considered _materialized_ unless the object was retrieved from the device with | ||
a __get__ operation, or the object was created with a __create__ operation. | ||
|
||
### Operations | ||
|
||
REST API allows a well-known list of HTTP verbs. They must be mapped to class- | ||
specific operations to keep the same behavior along this SDK. | ||
|
||
#### Get | ||
|
||
This method maps to the HTTP GET verb. It allows to retrieve the data from the | ||
device, converting the JSON response into the corresponding internal attributes | ||
of the object. Object attributes must match 1:1 with the device information. | ||
|
||
#### Create | ||
|
||
This method maps to the HTTP POST verb. It retrieves a list of attributes from | ||
the object known as writable attributes, creating a body for the | ||
POST request. | ||
|
||
#### Update | ||
|
||
This method maps to the HTTP PUT verb. Just as the CREATE, retrieves a list of | ||
attributes from the object known as writable attributes. The difference | ||
is the UPDATE methods makes a PUT Request. It's important to know that this method | ||
is executed only if the object is materialized. | ||
|
||
##### NOTIFICATIONS | ||
|
||
#### Set | ||
|
||
Given that the REST API does not provide support to the HTTP PATCH verb yet, all | ||
the operations to change the device configuration must use the HTTP PUT verb. | ||
It means that the the original attributes must be retrieved first, then change | ||
the values required, and finally perform the change. This operation cannot be | ||
performed on an unmaterialized object. | ||
|
||
|
||
### Session management | ||
|
||
In order to perform any operation in the device, a connection must be | ||
established. The session is an object representing it. It keeps the credential | ||
information, such as `username` and `password`, and, once established, it also | ||
keeps the session cookie. There is an assumption that all the operations | ||
performed should be done with the same REST API version. Therefore, the session | ||
also contains the version the client wants to use. | ||
|
||
The session state must be validated every time an operation must be performed. | ||
Therefore, using a Python decorator is the suggested approach. | ||
|
||
However, in order to prevent using a _global accessible object_ representing | ||
the session, and passing it as a parameter in every call, the SDK objects may | ||
receive the session object as _mandatory parameter_ in the constructor. | ||
|
||
### Factory Pattern | ||
|
||
The REST API request and responses vary depending on the version. It means that | ||
the internal structure of the payload changes, and the SDK must take care of it. | ||
A Factory class is used to create new objects -- both python objects and modules | ||
inside a switch AOS-CX Device. | ||
|
||
If a module is created using the pyaoscx Factory, it's going to be set with the given | ||
state in each creation method. | ||
|
||
## Main classes | ||
|
||
### Session | ||
|
||
The session class keeps the connection parameters. When a connection is established, | ||
it also records the session cookie and the last time the connection was used, which | ||
can help to identify whether the session is still valid because of the idle time. | ||
The following fields will be required to store the main session information: | ||
|
||
* Username | ||
* Password | ||
* Cookie | ||
* API version | ||
* Last operation timestamp | ||
|
||
### API | ||
|
||
Represents the API version used. Keeps all the important information | ||
for the version and the methods related to it: | ||
|
||
* release date | ||
* version number | ||
* default selector | ||
* default depth | ||
|
||
|
||
### Device | ||
|
||
This class identifies the switch. It keeps all the basic internal parameters | ||
which defines the device identity, like serial number and name, but, most importantly, | ||
the device's capacities and capabilities. The latter parameters allow to decide | ||
what kind of operations can be performed on a switch, given some features are | ||
available on a certain family of devices. | ||
|
||
* Name | ||
* Serial | ||
* Capacities | ||
* Capabilities | ||
|
||
### Configuration | ||
|
||
This class represents a Device's configuration and all of its attributes. It's used to | ||
configure the device, get full config structure, backup configuration, among other things. | ||
|
||
|
||
### Error handling | ||
|
||
Leveraging the Python infrastructure, the exceptions are the best | ||
mechanism to handle the errors. An exception may report internal details | ||
about the issue found, by returning error codes and descriptive error strings. | ||
|
||
The following hierarchical organization will help classify the possible errors, | ||
and, furthermore, let the SDK client know what exactly happened when calling | ||
a function. | ||
|
||
#### Exceptions | ||
|
||
1. GenericOperationError | ||
2. ResponseError | ||
3. VerificationError |
Oops, something went wrong.