mirror of
https://github.com/jbowdre/phpIPAM-for-vRA8.git
synced 2024-11-23 23:42:20 +00:00
initial commit
This commit is contained in:
commit
7b8065c9de
1781 changed files with 274682 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
target/
|
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"python.pythonPath": "venv_tango/bin/python"
|
||||||
|
}
|
23
Dockerfile
Normal file
23
Dockerfile
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
FROM photon:3.0-20200609
|
||||||
|
|
||||||
|
ADD target/python /ipam/python
|
||||||
|
|
||||||
|
RUN tdnf install -y python3-pip.noarch python3-devel gcc glibc-devel binutils linux-api-headers shadow && \
|
||||||
|
pip3 install --upgrade pip setuptools && \
|
||||||
|
pip3 install certifi && \
|
||||||
|
tdnf clean all && \
|
||||||
|
rm -fr /var/cache/tdnf/*
|
||||||
|
|
||||||
|
RUN pip3 install -r /ipam/python/allocate_ip/requirements.txt --target=/ipam/python/allocate_ip
|
||||||
|
RUN pip3 install -r /ipam/python/deallocate_ip/requirements.txt --target=/ipam/python/deallocate_ip
|
||||||
|
RUN pip3 install -r /ipam/python/get_ip_ranges/requirements.txt --target=/ipam/python/get_ip_ranges
|
||||||
|
RUN pip3 install -r /ipam/python/validate_endpoint/requirements.txt --target=/ipam/python/validate_endpoint
|
||||||
|
RUN if [ "@provider.supportsUpdateRecord@" = "true" ] ; then pip3 install -r /ipam/python/update_record/requirements.txt --target=/ipam/python/update_record ; fi
|
||||||
|
RUN if [ "@provider.supportsOnDemandNetworks@" = "true" ] ; then pip3 install -r /ipam/python/get_ip_blocks/requirements.txt --target=/ipam/python/get_ip_blocks ; fi
|
||||||
|
RUN if [ "@provider.supportsOnDemandNetworks@" = "true" ] ; then pip3 install -r /ipam/python/allocate_ip_range/requirements.txt --target=/ipam/python/allocate_ip_range ; fi
|
||||||
|
RUN if [ "@provider.supportsOnDemandNetworks@" = "true" ] ; then pip3 install -r /ipam/python/deallocate_ip_range/requirements.txt --target=/ipam/python/deallocate_ip_range ; fi
|
||||||
|
|
||||||
|
RUN useradd -ms /bin/bash -u @user.id@ -U @user.name@
|
||||||
|
|
||||||
|
CMD yes | cp -rf -R /ipam/python /ipam/result && \
|
||||||
|
echo Collecting-dependencies-complete
|
263
README.md
Normal file
263
README.md
Normal file
|
@ -0,0 +1,263 @@
|
||||||
|
Sample IPAM Integration
|
||||||
|
============
|
||||||
|
|
||||||
|
A reference implementation of an IPAM integration plugin for vRA(C) 8.x
|
||||||
|
|
||||||
|
Use this documentation as a step by step guide for creating your own IPAM plugin.
|
||||||
|
|
||||||
|
For more information about the IPAM integration see: [vRA IPAM plugin reference documentation]
|
||||||
|
|
||||||
|
[vRA IPAM plugin reference documentation]: https://docs.vmware.com/en/VMware-Cloud-services/1.0/ipam_integration_contract_reqs.pdf
|
||||||
|
|
||||||
|
Prerequisites
|
||||||
|
===============
|
||||||
|
|
||||||
|
The following software should be installed and configured in order to use this plugin:
|
||||||
|
|
||||||
|
1. **Java 8**
|
||||||
|
|
||||||
|
2. **Maven 3** (Used for packaging the IPAM zip)
|
||||||
|
|
||||||
|
3. **Python 3** (The IPAM plugin is based on Python)
|
||||||
|
|
||||||
|
4. **Docker** (Docker is used to collect Python dependency libs that are needed by the IPAM plugin)
|
||||||
|
|
||||||
|
5. **Internet access** (The IPAM SDK relies on Maven Central, Docker HUB & PIP during packaging time. **Internet access is not required during runtime.** More details below)
|
||||||
|
|
||||||
|
Note: You can use a higher version of the above software as long as it is backward compatible.
|
||||||
|
|
||||||
|
Guide for creating the IPAM package
|
||||||
|
===============
|
||||||
|
|
||||||
|
Step 1: Package the scripts
|
||||||
|
----------------
|
||||||
|
|
||||||
|
Maven & Docker are used during build time to package the Python scripts into IPAM.zip distribution.
|
||||||
|
Maven enables the building of the IPAM package to be platform independent. This allows integrators to develop their IPAM integration solution under any Java-enabled OS - Windows, Unix, Mac, etc...
|
||||||
|
|
||||||
|
Docker is used during build time to start up a Photon OS container. All 3rd party libraries that the IPAM plugin depends on are downloaded during build time, using PIP, from within the Photon OS docker container. This guarantees that all Python lib binaries will be compiled exactly for Photon OS which is the OS of the Running Environment that is going to be executing the IPAM Python actions.
|
||||||
|
|
||||||
|
The first thing you can do is build the package by following the instructions below:
|
||||||
|
|
||||||
|
1. Open the `pom.xml` and modify the following properties:
|
||||||
|
|
||||||
|
`<provider.name>SampleIPAM</provider.name>`
|
||||||
|
`<provider.description>Sample IPAM integration for vRA</provider.description>`
|
||||||
|
`<provider.version>0.1</provider.version>`
|
||||||
|
|
||||||
|
Replace these property values with the name, description & version of your choice.
|
||||||
|
The provider.name will be used as a display name in vRA(C) when you deploy the plugin zip, along with the description & version.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
Use the src/main/resources/CHANGELOG.md file to document any bug fixes, features and additions to the plugin over the course of time when a new plugin version is released. The file is included in the final plugin zip distribution so that vRA end-customers would know what is new in the plugin.
|
||||||
|
|
||||||
|
2. Update the logo.png file with the logo icon of your company (advisable)
|
||||||
|
|
||||||
|
The vRA(C) UI uses the logo.png file located in ./src/main/resources when displaying the IPAM endpoints you create using this package.
|
||||||
|
|
||||||
|
3. (Optional) Change the IPAM Integration endpoint custom form.
|
||||||
|
|
||||||
|
This is done by modifying the endpoint-schema.json file located in ./src/main/resources. It contains the custom form definition that renders the IPAM provider's specific fields
|
||||||
|
during IPAM endpoint registration. You can change it however you like except that **it is required that this file contains entries for privateKey and privateKeyId fields.**
|
||||||
|
|
||||||
|
Note: In ./src/main/resources you can also see the registration.yaml file. It contains meta information about the contents of the package.
|
||||||
|
**Don't change anything in this file.**
|
||||||
|
|
||||||
|
4. Run `mvn package -PcollectDependencies`
|
||||||
|
|
||||||
|
**This produces a SampleIPAM.zip file under ./target.**
|
||||||
|
**The zip should be ready for deployment into vRA(C).**
|
||||||
|
|
||||||
|
Notice that the first time you run this command, it could take up to several minutes to complete packaging the IPAM zip.
|
||||||
|
The reason for that is because the first time the script runs it attempts to collect any 3rd party Python libs that
|
||||||
|
the plugin depends on - such as **requests**, **pyopenssh** & others.
|
||||||
|
|
||||||
|
Next consecutive runs of `mvn package` **will not** trigger another collection of 3rd party libs because this is time consuming and most often unnecessary.
|
||||||
|
In order to re-trigger collection of dependencies (could be needed in case you introduced a new 3rd party Python lib) you must provide the `-PcollectDependencies` option again.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
If you are building the package on Linux you must add one additional parameter to the build: `-Duser.id=${UID}`
|
||||||
|
(`mvn package -PcollectDependencies -Duser.id=${UID}`)
|
||||||
|
|
||||||
|
Now the IPAM package is ready to use.
|
||||||
|
We advise you to test whether it works by uploading it in vRA(C) and then checking that the actions are triggered when they should be and executed successfully.
|
||||||
|
For example, create a new IPAM endpoint and choose the package you uploaded in the **Provider** dropdown, enter an arbitrary username and password, enter **httpbin.org** as a **Hostname** and click on `Validate`.
|
||||||
|
You should see the **Validate Endpoint** action is triggered in the **Extensibility** tab. It should complete successfully.
|
||||||
|
|
||||||
|
Step 2: Get familiar with the IPAM operations and their skeleton implementations
|
||||||
|
----------------
|
||||||
|
|
||||||
|
After checking that the packaging of the sample IPAM scripts works, you can start exploring the code.
|
||||||
|
Under ./src/main/python you'd find separate directory for each IPAM specific operation that the plugin supports.
|
||||||
|
|
||||||
|
| Operation name | Description | Script | Required |
|
||||||
|
| ----------------------------|:------------------------------------------------------------------------------------------------------------------------------------------|:------------------------------------------------|:---------|
|
||||||
|
| Allocate IP | Allocates the next available IP for a VM | ./src/main/python/allocate_ip/source.py | Yes |
|
||||||
|
| Deallocate IP | Deallocates an already allocated IP | ./src/main/python/deallocate_ip/source.py | Yes |
|
||||||
|
| Get IP Ranges | Data collects IP ranges & networks from the IPAM provider | ./src/main/python/get_ip_ranges/source.py | Yes |
|
||||||
|
| Update Record | Updates the created host record. Could be used to update MAC address of VM after it has been provisioned | ./src/main/python/update_record/source.py | No |
|
||||||
|
| Validate Endpoint | Validates that the IPAM endpoint credentials are valid and that a connection to the external IPAM system can be established successfully | ./src/main/python/validate_endpoint/source.py | Yes |
|
||||||
|
| Allocate IP Range | Creates network inside some of the specified IP blocks | ./src/main/python/allocate_ip_range/source.py | No |
|
||||||
|
| Deallocate IP Range | Deletes an already allocated network | ./src/main/python/deallocate_ip_range/source.py | No |
|
||||||
|
| Get IP Blocks | Data collects IP blocks | ./src/main/python/get_ip_blocks/source.py | No |
|
||||||
|
|
||||||
|
The ./src/main/python/\*\*/source.py scripts contain the Python source code that would be used by vRA(C) to perform the respective IPAM operation.
|
||||||
|
|
||||||
|
Each script defines a `def handler(context, inputs):` function that is the entry point into the IPAM operation. vRA(C)'s IPAM framework calls the respective operation's `handler` function, passing request specific inputs in the form of Python dictionary along with the context object that can be used to securely connect to vRA(C) and call its services.
|
||||||
|
|
||||||
|
Step 3: Implement the IPAM operations
|
||||||
|
----------------
|
||||||
|
|
||||||
|
Integrators can choose to implement the `def handler(context, inputs):` function of each IPAM operation's source.py script from scratch, as long as they conform to the contract defined in the [vRA IPAM plugin reference documentation]
|
||||||
|
|
||||||
|
---
|
||||||
|
**We advise against implementing the operations from scratch.**
|
||||||
|
Instead, integrators can utilize the `vra_ipam_utils` library located in ./src/main/python/commons/vra_ipam_utils which contains utility functions and classes that will help with the `def handler(context, inputs):` implementation.
|
||||||
|
|
||||||
|
The source.py code already makes use of the `vra_ipam_utils` lib so you can look at it as reference:
|
||||||
|
|
||||||
|
```python
|
||||||
|
def handler(context, inputs):
|
||||||
|
|
||||||
|
ipam = IPAM(context, inputs)
|
||||||
|
IPAM.do_validate_endpoint = do_validate_endpoint
|
||||||
|
|
||||||
|
return ipam.validate_endpoint()
|
||||||
|
|
||||||
|
def do_validate_endpoint(self, auth_credentials, cert):
|
||||||
|
# Your implemention goes here
|
||||||
|
...
|
||||||
|
```
|
||||||
|
All you need to do in order to implement an operation is add your specific logic in the places indicated by the comments in the corresponding source.py file.
|
||||||
|
**Tip: It is a good idea to build the package, upload it in vRA(C) and test it after implementing each operation.**
|
||||||
|
|
||||||
|
We advise integrators to implement the IPAM operations one by one in the following order:
|
||||||
|
|
||||||
|
1. Validate Endpoint
|
||||||
|
2. Get IP Ranges
|
||||||
|
3. Get IP Blocks (Optionally)
|
||||||
|
4. Allocate IP
|
||||||
|
5. Allocate IP Range (Optionally)
|
||||||
|
6. Deallocate IP
|
||||||
|
7. Deallocate IP Range (Optionally)
|
||||||
|
8. Update Record (Optionally)
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
**Tip: How to call vRA(C) REST endpoints from within the IPAM operation**\
|
||||||
|
You can execute REST calls against vRA from within the Python scripts.
|
||||||
|
This is done by using the ```context``` object in your ```handler```
|
||||||
|
|
||||||
|
```python
|
||||||
|
context.request(link='/iaas/api/machines', operation='GET', body='')
|
||||||
|
```
|
||||||
|
The ```context``` is configured to handle authentication, authorization and proxying of your requests.
|
||||||
|
|
||||||
|
Step 4: Define 3rd party libraries (in case you use some)
|
||||||
|
----------------
|
||||||
|
|
||||||
|
In order to use 3rd party Python libs in the source.py scripts, you need to define them in the `requirements.txt` file that is located next to each IPAM operation's source.py.
|
||||||
|
|
||||||
|
The plugin build script takes care of downloading the dependency libs defined in `requirements.txt` and package them in the correct format within the IPAM zip.
|
||||||
|
|
||||||
|
The only important thing to remember here is to always re-run `mvn package -PcollectDependencies` every time you add or remove new dependency from the `requirements.txt`
|
||||||
|
|
||||||
|
The `requirements.txt` format is defined [here](https://pip.readthedocs.io/en/1.1/requirements.html)
|
||||||
|
|
||||||
|
Step 5: Change specific properties in the `pom.xml` (if needed)
|
||||||
|
----------------
|
||||||
|
|
||||||
|
**Implementing the optional Update Record operation**\
|
||||||
|
Integrators can choose to optionally implement the Update Record operation.
|
||||||
|
This operation is used by the vRA(C) IPAM service to notify the external IPAM system that a VM has been successfully provisioned and to propagate the VM's MAC address to the IPAM system.
|
||||||
|
|
||||||
|
Support of this optional operation is controlled by the following property in the `pom.xml`:
|
||||||
|
`<provider.supportsUpdateRecord>true</provider.supportsUpdateRecord>`
|
||||||
|
|
||||||
|
Changing this to `false` will force the build to exclude the Update Operation from the IPAM.zip package.
|
||||||
|
|
||||||
|
**Note**: If you ever change the property value from `false` to `true`, you'd have to re-run the build with `mvn package -PcollectDependencies` since the dependencies for the Update Operation would need to be re-collected.
|
||||||
|
|
||||||
|
----
|
||||||
|
**Implementing the optional 'Get IP Blocks', 'Allocate IP Range' and 'Deallocate IP Range' operations**\
|
||||||
|
The three operations are part of the extended IPAM plugin specification for vRA 8.X. They enable the plugin to support provisioning of on-demand networks from vRA.
|
||||||
|
Every time a vRA user requests to provision an on-demand network on i.e. NSX-T, a CIDR for that network will be allocated from the plugin along with other network settings such as default gateway.
|
||||||
|
|
||||||
|
The support for this operations is controlled by the following property in the `pom.xml`:
|
||||||
|
`<provider.supportsOnDemandNetworks>false</provider.supportsOnDemandNetworks>`
|
||||||
|
|
||||||
|
Changing this to `true` will force the build to include the `get_ip_blocks`, `allocate_ip_range` and `deallocate_ip_range` operations inside the IPAM.zip package.
|
||||||
|
|
||||||
|
**Note**: The same as with the Update operation, changing the `provider.supportsOnDemandNetworks` property from `false` to `true` must be followed by re-run of the `mvn package -PcollectDependencies` command in order to collect the required dependencies.
|
||||||
|
|
||||||
|
----
|
||||||
|
**Supporting address spaces**\
|
||||||
|
External IPAM networks & ranges can be organized into logical groups with overlapping address spaces, serving a single routing domain.
|
||||||
|
By default, the **SampleIPAM.zip** that this SDK produces is configured to not support address spaces. If your IPAM system does have the notion of an address space, you can choose to enable support for address spaces. This is done by changing the following property in the `pom.xml`:
|
||||||
|
`<provider.supportsAddressSpaces>true</provider.supportsAddressSpaces>`
|
||||||
|
|
||||||
|
Step 6: Build the package with the implemented IPAM operations (actually, it is advisable to do so after implementing each operation)
|
||||||
|
----------------
|
||||||
|
It is a good idea to deploy the package to vRA(C) and test the operations after implementing each IPAM operation.
|
||||||
|
When you're ready with your implementation, you can build the package by running `mvn package` (or `mvn package -PcollectDependencies` if needed) again.
|
||||||
|
After you implement all of the required operations (and some optional ones, if you choose to do so), the IPAM package is ready to be distributed and used.
|
||||||
|
|
||||||
|
Troubleshooting
|
||||||
|
===============
|
||||||
|
|
||||||
|
The following list contains the most common errors that might occur during build time:
|
||||||
|
1. `mvn package` build fails with:
|
||||||
|
|
||||||
|
> [ERROR] Plugin org.apache.maven.plugins:maven-resources-plugin:3.1.0 or one of its dependencies could not be resolved: Failed to read artifact descriptor for org.apache.maven.plugins:maven-resources-plugin:jar:3.1.0: Could not transfer artifact org.apache.maven.plugins:maven-resources-plugin:pom:3.1.0 from/to central (https://repo.maven.apache.org/maven2): repo.maven.apache.org: Unknown host repo.maven.apache.org -> [Help 1]
|
||||||
|
|
||||||
|
**Resolution**:
|
||||||
|
Sometimes establishing connections to Maven Central fails. Retry again after couple of minutes. If the issue persists - check your internet connection.
|
||||||
|
|
||||||
|
2. `mvn package -PcollectDependencies` build fail with:
|
||||||
|
>[ERROR] DOCKER> Unable to pull 'vmware/photon2:20180424' : error pulling image configuration: Get https://production.cloudflare.docker.com/registry-v2/docker/registry/v2/blobs/sha256/12/1204ad97f071063bea855f351348e15e9cc03610cbfc8df46ab96b42d7cafa9f/data?verify=1578042999-Nu9yKJgKQcuFU0Y9hAQe%2BKEOKGo%3D: dial tcp: lookup production.cloudflare.docker.com on XXX:53: read udp XXX:57798->XXX:53: i/o timeout
|
||||||
|
|
||||||
|
**Resolution**:
|
||||||
|
Sometimes establishing connections to the Docker Registry times out. Retry again after couple of minutes. If the issue persists - check your internet connection
|
||||||
|
|
||||||
|
3. `mvn package -PcollectDependencies` build on `Windows` fails with:
|
||||||
|
> [ERROR] Failed to execute goal io.fabric8:docker-maven-plugin:0.31.0:start (start-container) on project sample-ipam: I/O Error: Unable to create container for [ipam-dependency-collector:latest] : Drive has not been shared (Internal Server Error: 500)
|
||||||
|
|
||||||
|
**Resolution**:
|
||||||
|
The build script uses Docker to collect the Python dependencies that are needed by the plugin. In order for Docker to operate correctly, it needs to have access to the Windows Drive that the build script resides in.
|
||||||
|
You need to allow Docker access to the respective drive: [Configure shared volume on Docker for Windows](https://blogs.msdn.microsoft.com/stevelasker/2016/06/14/configuring-docker-for-windows-volumes/)
|
||||||
|
4. `mvn package -PcollectDependencies` build fails with:
|
||||||
|
> [INFO] --- docker-maven-plugin:0.31.0:start (start-container) @ sample-ipam ---
|
||||||
|
[ERROR] DOCKER> Error occurred during container startup, shutting down...
|
||||||
|
[ERROR] DOCKER> I/O Error [Unable to create container for [ipam-dependency-collector:latest] : {"message":"Conflict. The container name \"/ipam-dependency-collector-1\" is already in use by container \"2bfb215381514cd6496ecd5d0103da0a4d94034c5691b25bdf27b16bd2236022\". You have to remove (or rename) that container to be able to reuse that name."} (Conflict: 409)]
|
||||||
|
|
||||||
|
**Resolution**:
|
||||||
|
Run `docker ps -a `
|
||||||
|
The output should look similar to this:
|
||||||
|
| CONTAINER ID | IMAGE | COMMAND | CREATED | STATUS | PORTS | NAMES
|
||||||
|
| ------------ | ----- | ------- | ------- | ------ | ----- | ---- |
|
||||||
|
| 2bfb21538151 | d886e9bba96e | "/bin/sh -c 'yes \| c…" | 3 minutes ago | Exited (0) 3 minutes ago | | ipam-dependency-collector-1
|
||||||
|
|
||||||
|
Locate the container with name `ipam-dependency-collector-*` and purge it:
|
||||||
|
Run `docker rm -f 2bfb21538151`
|
||||||
|
5. `mvn package -PcollectDependencies` build fails with:
|
||||||
|
> [INFO] --- docker-maven-plugin:0.31.0:build (build-image) @ sample-ipam ---
|
||||||
|
> [INFO] Building tar: ...\sample-abx-integration\target\docker\ipam-dependency-collector\latest\tmp\docker-build.tar
|
||||||
|
> [INFO] DOCKER> [ipam-dependency-collector:latest]: Created docker-build.tar in 214 milliseconds
|
||||||
|
> [ERROR] DOCKER> Unable to build image [ipam-dependency-collector:latest] : "The command '/bin/sh -c tdnf install -y python3-3.6.5-1.ph2 python3-pip-3.6.5-1.ph2 shadow && pip3 install --upgrade pip setuptools && pip3 install certifi' returned a non-zero code: 127" ["The command '/bin/sh -c tdnf install -y python3-3.6.5-1.ph2 python3-pip-3.6.5-1.ph2 shadow && pip3 install --upgrade pip setuptools && pip3 install certifi' returned a non-zero code: 127" ]
|
||||||
|
|
||||||
|
**Resolution**:
|
||||||
|
Sometimes the **tdnf** Photon OS package manager fails to install Python3 due to connectivity errors.
|
||||||
|
In case this happens, please wait for 1 min and retrigger the build.
|
||||||
|
If the issue persists, check your internet connectivity.
|
||||||
|
|
||||||
|
Changelog
|
||||||
|
============
|
||||||
|
|
||||||
|
## IPAM SDK 1.1.0:
|
||||||
|
**Features:**
|
||||||
|
- IPAM actions are now packaged for Python 3.7.5 runtime. User's 3rd party libraries that contain binaries (defined in requirements.txt and gathered during build time when -PcollectDependencies is supplied) are now compiled against Python 3.7.5 runtime (as opposed to Python 3.6).
|
||||||
|
If you upgrade from SDK 1.0.0, you'd have to recompile with -PcollectDependencies so that new libs for Python 3.7.5 are gathered.
|
||||||
|
- This version adds a new CHANGELOG.md file in src/main/resources to allow IPAM SDK users to keep track of bug fixes, features and additions to the plugin over the course of time when a new plugin version is released.
|
||||||
|
|
||||||
|
**Bug fixes:**
|
||||||
|
- As part of this release, a known permission issue for Linux users is fixed by adding the `-Duser.id` parameter.
|
259
open_source_licenses.txt
Normal file
259
open_source_licenses.txt
Normal file
|
@ -0,0 +1,259 @@
|
||||||
|
open_source_license.txt
|
||||||
|
|
||||||
|
VMware vRealize® Automation Third-Party IP Address Management™ SDK 1.0.0 GA
|
||||||
|
|
||||||
|
======================================================================
|
||||||
|
|
||||||
|
The following copyright statements and licenses apply to various open
|
||||||
|
source software packages (or portions thereof) that are distributed with
|
||||||
|
this VMware Product.
|
||||||
|
|
||||||
|
The VMware Product may also include other VMware components, which may
|
||||||
|
contain additional open source software packages. One or more such
|
||||||
|
open_source_licenses.txt files may therefore accompany this VMware
|
||||||
|
Product.
|
||||||
|
|
||||||
|
The VMware Product that includes this file does not necessarily use all
|
||||||
|
the open source software packages referred to below and may also only
|
||||||
|
use portions of a given package.
|
||||||
|
|
||||||
|
=============== TABLE OF CONTENTS =============================
|
||||||
|
|
||||||
|
The following is a listing of the open source components detailed in
|
||||||
|
this document. This list is provided for your convenience; please read
|
||||||
|
further if you wish to review the copyright notice(s) and the full text
|
||||||
|
of the license associated with each component.
|
||||||
|
|
||||||
|
|
||||||
|
SECTION 1: Apache License, V2.0
|
||||||
|
|
||||||
|
>>> python-requests-2.21.0
|
||||||
|
|
||||||
|
|
||||||
|
APPENDIX. Standard License Files
|
||||||
|
|
||||||
|
>>> Apache License, V2.0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--------------- SECTION 1: Apache License, V2.0 ----------
|
||||||
|
|
||||||
|
Apache License, V2.0 is applicable to the following component(s).
|
||||||
|
|
||||||
|
|
||||||
|
>>> python-requests-2.21.0
|
||||||
|
|
||||||
|
Copyright 2018 Kenneth Reitz
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
https://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.
|
||||||
|
|
||||||
|
=============== APPENDIX. Standard License Files ==============
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--------------- SECTION 1: Apache License, V2.0 -----------
|
||||||
|
|
||||||
|
Apache License
|
||||||
|
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by the
|
||||||
|
copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all other
|
||||||
|
entities that control, are controlled by, or are under common control
|
||||||
|
with that entity. For the purposes of this definition, "control" means
|
||||||
|
(i) the power, direct or indirect, to cause the direction or management
|
||||||
|
of such entity, whether by contract or otherwise, or (ii) ownership
|
||||||
|
of fifty percent (50%) or more of the outstanding shares, or (iii)
|
||||||
|
beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity exercising
|
||||||
|
permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation source,
|
||||||
|
and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical transformation
|
||||||
|
or translation of a Source form, including but not limited to compiled
|
||||||
|
object code, generated documentation, and conversions to other media
|
||||||
|
types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a copyright
|
||||||
|
notice that is included in or attached to the work (an example is provided
|
||||||
|
in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object form,
|
||||||
|
that is based on (or derived from) the Work and for which the editorial
|
||||||
|
revisions, annotations, elaborations, or other modifications represent,
|
||||||
|
as a whole, an original work of authorship. For the purposes of this
|
||||||
|
License, Derivative Works shall not include works that remain separable
|
||||||
|
from, or merely link (or bind by name) to the interfaces of, the Work
|
||||||
|
and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including the
|
||||||
|
original version of the Work and any modifications or additions to
|
||||||
|
that Work or Derivative Works thereof, that is intentionally submitted
|
||||||
|
to Licensor for inclusion in the Work by the copyright owner or by an
|
||||||
|
individual or Legal Entity authorized to submit on behalf of the copyright
|
||||||
|
owner. For the purposes of this definition, "submitted" means any form of
|
||||||
|
electronic, verbal, or written communication sent to the Licensor or its
|
||||||
|
representatives, including but not limited to communication on electronic
|
||||||
|
mailing lists, source code control systems, and issue tracking systems
|
||||||
|
that are managed by, or on behalf of, the Licensor for the purpose of
|
||||||
|
discussing and improving the Work, but excluding communication that is
|
||||||
|
conspicuously marked or otherwise designated in writing by the copyright
|
||||||
|
owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License.
|
||||||
|
Subject to the terms and conditions of this License, each Contributor
|
||||||
|
hereby grants to You a perpetual, worldwide, non-exclusive, no-charge,
|
||||||
|
royalty-free, irrevocable copyright license to reproduce, prepare
|
||||||
|
Derivative Works of, publicly display, publicly perform, sublicense, and
|
||||||
|
distribute the Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License.
|
||||||
|
Subject to the terms and conditions of this License, each Contributor
|
||||||
|
hereby grants to You a perpetual, worldwide, non-exclusive, no-charge,
|
||||||
|
royalty- free, irrevocable (except as stated in this section) patent
|
||||||
|
license to make, have made, use, offer to sell, sell, import, and
|
||||||
|
otherwise transfer the Work, where such license applies only to those
|
||||||
|
patent claims licensable by such Contributor that are necessarily
|
||||||
|
infringed by their Contribution(s) alone or by combination of
|
||||||
|
their Contribution(s) with the Work to which such Contribution(s)
|
||||||
|
was submitted. If You institute patent litigation against any entity
|
||||||
|
(including a cross-claim or counterclaim in a lawsuit) alleging that the
|
||||||
|
Work or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses granted
|
||||||
|
to You under this License for that Work shall terminate as of the date
|
||||||
|
such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution.
|
||||||
|
You may reproduce and distribute copies of the Work or Derivative Works
|
||||||
|
thereof in any medium, with or without modifications, and in Source or
|
||||||
|
Object form, provided that You meet the following conditions:
|
||||||
|
|
||||||
|
a. You must give any other recipients of the Work or Derivative Works
|
||||||
|
a copy of this License; and
|
||||||
|
|
||||||
|
b. You must cause any modified files to carry prominent notices stating
|
||||||
|
that You changed the files; and
|
||||||
|
|
||||||
|
c. You must retain, in the Source form of any Derivative Works that
|
||||||
|
You distribute, all copyright, patent, trademark, and attribution
|
||||||
|
notices from the Source form of the Work, excluding those notices
|
||||||
|
that do not pertain to any part of the Derivative Works; and
|
||||||
|
|
||||||
|
d. If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one of
|
||||||
|
the following places: within a NOTICE text file distributed as part
|
||||||
|
of the Derivative Works; within the Source form or documentation,
|
||||||
|
if provided along with the Derivative Works; or, within a display
|
||||||
|
generated by the Derivative Works, if and wherever such third-party
|
||||||
|
notices normally appear. The contents of the NOTICE file are for
|
||||||
|
informational purposes only and do not modify the License. You
|
||||||
|
may add Your own attribution notices within Derivative Works that
|
||||||
|
You distribute, alongside or as an addendum to the NOTICE text
|
||||||
|
from the Work, provided that such additional attribution notices
|
||||||
|
cannot be construed as modifying the License. You may add Your own
|
||||||
|
copyright statement to Your modifications and may provide additional
|
||||||
|
or different license terms and conditions for use, reproduction, or
|
||||||
|
distribution of Your modifications, or for any such Derivative Works
|
||||||
|
as a whole, provided Your use, reproduction, and distribution of the
|
||||||
|
Work otherwise complies with the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions.
|
||||||
|
Unless You explicitly state otherwise, any Contribution intentionally
|
||||||
|
submitted for inclusion in the Work by You to the Licensor shall be
|
||||||
|
under the terms and conditions of this License, without any additional
|
||||||
|
terms or conditions. Notwithstanding the above, nothing herein shall
|
||||||
|
supersede or modify the terms of any separate license agreement you may
|
||||||
|
have executed with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks.
|
||||||
|
This License does not grant permission to use the trade names, trademarks,
|
||||||
|
service marks, or product names of the Licensor, except as required for
|
||||||
|
reasonable and customary use in describing the origin of the Work and
|
||||||
|
reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty.
|
||||||
|
Unless required by applicable law or agreed to in writing, Licensor
|
||||||
|
provides the Work (and each Contributor provides its Contributions) on
|
||||||
|
an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||||
|
express or implied, including, without limitation, any warranties or
|
||||||
|
conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any risks
|
||||||
|
associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability.
|
||||||
|
In no event and under no legal theory, whether in tort (including
|
||||||
|
negligence), contract, or otherwise, unless required by applicable law
|
||||||
|
(such as deliberate and grossly negligent acts) or agreed to in writing,
|
||||||
|
shall any Contributor be liable to You for damages, including any direct,
|
||||||
|
indirect, special, incidental, or consequential damages of any character
|
||||||
|
arising as a result of this License or out of the use or inability to
|
||||||
|
use the Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all other
|
||||||
|
commercial damages or losses), even if such Contributor has been advised
|
||||||
|
of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability.
|
||||||
|
While redistributing the Work or Derivative Works thereof, You may
|
||||||
|
choose to offer, and charge a fee for, acceptance of support, warranty,
|
||||||
|
indemnity, or other liability obligations and/or rights consistent with
|
||||||
|
this License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf of
|
||||||
|
any other Contributor, and only if You agree to indemnify, defend, and
|
||||||
|
hold each Contributor harmless for any liability incurred by, or claims
|
||||||
|
asserted against, such Contributor by reason of your accepting any such
|
||||||
|
warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
|
||||||
|
======================================================================
|
||||||
|
|
||||||
|
To the extent any open source components are licensed under the GPL
|
||||||
|
and/or LGPL, or other similar licenses that require the source code
|
||||||
|
and/or modifications to source code to be made available (as would be
|
||||||
|
noted above), you may obtain a copy of the source code corresponding to
|
||||||
|
the binaries for such open source components and modifications thereto,
|
||||||
|
if any, (the "Source Files"), by downloading the Source Files from
|
||||||
|
VMware's website at http://www.vmware.com/download/open_source.html, or
|
||||||
|
by sending a request, with your name and address to: VMware, Inc., 3401
|
||||||
|
Hillview Avenue, Palo Alto, CA 94304, United States of America. All such
|
||||||
|
requests should clearly specify: OPEN SOURCE FILES REQUEST, Attention
|
||||||
|
General Counsel. VMware shall mail a copy of the Source Files to you on
|
||||||
|
a CD or equivalent physical medium. This offer to obtain a copy of the
|
||||||
|
Source Files is valid for three years from the date you acquired this
|
||||||
|
Software product. Alternatively, the Source Files may accompany the
|
||||||
|
VMware product.
|
||||||
|
[vraipamsdk100GARZ022520]
|
372
pom.xml
Normal file
372
pom.xml
Normal file
|
@ -0,0 +1,372 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
Copyright (c) 2020 VMware, Inc. All Rights Reserved.
|
||||||
|
|
||||||
|
This product is licensed to you under the Apache License, Version 2.0 (the "License").
|
||||||
|
You may not use this product except in compliance with the License.
|
||||||
|
|
||||||
|
This product may include a number of subcomponents with separate copyright notices
|
||||||
|
and license terms. Your use of these subcomponents is subject to the terms and
|
||||||
|
conditions of the subcomponent's license, as noted in the LICENSE file.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>com.vmware.cas.ipam.adapter</groupId>
|
||||||
|
<artifactId>sample-ipam</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<provider.name>phpIPAM</provider.name>
|
||||||
|
<provider.description>phpIPAM integration for vRA</provider.description>
|
||||||
|
<provider.version>0.1</provider.version>
|
||||||
|
|
||||||
|
<provider.supportsAddressSpaces>false</provider.supportsAddressSpaces>
|
||||||
|
<provider.supportsUpdateRecord>true</provider.supportsUpdateRecord>
|
||||||
|
<provider.supportsOnDemandNetworks>false</provider.supportsOnDemandNetworks>
|
||||||
|
|
||||||
|
<user.id>1000</user.id>
|
||||||
|
</properties>
|
||||||
|
<profiles>
|
||||||
|
<profile>
|
||||||
|
<id>collectDependencies</id>
|
||||||
|
<activation>
|
||||||
|
<file>
|
||||||
|
<missing>${basedir}/target/dependencies.collected.flag</missing>
|
||||||
|
</file>
|
||||||
|
</activation>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>io.fabric8</groupId>
|
||||||
|
<artifactId>docker-maven-plugin</artifactId>
|
||||||
|
<version>0.31.0</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>build-image</id>
|
||||||
|
<phase>prepare-package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>build</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<name>ipam-dependency-collector:latest</name>
|
||||||
|
<images>
|
||||||
|
<image>
|
||||||
|
<name>ipam-dependency-collector:latest</name>
|
||||||
|
<build>
|
||||||
|
<dockerFile>${project.basedir}/Dockerfile</dockerFile>
|
||||||
|
<filter>@</filter>
|
||||||
|
</build>
|
||||||
|
</image>
|
||||||
|
</images>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>start-container</id>
|
||||||
|
<phase>prepare-package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>start</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<images>
|
||||||
|
<image>
|
||||||
|
<name>ipam-dependency-collector:latest</name>
|
||||||
|
<run>
|
||||||
|
<volumes>
|
||||||
|
<bind>${basedir}/target:/ipam/result</bind>
|
||||||
|
</volumes>
|
||||||
|
<wait>
|
||||||
|
<log>Collecting-dependencies-complete</log>
|
||||||
|
<time>600000</time> <!-- Wait for 10 minutes to copy the dependencies into the mounted dir -->
|
||||||
|
</wait>
|
||||||
|
<user>${user.name}</user>
|
||||||
|
</run>
|
||||||
|
</image>
|
||||||
|
</images>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>stop-container</id>
|
||||||
|
<phase>prepare-package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>stop</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-resources-plugin</artifactId>
|
||||||
|
<version>3.1.0</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<id>copy-dependencies-collected-flag</id>
|
||||||
|
<goals>
|
||||||
|
<goal>copy-resources</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<outputDirectory>${basedir}/target</outputDirectory>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>src/main/resources</directory>
|
||||||
|
<includes>
|
||||||
|
<include>dependencies.collected.flag</include>
|
||||||
|
</includes>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
|
<build>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>${basedir}/src/main/resources</directory>
|
||||||
|
<filtering>true</filtering>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>build-helper-maven-plugin</artifactId>
|
||||||
|
<version>1.12</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>dynamic-set-props</id>
|
||||||
|
<phase>initialize</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>bsh-property</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<source>skipUpdateRecord =
|
||||||
|
!${provider.supportsUpdateRecord};
|
||||||
|
excludeUpdateRecordFromAssemblyFilePattern
|
||||||
|
= skipUpdateRecord ? "update_record.abx"
|
||||||
|
: "dont-exclude"; skipOnDemandNetworks =
|
||||||
|
!${provider.supportsOnDemandNetworks};
|
||||||
|
excludeGetIpBlocksFromAssemblyFilePattern
|
||||||
|
= skipOnDemandNetworks ?
|
||||||
|
"get_ip_blocks.abx" : "dont-exclude";
|
||||||
|
excludeAllocateIpRangeFromAssemblyFilePattern
|
||||||
|
= skipOnDemandNetworks ?
|
||||||
|
"allocate_ip_range.abx" : "dont-exclude";
|
||||||
|
excludeDeallocateIpRangeFromAssemblyFilePattern
|
||||||
|
= skipOnDemandNetworks ?
|
||||||
|
"deallocate_ip_range.abx" : "dont-exclude";
|
||||||
|
supportsAddressSpaces
|
||||||
|
= ${provider.supportsAddressSpaces} ?
|
||||||
|
"supportsAddressSpaces: true" : "";
|
||||||
|
</source>
|
||||||
|
<properties>
|
||||||
|
<property>skipUpdateRecord</property>
|
||||||
|
<property>excludeUpdateRecordFromAssemblyFilePattern</property>
|
||||||
|
<property>skipOnDemandNetworks</property>
|
||||||
|
<property>excludeGetIpBlocksFromAssemblyFilePattern</property>
|
||||||
|
<property>excludeAllocateIpRangeFromAssemblyFilePattern</property>
|
||||||
|
<property>excludeDeallocateIpRangeFromAssemblyFilePattern</property>
|
||||||
|
<property>supportsAddressSpaces</property>
|
||||||
|
</properties>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-resources-plugin</artifactId>
|
||||||
|
<version>3.1.0</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>copy-scripts</id>
|
||||||
|
<phase>validate</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>copy-resources</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<outputDirectory>${basedir}/target/python</outputDirectory>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>src/main/python</directory>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>resources</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<version>2.2-beta-5</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>allocate_ip</id>
|
||||||
|
<phase>prepare-package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>single</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<descriptor>src/assembly/python/allocate_ip.xml</descriptor>
|
||||||
|
<finalName>allocate_ip</finalName>
|
||||||
|
<outputDirectory>${project.build.directory}/actions</outputDirectory>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>deallocate_ip</id>
|
||||||
|
<phase>prepare-package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>single</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<descriptor>src/assembly/python/deallocate_ip.xml</descriptor>
|
||||||
|
<finalName>deallocate_ip</finalName>
|
||||||
|
<outputDirectory>${project.build.directory}/actions</outputDirectory>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>get_ip_ranges</id>
|
||||||
|
<phase>prepare-package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>single</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<descriptor>src/assembly/python/get_ip_ranges.xml</descriptor>
|
||||||
|
<finalName>get_ip_ranges</finalName>
|
||||||
|
<outputDirectory>${project.build.directory}/actions</outputDirectory>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>update_record</id>
|
||||||
|
<phase>prepare-package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>single</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<descriptor>src/assembly/python/update_record.xml</descriptor>
|
||||||
|
<finalName>update_record</finalName>
|
||||||
|
<outputDirectory>${project.build.directory}/actions</outputDirectory>
|
||||||
|
<skipAssembly>${skipUpdateRecord}</skipAssembly>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>validate_endpoint</id>
|
||||||
|
<phase>prepare-package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>single</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<descriptor>src/assembly/python/validate_endpoint.xml</descriptor>
|
||||||
|
<finalName>validate_endpoint</finalName>
|
||||||
|
<outputDirectory>${project.build.directory}/actions</outputDirectory>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>get_ip_blocks</id>
|
||||||
|
<phase>prepare-package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>single</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<descriptor>src/assembly/python/get_ip_blocks.xml</descriptor>
|
||||||
|
<finalName>get_ip_blocks</finalName>
|
||||||
|
<outputDirectory>${project.build.directory}/actions</outputDirectory>
|
||||||
|
<skipAssembly>${skipOnDemandNetworks}</skipAssembly>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>allocate_ip_range</id>
|
||||||
|
<phase>prepare-package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>single</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<descriptor>src/assembly/python/allocate_ip_range.xml</descriptor>
|
||||||
|
<finalName>allocate_ip_range</finalName>
|
||||||
|
<outputDirectory>${project.build.directory}/actions</outputDirectory>
|
||||||
|
<skipAssembly>${skipOnDemandNetworks}</skipAssembly>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>deallocate_ip_range</id>
|
||||||
|
<phase>prepare-package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>single</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<descriptor>src/assembly/python/deallocate_ip_range.xml</descriptor>
|
||||||
|
<finalName>deallocate_ip_range</finalName>
|
||||||
|
<outputDirectory>${project.build.directory}/actions</outputDirectory>
|
||||||
|
<skipAssembly>${skipOnDemandNetworks}</skipAssembly>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>zip-actions</id>
|
||||||
|
<phase>prepare-package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>single</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<descriptor>src/assembly/zip-actions.xml</descriptor>
|
||||||
|
<finalName>bundle</finalName>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>zip-provider</id>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>single</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<descriptor>src/assembly/zip-provider.xml</descriptor>
|
||||||
|
<finalName>${provider.name}</finalName>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>net.nicoulaj.maven.plugins</groupId>
|
||||||
|
<artifactId>checksum-maven-plugin</artifactId>
|
||||||
|
<version>1.8</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>build-ipam-package-signature</id>
|
||||||
|
<phase>prepare-package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>files</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<fileSets>
|
||||||
|
<fileSet>
|
||||||
|
<directory>${basedir}/target/</directory>
|
||||||
|
<includes>
|
||||||
|
<include>bundle.zip</include>
|
||||||
|
</includes>
|
||||||
|
</fileSet>
|
||||||
|
</fileSets>
|
||||||
|
<algorithms>
|
||||||
|
<algorithm>SHA-256</algorithm>
|
||||||
|
</algorithms>
|
||||||
|
<csvSummary>false</csvSummary>
|
||||||
|
<shasumSummary>true</shasumSummary>
|
||||||
|
<shasumSummaryFile>signature</shasumSummaryFile>
|
||||||
|
<individualFiles>false</individualFiles>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
25
src/assembly/python/allocate_ip.xml
Normal file
25
src/assembly/python/allocate_ip.xml
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<assembly
|
||||||
|
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
|
||||||
|
<formats>
|
||||||
|
<format>zip</format>
|
||||||
|
</formats>
|
||||||
|
<includeBaseDirectory>false</includeBaseDirectory>
|
||||||
|
<fileSets>
|
||||||
|
<fileSet>
|
||||||
|
<directory>target/python/allocate_ip</directory>
|
||||||
|
<includes>
|
||||||
|
<include>**</include>
|
||||||
|
</includes>
|
||||||
|
<outputDirectory></outputDirectory>
|
||||||
|
</fileSet>
|
||||||
|
<fileSet>
|
||||||
|
<directory>target/python/commons</directory>
|
||||||
|
<includes>
|
||||||
|
<include>**</include>
|
||||||
|
</includes>
|
||||||
|
<outputDirectory></outputDirectory>
|
||||||
|
</fileSet>
|
||||||
|
</fileSets>
|
||||||
|
</assembly>
|
25
src/assembly/python/allocate_ip_range.xml
Normal file
25
src/assembly/python/allocate_ip_range.xml
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<assembly
|
||||||
|
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
|
||||||
|
<formats>
|
||||||
|
<format>zip</format>
|
||||||
|
</formats>
|
||||||
|
<includeBaseDirectory>false</includeBaseDirectory>
|
||||||
|
<fileSets>
|
||||||
|
<fileSet>
|
||||||
|
<directory>target/python/allocate_ip_range</directory>
|
||||||
|
<includes>
|
||||||
|
<include>**</include>
|
||||||
|
</includes>
|
||||||
|
<outputDirectory></outputDirectory>
|
||||||
|
</fileSet>
|
||||||
|
<fileSet>
|
||||||
|
<directory>target/python/commons</directory>
|
||||||
|
<includes>
|
||||||
|
<include>**</include>
|
||||||
|
</includes>
|
||||||
|
<outputDirectory></outputDirectory>
|
||||||
|
</fileSet>
|
||||||
|
</fileSets>
|
||||||
|
</assembly>
|
25
src/assembly/python/deallocate_ip.xml
Normal file
25
src/assembly/python/deallocate_ip.xml
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<assembly
|
||||||
|
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
|
||||||
|
<formats>
|
||||||
|
<format>zip</format>
|
||||||
|
</formats>
|
||||||
|
<includeBaseDirectory>false</includeBaseDirectory>
|
||||||
|
<fileSets>
|
||||||
|
<fileSet>
|
||||||
|
<directory>target/python/deallocate_ip</directory>
|
||||||
|
<includes>
|
||||||
|
<include>**</include>
|
||||||
|
</includes>
|
||||||
|
<outputDirectory></outputDirectory>
|
||||||
|
</fileSet>
|
||||||
|
<fileSet>
|
||||||
|
<directory>target/python/commons</directory>
|
||||||
|
<includes>
|
||||||
|
<include>**</include>
|
||||||
|
</includes>
|
||||||
|
<outputDirectory></outputDirectory>
|
||||||
|
</fileSet>
|
||||||
|
</fileSets>
|
||||||
|
</assembly>
|
25
src/assembly/python/deallocate_ip_range.xml
Normal file
25
src/assembly/python/deallocate_ip_range.xml
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<assembly
|
||||||
|
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
|
||||||
|
<formats>
|
||||||
|
<format>zip</format>
|
||||||
|
</formats>
|
||||||
|
<includeBaseDirectory>false</includeBaseDirectory>
|
||||||
|
<fileSets>
|
||||||
|
<fileSet>
|
||||||
|
<directory>target/python/deallocate_ip_range</directory>
|
||||||
|
<includes>
|
||||||
|
<include>**</include>
|
||||||
|
</includes>
|
||||||
|
<outputDirectory></outputDirectory>
|
||||||
|
</fileSet>
|
||||||
|
<fileSet>
|
||||||
|
<directory>target/python/commons</directory>
|
||||||
|
<includes>
|
||||||
|
<include>**</include>
|
||||||
|
</includes>
|
||||||
|
<outputDirectory></outputDirectory>
|
||||||
|
</fileSet>
|
||||||
|
</fileSets>
|
||||||
|
</assembly>
|
25
src/assembly/python/get_ip_blocks.xml
Normal file
25
src/assembly/python/get_ip_blocks.xml
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<assembly
|
||||||
|
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
|
||||||
|
<formats>
|
||||||
|
<format>zip</format>
|
||||||
|
</formats>
|
||||||
|
<includeBaseDirectory>false</includeBaseDirectory>
|
||||||
|
<fileSets>
|
||||||
|
<fileSet>
|
||||||
|
<directory>target/python/get_ip_blocks</directory>
|
||||||
|
<includes>
|
||||||
|
<include>**</include>
|
||||||
|
</includes>
|
||||||
|
<outputDirectory></outputDirectory>
|
||||||
|
</fileSet>
|
||||||
|
<fileSet>
|
||||||
|
<directory>target/python/commons</directory>
|
||||||
|
<includes>
|
||||||
|
<include>**</include>
|
||||||
|
</includes>
|
||||||
|
<outputDirectory></outputDirectory>
|
||||||
|
</fileSet>
|
||||||
|
</fileSets>
|
||||||
|
</assembly>
|
25
src/assembly/python/get_ip_ranges.xml
Normal file
25
src/assembly/python/get_ip_ranges.xml
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<assembly
|
||||||
|
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
|
||||||
|
<formats>
|
||||||
|
<format>zip</format>
|
||||||
|
</formats>
|
||||||
|
<includeBaseDirectory>false</includeBaseDirectory>
|
||||||
|
<fileSets>
|
||||||
|
<fileSet>
|
||||||
|
<directory>target/python/get_ip_ranges</directory>
|
||||||
|
<includes>
|
||||||
|
<include>**</include>
|
||||||
|
</includes>
|
||||||
|
<outputDirectory></outputDirectory>
|
||||||
|
</fileSet>
|
||||||
|
<fileSet>
|
||||||
|
<directory>target/python/commons</directory>
|
||||||
|
<includes>
|
||||||
|
<include>**</include>
|
||||||
|
</includes>
|
||||||
|
<outputDirectory></outputDirectory>
|
||||||
|
</fileSet>
|
||||||
|
</fileSets>
|
||||||
|
</assembly>
|
25
src/assembly/python/update_record.xml
Normal file
25
src/assembly/python/update_record.xml
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<assembly
|
||||||
|
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
|
||||||
|
<formats>
|
||||||
|
<format>zip</format>
|
||||||
|
</formats>
|
||||||
|
<includeBaseDirectory>false</includeBaseDirectory>
|
||||||
|
<fileSets>
|
||||||
|
<fileSet>
|
||||||
|
<directory>target/python/update_record</directory>
|
||||||
|
<includes>
|
||||||
|
<include>**</include>
|
||||||
|
</includes>
|
||||||
|
<outputDirectory></outputDirectory>
|
||||||
|
</fileSet>
|
||||||
|
<fileSet>
|
||||||
|
<directory>target/python/commons</directory>
|
||||||
|
<includes>
|
||||||
|
<include>**</include>
|
||||||
|
</includes>
|
||||||
|
<outputDirectory></outputDirectory>
|
||||||
|
</fileSet>
|
||||||
|
</fileSets>
|
||||||
|
</assembly>
|
25
src/assembly/python/validate_endpoint.xml
Normal file
25
src/assembly/python/validate_endpoint.xml
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<assembly
|
||||||
|
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
|
||||||
|
<formats>
|
||||||
|
<format>zip</format>
|
||||||
|
</formats>
|
||||||
|
<includeBaseDirectory>false</includeBaseDirectory>
|
||||||
|
<fileSets>
|
||||||
|
<fileSet>
|
||||||
|
<directory>target/python/validate_endpoint</directory>
|
||||||
|
<includes>
|
||||||
|
<include>**</include>
|
||||||
|
</includes>
|
||||||
|
<outputDirectory></outputDirectory>
|
||||||
|
</fileSet>
|
||||||
|
<fileSet>
|
||||||
|
<directory>target/python/commons</directory>
|
||||||
|
<includes>
|
||||||
|
<include>**</include>
|
||||||
|
</includes>
|
||||||
|
<outputDirectory></outputDirectory>
|
||||||
|
</fileSet>
|
||||||
|
</fileSets>
|
||||||
|
</assembly>
|
28
src/assembly/zip-actions.xml
Normal file
28
src/assembly/zip-actions.xml
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
<assembly
|
||||||
|
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
|
||||||
|
<formats>
|
||||||
|
<format>zip</format>
|
||||||
|
</formats>
|
||||||
|
<includeBaseDirectory>false</includeBaseDirectory>
|
||||||
|
<fileSets>
|
||||||
|
<fileSet>
|
||||||
|
<directory>target/classes/bundle</directory>
|
||||||
|
<outputDirectory></outputDirectory>
|
||||||
|
<excludes>
|
||||||
|
<exclude>${excludeUpdateRecordFromAssemblyFilePattern}</exclude>
|
||||||
|
<exclude>${excludeGetIpBlocksFromAssemblyFilePattern}</exclude>
|
||||||
|
<exclude>${excludeAllocateIpRangeFromAssemblyFilePattern}</exclude>
|
||||||
|
<exclude>${excludeDeallocateIpRangeFromAssemblyFilePattern}</exclude>
|
||||||
|
</excludes>
|
||||||
|
</fileSet>
|
||||||
|
<fileSet>
|
||||||
|
<directory>target/actions</directory>
|
||||||
|
<includes>
|
||||||
|
<include>*.zip</include>
|
||||||
|
</includes>
|
||||||
|
<outputDirectory></outputDirectory>
|
||||||
|
</fileSet>
|
||||||
|
</fileSets>
|
||||||
|
</assembly>
|
29
src/assembly/zip-provider.xml
Normal file
29
src/assembly/zip-provider.xml
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
<assembly
|
||||||
|
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
|
||||||
|
<formats>
|
||||||
|
<format>zip</format>
|
||||||
|
</formats>
|
||||||
|
<includeBaseDirectory>false</includeBaseDirectory>
|
||||||
|
<fileSets>
|
||||||
|
<fileSet>
|
||||||
|
<directory>target/classes</directory>
|
||||||
|
<outputDirectory></outputDirectory>
|
||||||
|
<includes>
|
||||||
|
<include>registration.yaml</include>
|
||||||
|
<include>endpoint-schema.json</include>
|
||||||
|
<include>logo.png</include>
|
||||||
|
<include>CHANGELOG.md</include>
|
||||||
|
</includes>
|
||||||
|
</fileSet>
|
||||||
|
<fileSet>
|
||||||
|
<directory>target</directory>
|
||||||
|
<outputDirectory></outputDirectory>
|
||||||
|
<includes>
|
||||||
|
<include>bundle.zip</include>
|
||||||
|
<include>signature</include>
|
||||||
|
</includes>
|
||||||
|
</fileSet>
|
||||||
|
</fileSets>
|
||||||
|
</assembly>
|
BIN
src/main/python/.DS_Store
vendored
Normal file
BIN
src/main/python/.DS_Store
vendored
Normal file
Binary file not shown.
0
src/main/python/allocate_ip/__init__.py
Normal file
0
src/main/python/allocate_ip/__init__.py
Normal file
1
src/main/python/allocate_ip/requirements.txt
Normal file
1
src/main/python/allocate_ip/requirements.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
requests==2.21.0
|
143
src/main/python/allocate_ip/source.py
Normal file
143
src/main/python/allocate_ip/source.py
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
"""
|
||||||
|
Copyright (c) 2020 VMware, Inc.
|
||||||
|
|
||||||
|
This product is licensed to you under the Apache License, Version 2.0 (the "License").
|
||||||
|
You may not use this product except in compliance with the License.
|
||||||
|
|
||||||
|
This product may include a number of subcomponents with separate copyright notices
|
||||||
|
and license terms. Your use of these subcomponents is subject to the terms and
|
||||||
|
conditions of the subcomponent's license, as noted in the LICENSE file.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import requests
|
||||||
|
from vra_ipam_utils.ipam import IPAM
|
||||||
|
import logging
|
||||||
|
|
||||||
|
"""
|
||||||
|
Example payload
|
||||||
|
|
||||||
|
"inputs": {
|
||||||
|
"resourceInfo": {
|
||||||
|
"id": "11f912e71454a075574a728848458",
|
||||||
|
"name": "external-ipam-it-mcm-323412",
|
||||||
|
"description": "test",
|
||||||
|
"type": "VM",
|
||||||
|
"owner": "mdzhigarov@vmware.com",
|
||||||
|
"orgId": "ce811934-ea1a-4f53-b6ec-465e6ca7d126",
|
||||||
|
"properties": {
|
||||||
|
"osType": "WINDOWS",
|
||||||
|
"vcUuid": "ff257ed9-070b-45eb-b2e7-d63926d5bdd7",
|
||||||
|
"__moref": "VirtualMachine:vm-288560",
|
||||||
|
"memoryGB": "4",
|
||||||
|
"datacenter": "Datacenter:datacenter-2",
|
||||||
|
"provisionGB": "1",
|
||||||
|
"__dcSelfLink": "/resources/groups/b28c7b8de065f07558b1612fce028",
|
||||||
|
"softwareName": "Microsoft Windows XP Professional (32-bit)",
|
||||||
|
"__computeType": "VirtualMachine",
|
||||||
|
"__hasSnapshot": "false",
|
||||||
|
"__placementLink": "/resources/compute/9bdc98681fb8b27557252188607b8",
|
||||||
|
"__computeHostLink": "/resources/compute/9bdc98681fb8b27557252188607b8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ipAllocations": [
|
||||||
|
{
|
||||||
|
"id": "111bb2f0-02fd-4983-94d2-8ac11768150f",
|
||||||
|
"ipRangeIds": [
|
||||||
|
"network/ZG5zLm5ldHdvcmskMTAuMjMuMTE3LjAvMjQvMA:10.23.117.0/24/default"
|
||||||
|
],
|
||||||
|
"nicIndex": "0",
|
||||||
|
"isPrimary": "true",
|
||||||
|
"size": "1",
|
||||||
|
"properties": {
|
||||||
|
"__moref": "DistributedVirtualPortgroup:dvportgroup-307087",
|
||||||
|
"__dvsUuid": "0c 8c 0b 50 46 b6 1c f2-e8 63 f4 24 24 d7 24 6c",
|
||||||
|
"__dcSelfLink": "/resources/groups/abe46b8cfa663a7558b28a6ffe088",
|
||||||
|
"__computeType": "DistributedVirtualPortgroup",
|
||||||
|
"__portgroupKey": "dvportgroup-307087"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"endpoint": {
|
||||||
|
"id": "f097759d8736675585c4c5d272cd",
|
||||||
|
"endpointProperties": {
|
||||||
|
"hostName": "sampleipam.sof-mbu.eng.vmware.com",
|
||||||
|
"projectId": "111bb2f0-02fd-4983-94d2-8ac11768150f",
|
||||||
|
"providerId": "d8a5e3f2-d839-4365-af5b-f48de588fdc1",
|
||||||
|
"certificate": "-----BEGIN CERTIFICATE-----\nMIID0jCCArqgAwIBAgIQQaJF55UCb58f9KgQLD/QgTANBgkqhkiG9w0BAQUFADCB\niTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExEjAQBgNVBAcTCVN1\nbm55dmFsZTERMA8GA1UEChMISW5mb2Jsb3gxFDASBgNVBAsTC0VuZ2luZWVyaW5n\nMSgwJgYDVQQDEx9pbmZvYmxveC5zb2YtbWJ1LmVuZy52bXdhcmUuY29tMB4XDTE5\nMDEyOTEzMDExMloXDTIwMDEyOTEzMDExMlowgYkxCzAJBgNVBAYTAlVTMRMwEQYD\nVQQIEwpDYWxpZm9ybmlhMRIwEAYDVQQHEwlTdW5ueXZhbGUxETAPBgNVBAoTCElu\nZm9ibG94MRQwEgYDVQQLEwtFbmdpbmVlcmluZzEoMCYGA1UEAxMfaW5mb2Jsb3gu\nc29mLW1idS5lbmcudm13YXJlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC\nAQoCggEBAMMLNTqbAri6rt/H8iC4UgRdN0qj+wk0R2blmD9h1BiZJTeQk1r9i2rz\nzUOZHvE8Bld8m8xJ+nysWHaoFFGTX8bOd/p20oJBGbCLqXtoLMMBGAlP7nzWGBXH\nBYUS7kMv/CG+PSX0uuB0pRbhwOFq8Y69m4HRnn2X0WJGuu+v0FmRK/1m/kCacHga\nMBKaIgbwN72rW1t/MK0ijogmLR1ASY4FlMn7OBHIEUzO+dWFBh+gPDjoBECTTH8W\n5AK9TnYdxwAtJRYWmnVqtLoT3bImtSfI4YLUtpr9r13Kv5FkYVbXov1KBrQPbYyp\n72uT2ZgDJT4YUuWyKpMppgw1VcG3MosCAwEAAaM0MDIwMAYDVR0RBCkwJ4cEChda\nCoIfaW5mb2Jsb3guc29mLW1idS5lbmcudm13YXJlLmNvbTANBgkqhkiG9w0BAQUF\nAAOCAQEAXFPIh00VI55Sdfx+czbBb4rJz3c1xgN7pbV46K0nGI8S6ufAQPgLvZJ6\ng2T/mpo0FTuWCz1IE9PC28276vwv+xJZQwQyoUq4lhT6At84NWN+ZdLEe+aBAq+Y\nxUcIWzcKv8WdnlS5DRQxnw6pQCBdisnaFoEIzngQV8oYeIemW4Hcmb//yeykbZKJ\n0GTtK5Pud+kCkYmMHpmhH21q+3aRIcdzOYIoXhdzmIKG0Och97HthqpvRfOeWQ/A\nPDbxqQ2R/3D0gt9jWPCG7c0lB8Ynl24jLBB0RhY6mBrYpFbtXBQSEciUDRJVB2zL\nV8nJiMdhj+Q+ZmtSwhNRvi2qvWAUJQ==\n-----END CERTIFICATE-----\n"
|
||||||
|
},
|
||||||
|
"authCredentialsLink": "/core/auth/credentials/13c9cbade08950755898c4b89c4a0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
def handler(context, inputs):
|
||||||
|
|
||||||
|
ipam = IPAM(context, inputs)
|
||||||
|
IPAM.do_allocate_ip = do_allocate_ip
|
||||||
|
|
||||||
|
return ipam.allocate_ip()
|
||||||
|
|
||||||
|
def do_allocate_ip(self, auth_credentials, cert):
|
||||||
|
# Your implemention goes here
|
||||||
|
|
||||||
|
username = auth_credentials["privateKeyId"]
|
||||||
|
password = auth_credentials["privateKey"]
|
||||||
|
allocation_result = []
|
||||||
|
try:
|
||||||
|
resource = self.inputs["resourceInfo"]
|
||||||
|
for allocation in self.inputs["ipAllocations"]:
|
||||||
|
allocation_result.append(allocate(resource, allocation, self.context, self.inputs["endpoint"]))
|
||||||
|
except Exception as e:
|
||||||
|
try:
|
||||||
|
rollback(allocation_result)
|
||||||
|
except Exception as rollback_e:
|
||||||
|
logging.error(f"Error during rollback of allocation result {str(allocation_result)}")
|
||||||
|
logging.error(rollback_e)
|
||||||
|
raise e
|
||||||
|
|
||||||
|
assert len(allocation_result) > 0
|
||||||
|
return {
|
||||||
|
"ipAllocations": allocation_result
|
||||||
|
}
|
||||||
|
|
||||||
|
def allocate(resource, allocation, context, endpoint):
|
||||||
|
|
||||||
|
last_error = None
|
||||||
|
for range_id in allocation["ipRangeIds"]:
|
||||||
|
|
||||||
|
logging.info(f"Allocating from range {range_id}")
|
||||||
|
try:
|
||||||
|
return allocate_in_range(range_id, resource, allocation, context, endpoint)
|
||||||
|
except Exception as e:
|
||||||
|
last_error = e
|
||||||
|
logging.error(f"Failed to allocate from range {range_id}: {str(e)}")
|
||||||
|
|
||||||
|
logging.error("No more ranges. Raising last error")
|
||||||
|
raise last_error
|
||||||
|
|
||||||
|
|
||||||
|
def allocate_in_range(range_id, resource, allocation, context, endpoint):
|
||||||
|
|
||||||
|
## Plug your implementation here to allocate an ip address
|
||||||
|
## ...
|
||||||
|
## Allocation successful
|
||||||
|
|
||||||
|
result = {
|
||||||
|
"ipAllocationId": allocation["id"],
|
||||||
|
"ipRangeId": range_id,
|
||||||
|
"ipVersion": "IPv4"
|
||||||
|
}
|
||||||
|
|
||||||
|
result["ipAddresses"] = ["10.23.117.5"]
|
||||||
|
result["properties"] = {"customPropertyKey1": "customPropertyValue1"}
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
## Rollback any previously allocated addresses in case this allocation request contains multiple ones and failed in the middle
|
||||||
|
def rollback(allocation_result):
|
||||||
|
for allocation in reversed(allocation_result):
|
||||||
|
logging.info(f"Rolling back allocation {str(allocation)}")
|
||||||
|
ipAddresses = allocation.get("ipAddresses", None)
|
||||||
|
|
||||||
|
## release the address
|
||||||
|
|
||||||
|
return
|
0
src/main/python/allocate_ip_range/__init__.py
Normal file
0
src/main/python/allocate_ip_range/__init__.py
Normal file
1
src/main/python/allocate_ip_range/requirements.txt
Normal file
1
src/main/python/allocate_ip_range/requirements.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
requests==2.21.0
|
139
src/main/python/allocate_ip_range/source.py
Normal file
139
src/main/python/allocate_ip_range/source.py
Normal file
|
@ -0,0 +1,139 @@
|
||||||
|
"""
|
||||||
|
Copyright (c) 2020 VMware, Inc.
|
||||||
|
|
||||||
|
This product is licensed to you under the Apache License, Version 2.0 (the "License").
|
||||||
|
You may not use this product except in compliance with the License.
|
||||||
|
|
||||||
|
This product may include a number of subcomponents with separate copyright notices
|
||||||
|
and license terms. Your use of these subcomponents is subject to the terms and
|
||||||
|
conditions of the subcomponent's license, as noted in the LICENSE file.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import requests
|
||||||
|
from vra_ipam_utils.ipam import IPAM
|
||||||
|
import logging
|
||||||
|
|
||||||
|
"""
|
||||||
|
Example payload
|
||||||
|
|
||||||
|
"inputs": {
|
||||||
|
"resourceInfo": {
|
||||||
|
"id": "/resources/sub-networks/255ac10c-0198-4a92-9414-b8e0c23c0204",
|
||||||
|
"name": "net1-mcm223-126361015194",
|
||||||
|
"type": "SUBNET",
|
||||||
|
"orgId": "e0d6ea3a-519a-4308-afba-c973a8903250",
|
||||||
|
"owner": "jason@csp.local",
|
||||||
|
"properties": {
|
||||||
|
"networkType": "PRIVATE",
|
||||||
|
"datacenterId": "Datacenter:datacenter-21",
|
||||||
|
"__networkCidr": "192.168.197.0/28",
|
||||||
|
"__deploymentLink": "/resources/deployments/f77fbe4d-9e78-4b1b-93b0-024d342d0872",
|
||||||
|
"__infrastructureUse": "true",
|
||||||
|
"__composition_context_id": "f77fbe4d-9e78-4b1b-93b0-024d342d0872",
|
||||||
|
"__isInfrastructureShareable": "true"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ipRangeAllocation": {
|
||||||
|
"name": "net1-mcm223-126361015194",
|
||||||
|
"ipBlockIds": [
|
||||||
|
"block1",
|
||||||
|
"block2"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"networkType": "PRIVATE",
|
||||||
|
"datacenterId": "Datacenter:datacenter-21",
|
||||||
|
"__networkCidr": "192.168.197.0/28",
|
||||||
|
"__deploymentLink": "/resources/deployments/f77fbe4d-9e78-4b1b-93b0-024d342d0872",
|
||||||
|
"__infrastructureUse": "true",
|
||||||
|
"__composition_context_id": "f77fbe4d-9e78-4b1b-93b0-024d342d0872",
|
||||||
|
"__isInfrastructureShareable": "true"
|
||||||
|
},
|
||||||
|
"subnetCidr": "192.168.197.0/28",
|
||||||
|
"addressSpaceId": "default"
|
||||||
|
},
|
||||||
|
"endpoint": {
|
||||||
|
"id": "f097759d8736675585c4c5d272cd",
|
||||||
|
"endpointProperties": {
|
||||||
|
"hostName": "sampleipam.sof-mbu.eng.vmware.com",
|
||||||
|
"projectId": "111bb2f0-02fd-4983-94d2-8ac11768150f",
|
||||||
|
"providerId": "d8a5e3f2-d839-4365-af5b-f48de588fdc1",
|
||||||
|
"certificate": "-----BEGIN CERTIFICATE-----\nMIID0jCCArqgAwIBAgIQQaJF55UCb58f9KgQLD/QgTANBgkqhkiG9w0BAQUFADCB\niTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExEjAQBgNVBAcTCVN1\nbm55dmFsZTERMA8GA1UEChMISW5mb2Jsb3gxFDASBgNVBAsTC0VuZ2luZWVyaW5n\nMSgwJgYDVQQDEx9pbmZvYmxveC5zb2YtbWJ1LmVuZy52bXdhcmUuY29tMB4XDTE5\nMDEyOTEzMDExMloXDTIwMDEyOTEzMDExMlowgYkxCzAJBgNVBAYTAlVTMRMwEQYD\nVQQIEwpDYWxpZm9ybmlhMRIwEAYDVQQHEwlTdW5ueXZhbGUxETAPBgNVBAoTCElu\nZm9ibG94MRQwEgYDVQQLEwtFbmdpbmVlcmluZzEoMCYGA1UEAxMfaW5mb2Jsb3gu\nc29mLW1idS5lbmcudm13YXJlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC\nAQoCggEBAMMLNTqbAri6rt/H8iC4UgRdN0qj+wk0R2blmD9h1BiZJTeQk1r9i2rz\nzUOZHvE8Bld8m8xJ+nysWHaoFFGTX8bOd/p20oJBGbCLqXtoLMMBGAlP7nzWGBXH\nBYUS7kMv/CG+PSX0uuB0pRbhwOFq8Y69m4HRnn2X0WJGuu+v0FmRK/1m/kCacHga\nMBKaIgbwN72rW1t/MK0ijogmLR1ASY4FlMn7OBHIEUzO+dWFBh+gPDjoBECTTH8W\n5AK9TnYdxwAtJRYWmnVqtLoT3bImtSfI4YLUtpr9r13Kv5FkYVbXov1KBrQPbYyp\n72uT2ZgDJT4YUuWyKpMppgw1VcG3MosCAwEAAaM0MDIwMAYDVR0RBCkwJ4cEChda\nCoIfaW5mb2Jsb3guc29mLW1idS5lbmcudm13YXJlLmNvbTANBgkqhkiG9w0BAQUF\nAAOCAQEAXFPIh00VI55Sdfx+czbBb4rJz3c1xgN7pbV46K0nGI8S6ufAQPgLvZJ6\ng2T/mpo0FTuWCz1IE9PC28276vwv+xJZQwQyoUq4lhT6At84NWN+ZdLEe+aBAq+Y\nxUcIWzcKv8WdnlS5DRQxnw6pQCBdisnaFoEIzngQV8oYeIemW4Hcmb//yeykbZKJ\n0GTtK5Pud+kCkYmMHpmhH21q+3aRIcdzOYIoXhdzmIKG0Och97HthqpvRfOeWQ/A\nPDbxqQ2R/3D0gt9jWPCG7c0lB8Ynl24jLBB0RhY6mBrYpFbtXBQSEciUDRJVB2zL\nV8nJiMdhj+Q+ZmtSwhNRvi2qvWAUJQ==\n-----END CERTIFICATE-----\n"
|
||||||
|
},
|
||||||
|
"authCredentialsLink": "/core/auth/credentials/13c9cbade08950755898c4b89c4a0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
def handler(context, inputs):
|
||||||
|
|
||||||
|
ipam = IPAM(context, inputs)
|
||||||
|
IPAM.do_allocate_ip_range = do_allocate_ip_range
|
||||||
|
|
||||||
|
return ipam.allocate_ip_range()
|
||||||
|
|
||||||
|
def do_allocate_ip_range(self, auth_credentials, cert):
|
||||||
|
# Your implemention goes here
|
||||||
|
|
||||||
|
username = auth_credentials["privateKeyId"]
|
||||||
|
password = auth_credentials["privateKey"]
|
||||||
|
|
||||||
|
resource = self.inputs["resourceInfo"]
|
||||||
|
allocation = self.inputs["ipRangeAllocation"]
|
||||||
|
ipRange = allocate(resource, allocation, self.context, self.inputs["endpoint"])
|
||||||
|
|
||||||
|
return {
|
||||||
|
"ipRange": ipRange
|
||||||
|
}
|
||||||
|
|
||||||
|
def allocate(resource, allocation, context, endpoint):
|
||||||
|
|
||||||
|
last_error = None
|
||||||
|
for ip_block_id in allocation["ipBlockIds"]:
|
||||||
|
|
||||||
|
logging.info(f"Allocating from ip block {ip_block_id}")
|
||||||
|
try:
|
||||||
|
return allocate_in_ip_block(ip_block_id, resource, allocation, context, endpoint)
|
||||||
|
except Exception as e:
|
||||||
|
last_error = e
|
||||||
|
logging.error(f"Failed to allocate from ip block {ip_block_id}: {str(e)}")
|
||||||
|
|
||||||
|
logging.error("No more ip blocks. Raising last error")
|
||||||
|
raise last_error
|
||||||
|
|
||||||
|
|
||||||
|
def allocate_in_ip_block(ip_block_id, resource, allocation, context, endpoint):
|
||||||
|
|
||||||
|
## Plug your implementation here to allocate an ip range
|
||||||
|
## ...
|
||||||
|
## Allocation successful
|
||||||
|
|
||||||
|
result = {
|
||||||
|
"id": "range-new",
|
||||||
|
|
||||||
|
"name": "sample range new",
|
||||||
|
|
||||||
|
"startIPAddress": "10.10.40.1",
|
||||||
|
|
||||||
|
"endIPAddress": "10.10.40.10",
|
||||||
|
|
||||||
|
"description": "sampleDescription",
|
||||||
|
|
||||||
|
"ipVersion": "IPv4",
|
||||||
|
|
||||||
|
"addressSpaceId": "default",
|
||||||
|
|
||||||
|
"subnetPrefixLength": "24",
|
||||||
|
|
||||||
|
"gatewayAddress": "10.10.13.1",
|
||||||
|
|
||||||
|
"domain": "test.local",
|
||||||
|
|
||||||
|
"tags": [{
|
||||||
|
"key": "Building",
|
||||||
|
"value": "VMware main facility"
|
||||||
|
}],
|
||||||
|
|
||||||
|
"properties": {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
0
src/main/python/commons/vra_ipam_utils/__init__.py
Normal file
0
src/main/python/commons/vra_ipam_utils/__init__.py
Normal file
7
src/main/python/commons/vra_ipam_utils/exceptions.py
Normal file
7
src/main/python/commons/vra_ipam_utils/exceptions.py
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
class InvalidCertificateException(Exception):
|
||||||
|
def __init__(self, message, host, port):
|
||||||
|
# Call the base class constructor with the parameters it needs
|
||||||
|
super().__init__(message)
|
||||||
|
|
||||||
|
self.host = host
|
||||||
|
self.port = port
|
344
src/main/python/commons/vra_ipam_utils/ipam.py
Normal file
344
src/main/python/commons/vra_ipam_utils/ipam.py
Normal file
|
@ -0,0 +1,344 @@
|
||||||
|
"""
|
||||||
|
Copyright (c) 2020 VMware, Inc.
|
||||||
|
|
||||||
|
This product is licensed to you under the Apache License, Version 2.0 (the "License").
|
||||||
|
You may not use this product except in compliance with the License.
|
||||||
|
|
||||||
|
This product may include a number of subcomponents with separate copyright notices
|
||||||
|
and license terms. Your use of these subcomponents is subject to the terms and
|
||||||
|
conditions of the subcomponent's license, as noted in the LICENSE file.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import json
|
||||||
|
import tempfile
|
||||||
|
import os
|
||||||
|
import logging
|
||||||
|
from vra_ipam_utils.exceptions import InvalidCertificateException
|
||||||
|
|
||||||
|
class IPAM(object):
|
||||||
|
""" IPAM holds util methods for interacting with vRA's IPAM service.
|
||||||
|
|
||||||
|
Defines methods for the following ipam operations:
|
||||||
|
1] Validate endpoint
|
||||||
|
2] Get IP Ranges
|
||||||
|
3] Allocate IP
|
||||||
|
4] Deallocate IP
|
||||||
|
5] Update record
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, context, inputs):
|
||||||
|
|
||||||
|
self.context = context
|
||||||
|
self.inputs = inputs
|
||||||
|
|
||||||
|
# Setup the logging globally
|
||||||
|
self._setup_logger()
|
||||||
|
|
||||||
|
def validate_endpoint(self):
|
||||||
|
|
||||||
|
cert = None
|
||||||
|
try:
|
||||||
|
auth_credentials = self._get_auth_credentials()
|
||||||
|
cert = self._get_cert()
|
||||||
|
|
||||||
|
return self.do_validate_endpoint(auth_credentials, cert)
|
||||||
|
except InvalidCertificateException as e:
|
||||||
|
return {
|
||||||
|
"certificateInfo": {
|
||||||
|
"certificate": self._fetch_server_certificate(e.host, e.port)
|
||||||
|
},
|
||||||
|
"error": self._build_error_response("3002", str(e))["error"] ## Return special status code "3002" on invalid certificate
|
||||||
|
}
|
||||||
|
finally:
|
||||||
|
if cert is not None and type(cert) is str:
|
||||||
|
os.unlink(cert)
|
||||||
|
|
||||||
|
|
||||||
|
def get_ip_ranges(self):
|
||||||
|
|
||||||
|
cert = None
|
||||||
|
try:
|
||||||
|
auth_credentials = self._get_auth_credentials()
|
||||||
|
cert = self._get_cert()
|
||||||
|
|
||||||
|
result = self.do_get_ip_ranges(auth_credentials, cert)
|
||||||
|
|
||||||
|
# Validation of returned result
|
||||||
|
err_msg = "{} is mandatory part of the response schema and must be present in the response"
|
||||||
|
assert result.get("ipRanges") is not None, err_msg.format("ipRanges")
|
||||||
|
assert isinstance(result["ipRanges"], list), "ipRanges must be a list type"
|
||||||
|
for i in range(len(result["ipRanges"])):
|
||||||
|
assert result["ipRanges"][i].get("id") is not None, err_msg.format(f"ipRanges[{i}]['id']")
|
||||||
|
assert result["ipRanges"][i].get("name") is not None, err_msg.format(f"ipRanges[{i}]['name']")
|
||||||
|
assert result["ipRanges"][i].get("startIPAddress") is not None, err_msg.format(f"ipRanges[{i}]['startIPAddress']")
|
||||||
|
assert result["ipRanges"][i].get("endIPAddress") is not None, err_msg.format(f"ipRanges[{i}]['endIPAddress']")
|
||||||
|
assert result["ipRanges"][i].get("ipVersion") is not None, err_msg.format(f"ipRanges[{i}]['ipVersion']")
|
||||||
|
assert result["ipRanges"][i].get("subnetPrefixLength") is not None, err_msg.format(f"ipRanges[{i}]['subnetPrefixLength']")
|
||||||
|
|
||||||
|
return result
|
||||||
|
finally:
|
||||||
|
if cert is not None and type(cert) is str:
|
||||||
|
os.unlink(cert)
|
||||||
|
|
||||||
|
|
||||||
|
def allocate_ip(self):
|
||||||
|
|
||||||
|
cert = None
|
||||||
|
try:
|
||||||
|
auth_credentials = self._get_auth_credentials()
|
||||||
|
cert = self._get_cert()
|
||||||
|
|
||||||
|
result = self.do_allocate_ip(auth_credentials, cert)
|
||||||
|
|
||||||
|
# Validation of returned result
|
||||||
|
err_msg = "{} is mandatory part of the response schema and must be present in the response"
|
||||||
|
assert result.get("ipAllocations") is not None, err_msg.format("ipAllocations")
|
||||||
|
assert isinstance(result["ipAllocations"], list), "ipAllocations must be a list type"
|
||||||
|
assert len(result["ipAllocations"]) == len(self.inputs["ipAllocations"]), "Size of ipAllocations in the inputs is different than the one in the outputs"
|
||||||
|
for i in range(len(result["ipAllocations"])):
|
||||||
|
assert result["ipAllocations"][i].get("ipAllocationId") is not None, err_msg.format(f"ipAllocations[{i}]['ipAllocationId']")
|
||||||
|
assert result["ipAllocations"][i].get("ipRangeId") is not None, err_msg.format(f"ipAllocations[{i}]['ipRangeId']")
|
||||||
|
assert result["ipAllocations"][i].get("ipVersion") is not None, err_msg.format(f"ipAllocations[{i}]['ipVersion']")
|
||||||
|
assert result["ipAllocations"][i].get("ipAddresses") is not None, err_msg.format(f"ipAllocations[{i}]['ipAddresses']")
|
||||||
|
assert isinstance(result["ipAllocations"][i]["ipAddresses"], list), f"ipAllocations[{i}]['ipAddresses'] must be a list type"
|
||||||
|
assert len(result["ipAllocations"][i]["ipAddresses"]) > 0, f"ipAllocations[{i}]['ipAddresses'] must not be empty"
|
||||||
|
|
||||||
|
for allocation in self.inputs["ipAllocations"]:
|
||||||
|
found = False
|
||||||
|
if allocation["id"] == result["ipAllocations"][i]["ipAllocationId"]:
|
||||||
|
found = True
|
||||||
|
break
|
||||||
|
|
||||||
|
assert found, f"Allocation result with id {result['ipAllocations'][i]['ipAllocationId']} not found"
|
||||||
|
|
||||||
|
return result
|
||||||
|
finally:
|
||||||
|
if cert is not None and type(cert) is str:
|
||||||
|
os.unlink(cert)
|
||||||
|
|
||||||
|
def deallocate_ip(self):
|
||||||
|
|
||||||
|
cert = None
|
||||||
|
try:
|
||||||
|
auth_credentials = self._get_auth_credentials()
|
||||||
|
cert = self._get_cert()
|
||||||
|
|
||||||
|
result = self.do_deallocate_ip(auth_credentials, cert)
|
||||||
|
|
||||||
|
# Validation of returned result
|
||||||
|
err_msg = "{} is mandatory part of the response schema and must be present in the response"
|
||||||
|
assert result.get("ipDeallocations") is not None, err_msg.format("ipDeallocations")
|
||||||
|
assert isinstance(result["ipDeallocations"], list), "ipDeallocations must be a list type"
|
||||||
|
assert len(result["ipDeallocations"]) == len(self.inputs["ipDeallocations"]), "Size of ipDeallocations in the inputs is different than the one in the outputs"
|
||||||
|
for i in range(len(result["ipDeallocations"])):
|
||||||
|
assert result["ipDeallocations"][i].get("ipDeallocationId") is not None, err_msg.format(f"ipDeallocations[{i}]['ipDeallocationId']")
|
||||||
|
|
||||||
|
for deallocation in self.inputs["ipDeallocations"]:
|
||||||
|
found = False
|
||||||
|
if deallocation["id"] == result["ipDeallocations"][i]["ipDeallocationId"]:
|
||||||
|
found = True
|
||||||
|
break
|
||||||
|
|
||||||
|
assert found, f"Deallocation result with id {result['ipDeallocations'][i]['ipDeallocationId']} not found"
|
||||||
|
|
||||||
|
return result
|
||||||
|
finally:
|
||||||
|
if cert is not None and type(cert) is str:
|
||||||
|
os.unlink(cert)
|
||||||
|
|
||||||
|
def update_record(self):
|
||||||
|
|
||||||
|
cert = None
|
||||||
|
try:
|
||||||
|
auth_credentials = self._get_auth_credentials();
|
||||||
|
cert = self._get_cert()
|
||||||
|
|
||||||
|
return self.do_update_record(auth_credentials, cert)
|
||||||
|
finally:
|
||||||
|
if cert is not None and type(cert) is str:
|
||||||
|
os.unlink(cert)
|
||||||
|
|
||||||
|
def get_ip_blocks(self):
|
||||||
|
|
||||||
|
cert = None
|
||||||
|
try:
|
||||||
|
auth_credentials = self._get_auth_credentials()
|
||||||
|
cert = self._get_cert()
|
||||||
|
|
||||||
|
result = self.do_get_ip_blocks(auth_credentials, cert)
|
||||||
|
|
||||||
|
# Validation of returned result
|
||||||
|
err_msg = "{} is mandatory part of the response schema and must be present in the response"
|
||||||
|
assert result.get("ipBlocks") is not None, err_msg.format("ipBlocks")
|
||||||
|
assert isinstance(result["ipBlocks"], list), "ipRanges must be a list type"
|
||||||
|
for i in range(len(result["ipBlocks"])):
|
||||||
|
assert result["ipBlocks"][i].get("id") is not None, err_msg.format(f"ipBlocks[{i}]['id']")
|
||||||
|
assert result["ipBlocks"][i].get("name") is not None, err_msg.format(f"ipBlocks[{i}]['name']")
|
||||||
|
assert result["ipBlocks"][i].get("ipBlockCIDR") is not None, err_msg.format(f"ipBlocks[{i}]['ipBlockCIDR']")
|
||||||
|
assert result["ipBlocks"][i].get("ipVersion") is not None, err_msg.format(f"ipBlocks[{i}]['ipVersion']")
|
||||||
|
|
||||||
|
return result
|
||||||
|
finally:
|
||||||
|
if cert is not None and type(cert) is str:
|
||||||
|
os.unlink(cert)
|
||||||
|
|
||||||
|
def allocate_ip_range(self):
|
||||||
|
|
||||||
|
cert = None
|
||||||
|
try:
|
||||||
|
auth_credentials = self._get_auth_credentials()
|
||||||
|
cert = self._get_cert()
|
||||||
|
|
||||||
|
result = self.do_allocate_ip_range(auth_credentials, cert)
|
||||||
|
|
||||||
|
# Validation of returned result
|
||||||
|
err_msg = "{} is mandatory part of the response schema and must be present in the response"
|
||||||
|
assert result.get("ipRange") is not None, err_msg.format("ipRange")
|
||||||
|
assert result["ipRange"].get("id") is not None, err_msg.format(f"ipRange['id']")
|
||||||
|
assert result["ipRange"].get("name") is not None, err_msg.format(f"ipRange['name']")
|
||||||
|
assert result["ipRange"].get("startIPAddress") is not None, err_msg.format(f"ipRange['startIPAddress']")
|
||||||
|
assert result["ipRange"].get("endIPAddress") is not None, err_msg.format(f"ipRange['endIPAddress']")
|
||||||
|
assert result["ipRange"].get("ipVersion") is not None, err_msg.format(f"ipRange['ipVersion']")
|
||||||
|
assert result["ipRange"].get("subnetPrefixLength") is not None, err_msg.format(f"ipRange['subnetPrefixLength']")
|
||||||
|
|
||||||
|
return result
|
||||||
|
finally:
|
||||||
|
if cert is not None and type(cert) is str:
|
||||||
|
os.unlink(cert)
|
||||||
|
|
||||||
|
def deallocate_ip_range(self):
|
||||||
|
|
||||||
|
cert = None
|
||||||
|
try:
|
||||||
|
auth_credentials = self._get_auth_credentials()
|
||||||
|
cert = self._get_cert()
|
||||||
|
|
||||||
|
return self.do_deallocate_ip_range(auth_credentials, cert)
|
||||||
|
finally:
|
||||||
|
if cert is not None and type(cert) is str:
|
||||||
|
os.unlink(cert)
|
||||||
|
|
||||||
|
def do_validate_endpoint(self, auth_credentials, cert):
|
||||||
|
raise Exception("Method do_validate_endpoint(self, auth_credentials, cert) not implemented")
|
||||||
|
|
||||||
|
def do_get_ip_ranges(self, auth_credentials, cert):
|
||||||
|
raise Exception("Method do_get_ip_ranges(self, auth_credentials, cert) not implemented")
|
||||||
|
|
||||||
|
def do_allocate_ip(self, auth_credentials, cert):
|
||||||
|
raise Exception("Method do_allocate_ip(self, auth_credentials, cert) not implemented")
|
||||||
|
|
||||||
|
def do_deallocate_ip(self, auth_credentials, cert):
|
||||||
|
raise Exception("Method do_deallocate_ip(self, auth_credentials, cert) not implemented")
|
||||||
|
|
||||||
|
def do_update_record(self, auth_credentials, cert):
|
||||||
|
raise Exception("Method do_update_record(self, auth_credentials, cert) not implemented")
|
||||||
|
|
||||||
|
def do_get_ip_blocks(self, auth_credentials, cert):
|
||||||
|
raise Exception("Method do_get_ip_blocks(self, auth_credentials, cert) not implemented")
|
||||||
|
|
||||||
|
def do_allocate_ip_range(self, auth_credentials, cert):
|
||||||
|
raise Exception("Method do_allocate_ip_range(self, auth_credentials, cert) not implemented")
|
||||||
|
|
||||||
|
def do_deallocate_ip_range(self, auth_credentials, cert):
|
||||||
|
raise Exception("Method do_deallocate_ip_range(self, auth_credentials, cert) not implemented")
|
||||||
|
|
||||||
|
|
||||||
|
def _get_cert(self):
|
||||||
|
inputs = self.inputs.get("endpoint", self.inputs)
|
||||||
|
certificate = inputs["endpointProperties"].get("certificate", None)
|
||||||
|
if certificate is not None:
|
||||||
|
cert = tempfile.NamedTemporaryFile(mode='w', delete=False)
|
||||||
|
cert.write(certificate)
|
||||||
|
cert.close()
|
||||||
|
return cert.name
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
|
""" Fetches the server certificate of the host.
|
||||||
|
Used in case the certificate is not automatically trusted
|
||||||
|
"""
|
||||||
|
def _fetch_server_certificate(self, hostname, port):
|
||||||
|
|
||||||
|
logging.info(f"Fetching certificate of {hostname}")
|
||||||
|
import ssl
|
||||||
|
import socket
|
||||||
|
from OpenSSL import SSL
|
||||||
|
from OpenSSL import crypto
|
||||||
|
import os
|
||||||
|
import idna
|
||||||
|
|
||||||
|
hostname_idna = idna.encode(hostname)
|
||||||
|
proxy = os.environ.get("http_proxy", None)
|
||||||
|
if proxy is not None:
|
||||||
|
from urllib.parse import urlparse
|
||||||
|
o = urlparse(proxy)
|
||||||
|
PROXY_ADDR = (o.hostname, o.port)
|
||||||
|
CONNECT = "CONNECT %s:%s HTTP/1.0\r\nConnection: close\r\n\r\n" % (hostname, port)
|
||||||
|
logging.info(f"HTTP Proxy is configured. Sending CONNECT command to {proxy}: {CONNECT}")
|
||||||
|
CONNECT = bytes(CONNECT, "utf-8")
|
||||||
|
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
sock.connect(PROXY_ADDR)
|
||||||
|
sock.send(CONNECT)
|
||||||
|
logging.info(sock.recv(4096))
|
||||||
|
else:
|
||||||
|
sock = socket.socket()
|
||||||
|
sock.connect((hostname, port))
|
||||||
|
|
||||||
|
ctx = SSL.Context(SSL.SSLv23_METHOD) # most compatible
|
||||||
|
ctx.check_hostname = False
|
||||||
|
ctx.verify_mode = SSL.VERIFY_NONE
|
||||||
|
|
||||||
|
sock_ssl = SSL.Connection(ctx, sock)
|
||||||
|
sock_ssl.set_connect_state()
|
||||||
|
sock_ssl.set_tlsext_host_name(hostname_idna)
|
||||||
|
sock_ssl.do_handshake()
|
||||||
|
certs = sock_ssl.get_peer_cert_chain()
|
||||||
|
sb = ""
|
||||||
|
for cert in certs:
|
||||||
|
cert = crypto.dump_certificate(crypto.FILETYPE_PEM, cert)
|
||||||
|
cert = cert.decode()
|
||||||
|
sb += cert
|
||||||
|
|
||||||
|
sock_ssl.shutdown()
|
||||||
|
sock_ssl.close()
|
||||||
|
sock.close()
|
||||||
|
|
||||||
|
return sb
|
||||||
|
|
||||||
|
def _build_error_response(self, error_code, error_message):
|
||||||
|
return {
|
||||||
|
"error": {
|
||||||
|
"errorCode": error_code,
|
||||||
|
"errorMessage": error_message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
""" Fetches the auth credentials from vRA """
|
||||||
|
def _get_auth_credentials(self):
|
||||||
|
|
||||||
|
if self._is_mock_request(): # Used for testing purposes within VMware
|
||||||
|
return {"privateKeyId": "admin", "privateKey":"VMware"}
|
||||||
|
|
||||||
|
logging.info("Querying for auth credentials")
|
||||||
|
inputs = self.inputs.get("endpoint", self.inputs)
|
||||||
|
auth_credentials_link = inputs["authCredentialsLink"]
|
||||||
|
auth_credentials_response = self.context.request(auth_credentials_link, 'GET', '') ## Integrators can use context.request() to call CAS/Prelude REST endpoints
|
||||||
|
if auth_credentials_response["status"] == 200:
|
||||||
|
logging.info("Credentials obtained successfully!")
|
||||||
|
return json.loads(auth_credentials_response["content"])
|
||||||
|
|
||||||
|
raise Exception('Failed to obtain auth credentials from {}: {}'.format(auth_credentials_link, str(auth_credentials_response)))
|
||||||
|
|
||||||
|
|
||||||
|
def _setup_logger(self):
|
||||||
|
logger = logging.getLogger()
|
||||||
|
if logger.handlers:
|
||||||
|
for handler in logger.handlers:
|
||||||
|
logger.removeHandler(handler)
|
||||||
|
|
||||||
|
logging.basicConfig(format="[%(asctime)s] [%(levelname)s] - %(message)s", level=logging.INFO)
|
||||||
|
logging.StreamHandler.emit = lambda self, record: print(logging.StreamHandler.format(self, record))
|
||||||
|
|
||||||
|
def _is_mock_request(self):
|
||||||
|
endpoint = self.inputs.get("endpoint", self.inputs)
|
||||||
|
return endpoint["endpointProperties"].get("isMockRequest", False)
|
0
src/main/python/deallocate_ip/__init__.py
Normal file
0
src/main/python/deallocate_ip/__init__.py
Normal file
1
src/main/python/deallocate_ip/requirements.txt
Normal file
1
src/main/python/deallocate_ip/requirements.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
requests==2.21.0
|
96
src/main/python/deallocate_ip/source.py
Normal file
96
src/main/python/deallocate_ip/source.py
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
"""
|
||||||
|
Copyright (c) 2020 VMware, Inc.
|
||||||
|
|
||||||
|
This product is licensed to you under the Apache License, Version 2.0 (the "License").
|
||||||
|
You may not use this product except in compliance with the License.
|
||||||
|
|
||||||
|
This product may include a number of subcomponents with separate copyright notices
|
||||||
|
and license terms. Your use of these subcomponents is subject to the terms and
|
||||||
|
conditions of the subcomponent's license, as noted in the LICENSE file.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import requests
|
||||||
|
from vra_ipam_utils.ipam import IPAM
|
||||||
|
import logging
|
||||||
|
|
||||||
|
"""
|
||||||
|
Example payload:
|
||||||
|
|
||||||
|
"inputs": {
|
||||||
|
"resourceInfo": {
|
||||||
|
"id": "11f912e71454a075574a728848458",
|
||||||
|
"name": "external-ipam-it-mcm-323412",
|
||||||
|
"description": "test",
|
||||||
|
"type": "VM",
|
||||||
|
"owner": "mdzhigarov@vmware.com",
|
||||||
|
"orgId": "ce811934-ea1a-4f53-b6ec-465e6ca7d126",
|
||||||
|
"properties": {
|
||||||
|
"osType": "WINDOWS",
|
||||||
|
"vcUuid": "ff257ed9-070b-45eb-b2e7-d63926d5bdd7",
|
||||||
|
"__moref": "VirtualMachine:vm-288560",
|
||||||
|
"memoryGB": "4",
|
||||||
|
"datacenter": "Datacenter:datacenter-2",
|
||||||
|
"provisionGB": "1",
|
||||||
|
"__dcSelfLink": "/resources/groups/b28c7b8de065f07558b1612fce028",
|
||||||
|
"softwareName": "Microsoft Windows XP Professional (32-bit)",
|
||||||
|
"__computeType": "VirtualMachine",
|
||||||
|
"__hasSnapshot": "false",
|
||||||
|
"__placementLink": "/resources/compute/9bdc98681fb8b27557252188607b8",
|
||||||
|
"__computeHostLink": "/resources/compute/9bdc98681fb8b27557252188607b8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ipDeallocations": [
|
||||||
|
{
|
||||||
|
"id": "111bb2f0-02fd-4983-94d2-8ac11768150f",
|
||||||
|
"ipRangeId": "network/ZG5zLm5ldHdvcmskMTAuMjMuMTE3LjAvMjQvMA:10.23.117.0/24/default",
|
||||||
|
"ipAddress": "10.23.117.5"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"endpoint": {
|
||||||
|
"id": "f097759d8736675585c4c5d272cd",
|
||||||
|
"endpointProperties": {
|
||||||
|
"hostName": "sampleipam.sof-mbu.eng.vmware.com",
|
||||||
|
"projectId": "111bb2f0-02fd-4983-94d2-8ac11768150f",
|
||||||
|
"providerId": "d8a5e3f2-d839-4365-af5b-f48de588fdc1",
|
||||||
|
"certificate": "-----BEGIN CERTIFICATE-----\nMIID0jCCArqgAwIBAgIQQaJF55UCb58f9KgQLD/QgTANBgkqhkiG9w0BAQUFADCB\niTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExEjAQBgNVBAcTCVN1\nbm55dmFsZTERMA8GA1UEChMISW5mb2Jsb3gxFDASBgNVBAsTC0VuZ2luZWVyaW5n\nMSgwJgYDVQQDEx9pbmZvYmxveC5zb2YtbWJ1LmVuZy52bXdhcmUuY29tMB4XDTE5\nMDEyOTEzMDExMloXDTIwMDEyOTEzMDExMlowgYkxCzAJBgNVBAYTAlVTMRMwEQYD\nVQQIEwpDYWxpZm9ybmlhMRIwEAYDVQQHEwlTdW5ueXZhbGUxETAPBgNVBAoTCElu\nZm9ibG94MRQwEgYDVQQLEwtFbmdpbmVlcmluZzEoMCYGA1UEAxMfaW5mb2Jsb3gu\nc29mLW1idS5lbmcudm13YXJlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC\nAQoCggEBAMMLNTqbAri6rt/H8iC4UgRdN0qj+wk0R2blmD9h1BiZJTeQk1r9i2rz\nzUOZHvE8Bld8m8xJ+nysWHaoFFGTX8bOd/p20oJBGbCLqXtoLMMBGAlP7nzWGBXH\nBYUS7kMv/CG+PSX0uuB0pRbhwOFq8Y69m4HRnn2X0WJGuu+v0FmRK/1m/kCacHga\nMBKaIgbwN72rW1t/MK0ijogmLR1ASY4FlMn7OBHIEUzO+dWFBh+gPDjoBECTTH8W\n5AK9TnYdxwAtJRYWmnVqtLoT3bImtSfI4YLUtpr9r13Kv5FkYVbXov1KBrQPbYyp\n72uT2ZgDJT4YUuWyKpMppgw1VcG3MosCAwEAAaM0MDIwMAYDVR0RBCkwJ4cEChda\nCoIfaW5mb2Jsb3guc29mLW1idS5lbmcudm13YXJlLmNvbTANBgkqhkiG9w0BAQUF\nAAOCAQEAXFPIh00VI55Sdfx+czbBb4rJz3c1xgN7pbV46K0nGI8S6ufAQPgLvZJ6\ng2T/mpo0FTuWCz1IE9PC28276vwv+xJZQwQyoUq4lhT6At84NWN+ZdLEe+aBAq+Y\nxUcIWzcKv8WdnlS5DRQxnw6pQCBdisnaFoEIzngQV8oYeIemW4Hcmb//yeykbZKJ\n0GTtK5Pud+kCkYmMHpmhH21q+3aRIcdzOYIoXhdzmIKG0Och97HthqpvRfOeWQ/A\nPDbxqQ2R/3D0gt9jWPCG7c0lB8Ynl24jLBB0RhY6mBrYpFbtXBQSEciUDRJVB2zL\nV8nJiMdhj+Q+ZmtSwhNRvi2qvWAUJQ==\n-----END CERTIFICATE-----\n"
|
||||||
|
},
|
||||||
|
"authCredentialsLink": "/core/auth/credentials/13c9cbade08950755898c4b89c4a0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
def handler(context, inputs):
|
||||||
|
|
||||||
|
ipam = IPAM(context, inputs)
|
||||||
|
IPAM.do_deallocate_ip = do_deallocate_ip
|
||||||
|
|
||||||
|
return ipam.deallocate_ip()
|
||||||
|
|
||||||
|
def do_deallocate_ip(self, auth_credentials, cert):
|
||||||
|
# Your implemention goes here
|
||||||
|
|
||||||
|
username = auth_credentials["privateKeyId"]
|
||||||
|
password = auth_credentials["privateKey"]
|
||||||
|
deallocation_result = []
|
||||||
|
for deallocation in self.inputs["ipDeallocations"]:
|
||||||
|
deallocation_result.append(deallocate(self.inputs["resourceInfo"], deallocation))
|
||||||
|
|
||||||
|
assert len(deallocation_result) > 0
|
||||||
|
return {
|
||||||
|
"ipDeallocations": deallocation_result
|
||||||
|
}
|
||||||
|
|
||||||
|
def deallocate(resource, deallocation):
|
||||||
|
ip_range_id = deallocation["ipRangeId"]
|
||||||
|
ip = deallocation["ipAddress"]
|
||||||
|
resource_id = resource["id"]
|
||||||
|
|
||||||
|
logging.info(f"Deallocating ip {ip} from range {ip_range_id}")
|
||||||
|
|
||||||
|
## Plug your implementation here to deallocate an already allocated ip address
|
||||||
|
## ...
|
||||||
|
## Deallocation successful
|
||||||
|
|
||||||
|
return {
|
||||||
|
"ipDeallocationId": deallocation["id"],
|
||||||
|
"message": "Success"
|
||||||
|
}
|
0
src/main/python/deallocate_ip_range/__init__.py
Normal file
0
src/main/python/deallocate_ip_range/__init__.py
Normal file
1
src/main/python/deallocate_ip_range/requirements.txt
Normal file
1
src/main/python/deallocate_ip_range/requirements.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
requests==2.21.0
|
74
src/main/python/deallocate_ip_range/source.py
Normal file
74
src/main/python/deallocate_ip_range/source.py
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
"""
|
||||||
|
Copyright (c) 2020 VMware, Inc.
|
||||||
|
|
||||||
|
This product is licensed to you under the Apache License, Version 2.0 (the "License").
|
||||||
|
You may not use this product except in compliance with the License.
|
||||||
|
|
||||||
|
This product may include a number of subcomponents with separate copyright notices
|
||||||
|
and license terms. Your use of these subcomponents is subject to the terms and
|
||||||
|
conditions of the subcomponent's license, as noted in the LICENSE file.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import requests
|
||||||
|
from vra_ipam_utils.ipam import IPAM
|
||||||
|
import logging
|
||||||
|
|
||||||
|
"""
|
||||||
|
Example payload:
|
||||||
|
|
||||||
|
"inputs": {
|
||||||
|
"resourceInfo": {
|
||||||
|
"id": "/resources/sub-networks/255ac10c-0198-4a92-9414-b8e0c23c0204",
|
||||||
|
"name": "net1-mcm223-126361015194",
|
||||||
|
"type": "SUBNET",
|
||||||
|
"owner": "mdzhigarov@vmware.com",
|
||||||
|
"orgId": "ce811934-ea1a-4f53-b6ec-465e6ca7d126",
|
||||||
|
},
|
||||||
|
"ipDeallocations": [
|
||||||
|
{
|
||||||
|
"id": "111bb2f0-02fd-4983-94d2-8ac11768150f",
|
||||||
|
"ipRangeId": "network/ZG5zLm5ldHdvcmskMTAuMjMuMTE3LjAvMjQvMA:10.23.117.0/24/default",
|
||||||
|
"ipAddress": "10.23.117.5"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"endpoint": {
|
||||||
|
"id": "f097759d8736675585c4c5d272cd",
|
||||||
|
"endpointProperties": {
|
||||||
|
"hostName": "sampleipam.sof-mbu.eng.vmware.com",
|
||||||
|
"projectId": "111bb2f0-02fd-4983-94d2-8ac11768150f",
|
||||||
|
"providerId": "d8a5e3f2-d839-4365-af5b-f48de588fdc1",
|
||||||
|
"certificate": "-----BEGIN CERTIFICATE-----\nMIID0jCCArqgAwIBAgIQQaJF55UCb58f9KgQLD/QgTANBgkqhkiG9w0BAQUFADCB\niTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExEjAQBgNVBAcTCVN1\nbm55dmFsZTERMA8GA1UEChMISW5mb2Jsb3gxFDASBgNVBAsTC0VuZ2luZWVyaW5n\nMSgwJgYDVQQDEx9pbmZvYmxveC5zb2YtbWJ1LmVuZy52bXdhcmUuY29tMB4XDTE5\nMDEyOTEzMDExMloXDTIwMDEyOTEzMDExMlowgYkxCzAJBgNVBAYTAlVTMRMwEQYD\nVQQIEwpDYWxpZm9ybmlhMRIwEAYDVQQHEwlTdW5ueXZhbGUxETAPBgNVBAoTCElu\nZm9ibG94MRQwEgYDVQQLEwtFbmdpbmVlcmluZzEoMCYGA1UEAxMfaW5mb2Jsb3gu\nc29mLW1idS5lbmcudm13YXJlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC\nAQoCggEBAMMLNTqbAri6rt/H8iC4UgRdN0qj+wk0R2blmD9h1BiZJTeQk1r9i2rz\nzUOZHvE8Bld8m8xJ+nysWHaoFFGTX8bOd/p20oJBGbCLqXtoLMMBGAlP7nzWGBXH\nBYUS7kMv/CG+PSX0uuB0pRbhwOFq8Y69m4HRnn2X0WJGuu+v0FmRK/1m/kCacHga\nMBKaIgbwN72rW1t/MK0ijogmLR1ASY4FlMn7OBHIEUzO+dWFBh+gPDjoBECTTH8W\n5AK9TnYdxwAtJRYWmnVqtLoT3bImtSfI4YLUtpr9r13Kv5FkYVbXov1KBrQPbYyp\n72uT2ZgDJT4YUuWyKpMppgw1VcG3MosCAwEAAaM0MDIwMAYDVR0RBCkwJ4cEChda\nCoIfaW5mb2Jsb3guc29mLW1idS5lbmcudm13YXJlLmNvbTANBgkqhkiG9w0BAQUF\nAAOCAQEAXFPIh00VI55Sdfx+czbBb4rJz3c1xgN7pbV46K0nGI8S6ufAQPgLvZJ6\ng2T/mpo0FTuWCz1IE9PC28276vwv+xJZQwQyoUq4lhT6At84NWN+ZdLEe+aBAq+Y\nxUcIWzcKv8WdnlS5DRQxnw6pQCBdisnaFoEIzngQV8oYeIemW4Hcmb//yeykbZKJ\n0GTtK5Pud+kCkYmMHpmhH21q+3aRIcdzOYIoXhdzmIKG0Och97HthqpvRfOeWQ/A\nPDbxqQ2R/3D0gt9jWPCG7c0lB8Ynl24jLBB0RhY6mBrYpFbtXBQSEciUDRJVB2zL\nV8nJiMdhj+Q+ZmtSwhNRvi2qvWAUJQ==\n-----END CERTIFICATE-----\n"
|
||||||
|
},
|
||||||
|
"authCredentialsLink": "/core/auth/credentials/13c9cbade08950755898c4b89c4a0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
def handler(context, inputs):
|
||||||
|
|
||||||
|
ipam = IPAM(context, inputs)
|
||||||
|
IPAM.do_deallocate_ip_range = do_deallocate_ip_range
|
||||||
|
|
||||||
|
return ipam.deallocate_ip_range()
|
||||||
|
|
||||||
|
def do_deallocate_ip_range(self, auth_credentials, cert):
|
||||||
|
# Your implemention goes here
|
||||||
|
|
||||||
|
username = auth_credentials["privateKeyId"]
|
||||||
|
password = auth_credentials["privateKey"]
|
||||||
|
deallocation_result = deallocate(self.inputs["resourceInfo"], self.inputs["ipRangeDeallocation"])
|
||||||
|
|
||||||
|
return {
|
||||||
|
"message": f"Successfully deallocated {str(deallocation_result)}"
|
||||||
|
}
|
||||||
|
|
||||||
|
def deallocate(resource, deallocation):
|
||||||
|
ip_range_id = deallocation["ipRangeId"]
|
||||||
|
resource_id = resource["id"]
|
||||||
|
|
||||||
|
logging.info(f"Deallocating ip range {ip_range_id}")
|
||||||
|
|
||||||
|
## Plug your implementation here to deallocate an already allocated ip address
|
||||||
|
## ...
|
||||||
|
## Deallocation successful
|
||||||
|
|
||||||
|
return "Deallocated!"
|
0
src/main/python/get_ip_blocks/__init__.py
Normal file
0
src/main/python/get_ip_blocks/__init__.py
Normal file
1
src/main/python/get_ip_blocks/requirements.txt
Normal file
1
src/main/python/get_ip_blocks/requirements.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
requests==2.21.0
|
130
src/main/python/get_ip_blocks/source.py
Normal file
130
src/main/python/get_ip_blocks/source.py
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
"""
|
||||||
|
Copyright (c) 2020 VMware, Inc.
|
||||||
|
|
||||||
|
This product is licensed to you under the Apache License, Version 2.0 (the "License").
|
||||||
|
You may not use this product except in compliance with the License.
|
||||||
|
|
||||||
|
This product may include a number of subcomponents with separate copyright notices
|
||||||
|
and license terms. Your use of these subcomponents is subject to the terms and
|
||||||
|
conditions of the subcomponent's license, as noted in the LICENSE file.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import requests
|
||||||
|
from vra_ipam_utils.ipam import IPAM
|
||||||
|
import logging
|
||||||
|
|
||||||
|
'''
|
||||||
|
Example payload:
|
||||||
|
|
||||||
|
"inputs": {
|
||||||
|
"endpoint": {
|
||||||
|
"id": "f097759d8736675585c4c5d272cd",
|
||||||
|
"authCredentialsLink": "/core/auth/credentials/13c9cbade08950755898c4b89c4a0",
|
||||||
|
"endpointProperties": {
|
||||||
|
"hostName": "sampleipam.sof-mbu.eng.vmware.com",
|
||||||
|
"certificate": "-----BEGIN CERTIFICATE-----\nMIID0jCCArqgAwIBAgIQQaJF55UCb58f9KgQLD/QgTANBgkqhkiG9w0BAQUFADCB\niTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExEjAQBgNVBAcTCVN1\nbm55dmFsZTERMA8GA1UEChMISW5mb2Jsb3gxFDASBgNVBAsTC0VuZ2luZWVyaW5n\nMSgwJgYDVQQDEx9pbmZvYmxveC5zb2YtbWJ1LmVuZy52bXdhcmUuY29tMB4XDTE5\nMDEyOTEzMDExMloXDTIwMDEyOTEzMDExMlowgYkxCzAJBgNVBAYTAlVTMRMwEQYD\nVQQIEwpDYWxpZm9ybmlhMRIwEAYDVQQHEwlTdW5ueXZhbGUxETAPBgNVBAoTCElu\nZm9ibG94MRQwEgYDVQQLEwtFbmdpbmVlcmluZzEoMCYGA1UEAxMfaW5mb2Jsb3gu\nc29mLW1idS5lbmcudm13YXJlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC\nAQoCggEBAMMLNTqbAri6rt/H8iC4UgRdN0qj+wk0R2blmD9h1BiZJTeQk1r9i2rz\nzUOZHvE8Bld8m8xJ+nysWHaoFFGTX8bOd/p20oJBGbCLqXtoLMMBGAlP7nzWGBXH\nBYUS7kMv/CG+PSX0uuB0pRbhwOFq8Y69m4HRnn2X0WJGuu+v0FmRK/1m/kCacHga\nMBKaIgbwN72rW1t/MK0ijogmLR1ASY4FlMn7OBHIEUzO+dWFBh+gPDjoBECTTH8W\n5AK9TnYdxwAtJRYWmnVqtLoT3bImtSfI4YLUtpr9r13Kv5FkYVbXov1KBrQPbYyp\n72uT2ZgDJT4YUuWyKpMppgw1VcG3MosCAwEAAaM0MDIwMAYDVR0RBCkwJ4cEChda\nCoIfaW5mb2Jsb3guc29mLW1idS5lbmcudm13YXJlLmNvbTANBgkqhkiG9w0BAQUF\nAAOCAQEAXFPIh00VI55Sdfx+czbBb4rJz3c1xgN7pbV46K0nGI8S6ufAQPgLvZJ6\ng2T/mpo0FTuWCz1IE9PC28276vwv+xJZQwQyoUq4lhT6At84NWN+ZdLEe+aBAq+Y\nxUcIWzcKv8WdnlS5DRQxnw6pQCBdisnaFoEIzngQV8oYeIemW4Hcmb//yeykbZKJ\n0GTtK5Pud+kCkYmMHpmhH21q+3aRIcdzOYIoXhdzmIKG0Och97HthqpvRfOeWQ/A\nPDbxqQ2R/3D0gt9jWPCG7c0lB8Ynl24jLBB0RhY6mBrYpFbtXBQSEciUDRJVB2zL\nV8nJiMdhj+Q+ZmtSwhNRvi2qvWAUJQ==\n-----END CERTIFICATE-----\n"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pagingAndSorting": {
|
||||||
|
"maxResults": 1000,
|
||||||
|
"pageToken": "87811419dec2112cda2aa29685685d650ac1f61f"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'''
|
||||||
|
def handler(context, inputs):
|
||||||
|
|
||||||
|
ipam = IPAM(context, inputs)
|
||||||
|
IPAM.do_get_ip_blocks = do_get_ip_blocks
|
||||||
|
|
||||||
|
return ipam.get_ip_blocks()
|
||||||
|
|
||||||
|
def do_get_ip_blocks(self, auth_credentials, cert):
|
||||||
|
# Your implemention goes here
|
||||||
|
username = auth_credentials["privateKeyId"]
|
||||||
|
password = auth_credentials["privateKey"]
|
||||||
|
|
||||||
|
## If many IP blocks are expected on the IPAM server, it is considered a best practice
|
||||||
|
## to return them page by page instead of all at once.
|
||||||
|
## The vRA IPAM Service will propagate a pageToken string with each consecutive request
|
||||||
|
## until all pages are exhausted
|
||||||
|
pageToken = self.inputs['pagingAndSorting'].get('pageToken', None) ## The first request that vRA sends is with 'None' pageToken
|
||||||
|
|
||||||
|
## Plug your implementation here to collect all the ip blocks from the external IPAM system
|
||||||
|
result_ip_blocks, next_page_token = collect_ip_blocks(pageToken)
|
||||||
|
|
||||||
|
result = {
|
||||||
|
"ipBlocks": result_ip_blocks
|
||||||
|
}
|
||||||
|
|
||||||
|
## Return the next page token so that vRA can process the first page and then fetch the second page or ip blocks with the next request
|
||||||
|
if next_page_token is not None:
|
||||||
|
result["nextPageToken"] = next_page_token
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
def collect_ip_blocks(pageToken):
|
||||||
|
logging.info("Collecting ip blocks")
|
||||||
|
|
||||||
|
ip_block1 = {
|
||||||
|
"id": "block1",
|
||||||
|
|
||||||
|
"name": "sample name 1",
|
||||||
|
|
||||||
|
"ipBlockCIDR": "10.10.0.0/16",
|
||||||
|
|
||||||
|
"description": "sampleDescription",
|
||||||
|
|
||||||
|
"ipVersion": "IPv4",
|
||||||
|
|
||||||
|
"addressSpaceId": "default",
|
||||||
|
|
||||||
|
"gatewayAddress": "10.10.13.1",
|
||||||
|
|
||||||
|
"domain": "test.local",
|
||||||
|
|
||||||
|
"tags": [{
|
||||||
|
"key": "Building",
|
||||||
|
"value": "VMware main facility"
|
||||||
|
}],
|
||||||
|
|
||||||
|
"properties": {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ip_block2 = {
|
||||||
|
"id": "block2",
|
||||||
|
|
||||||
|
"name": "sample name 2",
|
||||||
|
|
||||||
|
"ipBlockCIDR": "10.10.40.0/24",
|
||||||
|
|
||||||
|
"description": "sampleDescription",
|
||||||
|
|
||||||
|
"ipVersion": "IPv4",
|
||||||
|
|
||||||
|
"addressSpaceId": "default",
|
||||||
|
|
||||||
|
"dnsServerAddresses": ["10.10.17.3", "10.10.22.1"],
|
||||||
|
|
||||||
|
"dnsSearchDomains": ["com", "net", "test.local"],
|
||||||
|
|
||||||
|
"domain": "test.local",
|
||||||
|
|
||||||
|
"tags": [{
|
||||||
|
"key": "Building",
|
||||||
|
"value": "VMware main facility"
|
||||||
|
}],
|
||||||
|
|
||||||
|
"properties": {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = []
|
||||||
|
next_page_token = None
|
||||||
|
if pageToken is None:
|
||||||
|
result = [ip_block1]
|
||||||
|
next_page_token = "87811419dec2112cda2aa29685685d650ac1f61f"
|
||||||
|
else:
|
||||||
|
result = [ip_block2]
|
||||||
|
|
||||||
|
return result, next_page_token
|
0
src/main/python/get_ip_ranges/__init__.py
Normal file
0
src/main/python/get_ip_ranges/__init__.py
Normal file
2
src/main/python/get_ip_ranges/requirements.txt
Normal file
2
src/main/python/get_ip_ranges/requirements.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
requests==2.21.0
|
||||||
|
ipaddress
|
87
src/main/python/get_ip_ranges/source.py
Normal file
87
src/main/python/get_ip_ranges/source.py
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
"""
|
||||||
|
Copyright (c) 2020 VMware, Inc.
|
||||||
|
|
||||||
|
This product is licensed to you under the Apache License, Version 2.0 (the "License").
|
||||||
|
You may not use this product except in compliance with the License.
|
||||||
|
|
||||||
|
This product may include a number of subcomponents with separate copyright notices
|
||||||
|
and license terms. Your use of these subcomponents is subject to the terms and
|
||||||
|
conditions of the subcomponent's license, as noted in the LICENSE file.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import requests
|
||||||
|
from vra_ipam_utils.ipam import IPAM
|
||||||
|
import logging
|
||||||
|
import ipaddress
|
||||||
|
|
||||||
|
'''
|
||||||
|
Example payload:
|
||||||
|
|
||||||
|
"inputs": {
|
||||||
|
"endpoint": {
|
||||||
|
"id": "f097759d8736675585c4c5d272cd",
|
||||||
|
"authCredentialsLink": "/core/auth/credentials/13c9cbade08950755898c4b89c4a0",
|
||||||
|
"endpointProperties": {
|
||||||
|
"hostName": "sampleipam.sof-mbu.eng.vmware.com",
|
||||||
|
"certificate": "-----BEGIN CERTIFICATE-----\nMIID0jCCArqgAwIBAgIQQaJF55UCb58f9KgQLD/QgTANBgkqhkiG9w0BAQUFADCB\niTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExEjAQBgNVBAcTCVN1\nbm55dmFsZTERMA8GA1UEChMISW5mb2Jsb3gxFDASBgNVBAsTC0VuZ2luZWVyaW5n\nMSgwJgYDVQQDEx9pbmZvYmxveC5zb2YtbWJ1LmVuZy52bXdhcmUuY29tMB4XDTE5\nMDEyOTEzMDExMloXDTIwMDEyOTEzMDExMlowgYkxCzAJBgNVBAYTAlVTMRMwEQYD\nVQQIEwpDYWxpZm9ybmlhMRIwEAYDVQQHEwlTdW5ueXZhbGUxETAPBgNVBAoTCElu\nZm9ibG94MRQwEgYDVQQLEwtFbmdpbmVlcmluZzEoMCYGA1UEAxMfaW5mb2Jsb3gu\nc29mLW1idS5lbmcudm13YXJlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC\nAQoCggEBAMMLNTqbAri6rt/H8iC4UgRdN0qj+wk0R2blmD9h1BiZJTeQk1r9i2rz\nzUOZHvE8Bld8m8xJ+nysWHaoFFGTX8bOd/p20oJBGbCLqXtoLMMBGAlP7nzWGBXH\nBYUS7kMv/CG+PSX0uuB0pRbhwOFq8Y69m4HRnn2X0WJGuu+v0FmRK/1m/kCacHga\nMBKaIgbwN72rW1t/MK0ijogmLR1ASY4FlMn7OBHIEUzO+dWFBh+gPDjoBECTTH8W\n5AK9TnYdxwAtJRYWmnVqtLoT3bImtSfI4YLUtpr9r13Kv5FkYVbXov1KBrQPbYyp\n72uT2ZgDJT4YUuWyKpMppgw1VcG3MosCAwEAAaM0MDIwMAYDVR0RBCkwJ4cEChda\nCoIfaW5mb2Jsb3guc29mLW1idS5lbmcudm13YXJlLmNvbTANBgkqhkiG9w0BAQUF\nAAOCAQEAXFPIh00VI55Sdfx+czbBb4rJz3c1xgN7pbV46K0nGI8S6ufAQPgLvZJ6\ng2T/mpo0FTuWCz1IE9PC28276vwv+xJZQwQyoUq4lhT6At84NWN+ZdLEe+aBAq+Y\nxUcIWzcKv8WdnlS5DRQxnw6pQCBdisnaFoEIzngQV8oYeIemW4Hcmb//yeykbZKJ\n0GTtK5Pud+kCkYmMHpmhH21q+3aRIcdzOYIoXhdzmIKG0Och97HthqpvRfOeWQ/A\nPDbxqQ2R/3D0gt9jWPCG7c0lB8Ynl24jLBB0RhY6mBrYpFbtXBQSEciUDRJVB2zL\nV8nJiMdhj+Q+ZmtSwhNRvi2qvWAUJQ==\n-----END CERTIFICATE-----\n"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pagingAndSorting": {
|
||||||
|
"maxResults": 1000,
|
||||||
|
"pageToken": "789c55905d6e02310c84df7d91452a456481168ec04b55950344f9db55dadd384abc056e5f3b42adfa12299f279ec9ac7c5670e9b0045a4ad2430c93af7a465f3bc83d4f9e3aa8976e6681ce660c827770de2aa1a68c72dfc3cae74393999b2e4df302e72691373aa60199bd827398efac18810f87a952591c61817c849513999df0b6c11436d6d400effcfacc14f2099cd6768913c5a435a0fd0c8e20ab2dbcd147564a2228c93b60b99ae2d94efde6ac640a09d9331130c539367078c41c915067ac9122268dc350439bf3379e9bc01b32025e9bd111aa65c829e89e83f0135ba740572c5f525c73f95faa608e39e55e62c6fcbd37de9775b891212a758d59bceb7a0eb30d7c7f6cd35c1399984291053b30f29fc5feed6cedf7adfe21962ab17b8ebde5089b1fec0d97d7-e5c4e5a1d726f600c22ebfd9f186148a1449755fd79a69ceabfe2aa"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'''
|
||||||
|
def handler(context, inputs):
|
||||||
|
|
||||||
|
ipam = IPAM(context, inputs)
|
||||||
|
IPAM.do_get_ip_ranges = do_get_ip_ranges
|
||||||
|
|
||||||
|
return ipam.get_ip_ranges()
|
||||||
|
|
||||||
|
def auth_session(uri, auth, cert):
|
||||||
|
auth_uri = f'{uri}/user/'
|
||||||
|
req = requests.post(auth_uri, auth=auth, verify=cert)
|
||||||
|
if req.status_code != 200:
|
||||||
|
raise requests.exceptions.RequestException('Authentication Failure!')
|
||||||
|
print('Auth success.')
|
||||||
|
token = {"token": req.json()['data']['token']}
|
||||||
|
return token
|
||||||
|
|
||||||
|
def do_get_ip_ranges(self, auth_credentials, cert):
|
||||||
|
# Build variables
|
||||||
|
username = auth_credentials["privateKeyId"]
|
||||||
|
password = auth_credentials["privateKey"]
|
||||||
|
hostname = self.inputs["endpoint"]["endpointProperties"]["hostName"]
|
||||||
|
apiAppId = self.inputs["endpoint"]["endpointProperties"]["apiAppId"]
|
||||||
|
uri = f'https://{hostname}/api/{apiAppId}/'
|
||||||
|
auth = (username, password)
|
||||||
|
|
||||||
|
# Auth to API
|
||||||
|
token = auth_session(uri, auth, cert)
|
||||||
|
|
||||||
|
# Request list of subnets
|
||||||
|
subnet_uri = f'{uri}/subnets/'
|
||||||
|
ipRanges = []
|
||||||
|
req = requests.get(subnet_uri, headers=token, verify=cert)
|
||||||
|
subnets = req.json()['data']
|
||||||
|
for subnet in subnets:
|
||||||
|
ipRange = {}
|
||||||
|
ipRange['id'] = str(subnet['id'])
|
||||||
|
ipRange['name'] = f"{str(subnet['subnet'])}/{str(subnet['mask'])}"
|
||||||
|
ipRange['description'] = str(subnet['description'])
|
||||||
|
logging.info(f"Found subnet: {ipRange['name']} - {ipRange['description']}.")
|
||||||
|
network = ipaddress.ip_network(str(subnet['subnet']) + '/' + str(subnet['mask']))
|
||||||
|
ipRange['ipVersion'] = 'IPv' + str(network.version)
|
||||||
|
ipRange['startIpAddress'] = str(network[10])
|
||||||
|
ipRange['endIpAddress'] = str(network[-6])
|
||||||
|
ipRange['subnetPrefixLength'] = str(subnet['mask'])
|
||||||
|
logging.debug(ipRange)
|
||||||
|
ipRanges.append(ipRange)
|
||||||
|
|
||||||
|
# Return results to vRA
|
||||||
|
result = {
|
||||||
|
"ipRanges" : ipRanges
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
|
0
src/main/python/update_record/__init__.py
Normal file
0
src/main/python/update_record/__init__.py
Normal file
1
src/main/python/update_record/requirements.txt
Normal file
1
src/main/python/update_record/requirements.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
requests==2.21.0
|
92
src/main/python/update_record/source.py
Normal file
92
src/main/python/update_record/source.py
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
"""
|
||||||
|
Copyright (c) 2020 VMware, Inc.
|
||||||
|
|
||||||
|
This product is licensed to you under the Apache License, Version 2.0 (the "License").
|
||||||
|
You may not use this product except in compliance with the License.
|
||||||
|
|
||||||
|
This product may include a number of subcomponents with separate copyright notices
|
||||||
|
and license terms. Your use of these subcomponents is subject to the terms and
|
||||||
|
conditions of the subcomponent's license, as noted in the LICENSE file.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import requests
|
||||||
|
from vra_ipam_utils.ipam import IPAM
|
||||||
|
import logging
|
||||||
|
|
||||||
|
"""
|
||||||
|
Example payload:
|
||||||
|
|
||||||
|
"inputs": {
|
||||||
|
"resourceInfo": {
|
||||||
|
"id": "11f912e71454a075574a728848458",
|
||||||
|
"name": "external-ipam-it-mcm-323412",
|
||||||
|
"description": "test",
|
||||||
|
"type": "VM",
|
||||||
|
"owner": "mdzhigarov@vmware.com",
|
||||||
|
"orgId": "ce811934-ea1a-4f53-b6ec-465e6ca7d126",
|
||||||
|
"properties": {
|
||||||
|
"osType": "WINDOWS",
|
||||||
|
"vcUuid": "ff257ed9-070b-45eb-b2e7-d63926d5bdd7",
|
||||||
|
"__moref": "VirtualMachine:vm-288560",
|
||||||
|
"memoryGB": "4",
|
||||||
|
"datacenter": "Datacenter:datacenter-2",
|
||||||
|
"provisionGB": "1",
|
||||||
|
"__dcSelfLink": "/resources/groups/b28c7b8de065f07558b1612fce028",
|
||||||
|
"softwareName": "Microsoft Windows XP Professional (32-bit)",
|
||||||
|
"__computeType": "VirtualMachine",
|
||||||
|
"__hasSnapshot": "false",
|
||||||
|
"__placementLink": "/resources/compute/9bdc98681fb8b27557252188607b8",
|
||||||
|
"__computeHostLink": "/resources/compute/9bdc98681fb8b27557252188607b8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"addressInfos": [
|
||||||
|
{
|
||||||
|
"nicIndex": 0,
|
||||||
|
"address": "10.23.117.5",
|
||||||
|
"macAddress": "00:30:26:a7:23:26"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"endpoint": {
|
||||||
|
"id": "f097759d8736675585c4c5d272cd",
|
||||||
|
"endpointProperties": {
|
||||||
|
"hostName": "sampleipam.sof-mbu.eng.vmware.com",
|
||||||
|
"projectId": "111bb2f0-02fd-4983-94d2-8ac11768150f",
|
||||||
|
"providerId": "d8a5e3f2-d839-4365-af5b-f48de588fdc1",
|
||||||
|
"certificate": "-----BEGIN CERTIFICATE-----\nMIID0jCCArqgAwIBAgIQQaJF55UCb58f9KgQLD/QgTANBgkqhkiG9w0BAQUFADCB\niTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExEjAQBgNVBAcTCVN1\nbm55dmFsZTERMA8GA1UEChMISW5mb2Jsb3gxFDASBgNVBAsTC0VuZ2luZWVyaW5n\nMSgwJgYDVQQDEx9pbmZvYmxveC5zb2YtbWJ1LmVuZy52bXdhcmUuY29tMB4XDTE5\nMDEyOTEzMDExMloXDTIwMDEyOTEzMDExMlowgYkxCzAJBgNVBAYTAlVTMRMwEQYD\nVQQIEwpDYWxpZm9ybmlhMRIwEAYDVQQHEwlTdW5ueXZhbGUxETAPBgNVBAoTCElu\nZm9ibG94MRQwEgYDVQQLEwtFbmdpbmVlcmluZzEoMCYGA1UEAxMfaW5mb2Jsb3gu\nc29mLW1idS5lbmcudm13YXJlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC\nAQoCggEBAMMLNTqbAri6rt/H8iC4UgRdN0qj+wk0R2blmD9h1BiZJTeQk1r9i2rz\nzUOZHvE8Bld8m8xJ+nysWHaoFFGTX8bOd/p20oJBGbCLqXtoLMMBGAlP7nzWGBXH\nBYUS7kMv/CG+PSX0uuB0pRbhwOFq8Y69m4HRnn2X0WJGuu+v0FmRK/1m/kCacHga\nMBKaIgbwN72rW1t/MK0ijogmLR1ASY4FlMn7OBHIEUzO+dWFBh+gPDjoBECTTH8W\n5AK9TnYdxwAtJRYWmnVqtLoT3bImtSfI4YLUtpr9r13Kv5FkYVbXov1KBrQPbYyp\n72uT2ZgDJT4YUuWyKpMppgw1VcG3MosCAwEAAaM0MDIwMAYDVR0RBCkwJ4cEChda\nCoIfaW5mb2Jsb3guc29mLW1idS5lbmcudm13YXJlLmNvbTANBgkqhkiG9w0BAQUF\nAAOCAQEAXFPIh00VI55Sdfx+czbBb4rJz3c1xgN7pbV46K0nGI8S6ufAQPgLvZJ6\ng2T/mpo0FTuWCz1IE9PC28276vwv+xJZQwQyoUq4lhT6At84NWN+ZdLEe+aBAq+Y\nxUcIWzcKv8WdnlS5DRQxnw6pQCBdisnaFoEIzngQV8oYeIemW4Hcmb//yeykbZKJ\n0GTtK5Pud+kCkYmMHpmhH21q+3aRIcdzOYIoXhdzmIKG0Och97HthqpvRfOeWQ/A\nPDbxqQ2R/3D0gt9jWPCG7c0lB8Ynl24jLBB0RhY6mBrYpFbtXBQSEciUDRJVB2zL\nV8nJiMdhj+Q+ZmtSwhNRvi2qvWAUJQ==\n-----END CERTIFICATE-----\n"
|
||||||
|
},
|
||||||
|
"authCredentialsLink": "/core/auth/credentials/13c9cbade08950755898c4b89c4a0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
def handler(context, inputs):
|
||||||
|
|
||||||
|
ipam = IPAM(context, inputs)
|
||||||
|
IPAM.do_update_record = do_update_record
|
||||||
|
|
||||||
|
return ipam.update_record()
|
||||||
|
|
||||||
|
def do_update_record(self, auth_credentials, cert):
|
||||||
|
# Your implemention goes here
|
||||||
|
|
||||||
|
username = auth_credentials["privateKeyId"]
|
||||||
|
password = auth_credentials["privateKey"]
|
||||||
|
update_result = []
|
||||||
|
resource = self.inputs["resourceInfo"]
|
||||||
|
for update_record in self.inputs["addressInfos"]:
|
||||||
|
update_result.append(update(resource, self.inputs, update_record))
|
||||||
|
|
||||||
|
assert len(update_result) > 0
|
||||||
|
return {
|
||||||
|
"updateResults": update_result
|
||||||
|
}
|
||||||
|
|
||||||
|
def update(resource, inputs, update_record):
|
||||||
|
try:
|
||||||
|
## Plug your implementation here to update the MAC address of an already allocate ip record
|
||||||
|
## Search the record and update its MAC
|
||||||
|
mac = update_record["macAddress"]
|
||||||
|
|
||||||
|
return "Success"
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(f"Failed to update record {update_record}: {e}")
|
||||||
|
raise e
|
Binary file not shown.
0
src/main/python/validate_endpoint/__init__.py
Normal file
0
src/main/python/validate_endpoint/__init__.py
Normal file
Binary file not shown.
11
src/main/python/validate_endpoint/requirements.txt
Normal file
11
src/main/python/validate_endpoint/requirements.txt
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# User libs go here
|
||||||
|
#
|
||||||
|
requests==2.21.0
|
||||||
|
#
|
||||||
|
# ----------------- #
|
||||||
|
#
|
||||||
|
# The following libs are needed by vra_ipam_utils to fetch the server certificate and return it to vRA in case it is self signed or not automatically trusted
|
||||||
|
ndg-httpsclient
|
||||||
|
pyopenssl
|
||||||
|
pyasn1
|
||||||
|
idna
|
77
src/main/python/validate_endpoint/source.py
Normal file
77
src/main/python/validate_endpoint/source.py
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
"""
|
||||||
|
Copyright (c) 2020 VMware, Inc.
|
||||||
|
|
||||||
|
This product is licensed to you under the Apache License, Version 2.0 (the "License").
|
||||||
|
You may not use this product except in compliance with the License.
|
||||||
|
|
||||||
|
This product may include a number of subcomponents with separate copyright notices
|
||||||
|
and license terms. Your use of these subcomponents is subject to the terms and
|
||||||
|
conditions of the subcomponent's license, as noted in the LICENSE file.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import requests
|
||||||
|
from vra_ipam_utils.ipam import IPAM
|
||||||
|
from vra_ipam_utils.exceptions import InvalidCertificateException
|
||||||
|
import logging
|
||||||
|
|
||||||
|
|
||||||
|
'''
|
||||||
|
Example payload:
|
||||||
|
|
||||||
|
"inputs": {
|
||||||
|
"authCredentialsLink": "/core/auth/credentials/13c9cbade08950755898c4b89c4a0",
|
||||||
|
"endpointProperties": {
|
||||||
|
"hostName": "sampleipam.sof-mbu.eng.vmware.com"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'''
|
||||||
|
def handler(context, inputs):
|
||||||
|
|
||||||
|
ipam = IPAM(context, inputs)
|
||||||
|
IPAM.do_validate_endpoint = do_validate_endpoint
|
||||||
|
|
||||||
|
return ipam.validate_endpoint()
|
||||||
|
|
||||||
|
def auth_session(uri, auth, cert):
|
||||||
|
auth_uri = f'{uri}/user/'
|
||||||
|
req = requests.post(auth_uri, auth=auth, verify=cert)
|
||||||
|
## We don't need to handle errors or save the token here since we're just validating the endpoint
|
||||||
|
# if req.status_code != 200:
|
||||||
|
# raise requests.exceptions.RequestException('Authentication Failed!')
|
||||||
|
# logging.info('Authentication successful.')
|
||||||
|
# token = {"token": req.json()['data']['token']}
|
||||||
|
# return token
|
||||||
|
return req
|
||||||
|
|
||||||
|
def do_validate_endpoint(self, auth_credentials, cert):
|
||||||
|
# Build variables
|
||||||
|
username = auth_credentials["privateKeyId"]
|
||||||
|
password = auth_credentials["privateKey"]
|
||||||
|
hostname = self.inputs["endpointProperties"]["hostName"]
|
||||||
|
apiAppId = self.inputs["endpointProperties"]["apiAppId"]
|
||||||
|
uri = f'https://{hostname}/api/{apiAppId}/'
|
||||||
|
auth = (username, password)
|
||||||
|
|
||||||
|
# Test auth connection
|
||||||
|
try:
|
||||||
|
response = auth_session(uri, auth, cert)
|
||||||
|
|
||||||
|
if response.status_code == 200:
|
||||||
|
return {
|
||||||
|
"message": "Validated successfully",
|
||||||
|
"statusCode": "200"
|
||||||
|
}
|
||||||
|
elif response.status_code == 500 and response.json()['message'] == 'Invalid username or password':
|
||||||
|
logging.error(f"Invalid credentials error: {str(response.content)}")
|
||||||
|
raise Exception(f"Invalid credentials error: {str(response.content)}")
|
||||||
|
else:
|
||||||
|
raise Exception(f"Failed to connect: {str(response.content)}")
|
||||||
|
except Exception as e:
|
||||||
|
""" In case of SSL validation error, a InvalidCertificateException is raised.
|
||||||
|
So that the IPAM SDK can go ahead and fetch the server certificate
|
||||||
|
and display it to the user for manual acceptance.
|
||||||
|
"""
|
||||||
|
if "SSLCertVerificationError" in str(e) or "CERTIFICATE_VERIFY_FAILED" in str(e) or 'certificate verify failed' in str(e):
|
||||||
|
raise InvalidCertificateException("certificate verify failed", self.inputs["endpointProperties"]["hostName"], 443) from e
|
||||||
|
|
||||||
|
raise e
|
0
src/main/resources/CHANGELOG.md
Normal file
0
src/main/resources/CHANGELOG.md
Normal file
58
src/main/resources/bundle/allocate_ip.abx
Normal file
58
src/main/resources/bundle/allocate_ip.abx
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
---
|
||||||
|
exportVersion: "1"
|
||||||
|
exportId: "@provider.name@_AllocateIP"
|
||||||
|
name: "@provider.name@_AllocateIP"
|
||||||
|
runtime: "python"
|
||||||
|
entrypoint: "source.handler"
|
||||||
|
inputs:
|
||||||
|
resourceInfo:
|
||||||
|
id: "11f912e71454a075574a728848458"
|
||||||
|
name: "external-ipam-it-mcm-323412"
|
||||||
|
description: "test"
|
||||||
|
type: "VM"
|
||||||
|
owner: "mdzhigarov@vmware.com"
|
||||||
|
orgId: "ce811934-ea1a-4f53-b6ec-465e6ca7d126"
|
||||||
|
properties:
|
||||||
|
osType: "WINDOWS"
|
||||||
|
vcUuid: "ff257ed9-070b-45eb-b2e7-d63926d5bdd7"
|
||||||
|
__moref: "VirtualMachine:vm-288560"
|
||||||
|
memoryGB: "4"
|
||||||
|
datacenter: "Datacenter:datacenter-2"
|
||||||
|
provisionGB: "1"
|
||||||
|
__dcSelfLink: "/resources/groups/b28c7b8de065f07558b1612fce028"
|
||||||
|
softwareName: "Microsoft Windows XP Professional (32-bit)"
|
||||||
|
__computeType: "VirtualMachine"
|
||||||
|
__hasSnapshot: "false"
|
||||||
|
__placementLink: "/resources/compute/9bdc98681fb8b27557252188607b8"
|
||||||
|
__computeHostLink: "/resources/compute/9bdc98681fb8b27557252188607b8"
|
||||||
|
|
||||||
|
ipAllocations:
|
||||||
|
- id: "111bb2f0-02fd-4983-94d2-8ac11768150f"
|
||||||
|
ipRangeIds: ["network/ZG5zLm5ldHdvcmskMTAuMjMuMTE3LjAvMjQvMA:10.23.117.0/24/default"]
|
||||||
|
nicIndex: "0"
|
||||||
|
isPrimary: "true"
|
||||||
|
size: "1"
|
||||||
|
properties:
|
||||||
|
__moref: "DistributedVirtualPortgroup:dvportgroup-307087"
|
||||||
|
__dvsUuid: "0c 8c 0b 50 46 b6 1c f2-e8 63 f4 24 24 d7 24 6c"
|
||||||
|
__dcSelfLink: "/resources/groups/abe46b8cfa663a7558b28a6ffe088"
|
||||||
|
__computeType: "DistributedVirtualPortgroup"
|
||||||
|
__portgroupKey: "dvportgroup-307087"
|
||||||
|
endpoint:
|
||||||
|
id: "f097759d8736675585c4c5d272cd"
|
||||||
|
endpointProperties:
|
||||||
|
hostName: "sampleipam.sof-mbu.eng.vmware.com"
|
||||||
|
projectId: "111bb2f0-02fd-4983-94d2-8ac11768150f"
|
||||||
|
providerId: "d8a5e3f2-d839-4365-af5b-f48de588fdc1"
|
||||||
|
certificate: "-----BEGIN CERTIFICATE-----\nMIID0jCCArqgAwIBAgIQQaJF55UCb58f9KgQLD/QgTANBgkqhkiG9w0BAQUFADCB\niTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExEjAQBgNVBAcTCVN1\nbm55dmFsZTERMA8GA1UEChMISW5mb2Jsb3gxFDASBgNVBAsTC0VuZ2luZWVyaW5n\nMSgwJgYDVQQDEx9pbmZvYmxveC5zb2YtbWJ1LmVuZy52bXdhcmUuY29tMB4XDTE5\nMDEyOTEzMDExMloXDTIwMDEyOTEzMDExMlowgYkxCzAJBgNVBAYTAlVTMRMwEQYD\nVQQIEwpDYWxpZm9ybmlhMRIwEAYDVQQHEwlTdW5ueXZhbGUxETAPBgNVBAoTCElu\nZm9ibG94MRQwEgYDVQQLEwtFbmdpbmVlcmluZzEoMCYGA1UEAxMfaW5mb2Jsb3gu\nc29mLW1idS5lbmcudm13YXJlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC\nAQoCggEBAMMLNTqbAri6rt/H8iC4UgRdN0qj+wk0R2blmD9h1BiZJTeQk1r9i2rz\nzUOZHvE8Bld8m8xJ+nysWHaoFFGTX8bOd/p20oJBGbCLqXtoLMMBGAlP7nzWGBXH\nBYUS7kMv/CG+PSX0uuB0pRbhwOFq8Y69m4HRnn2X0WJGuu+v0FmRK/1m/kCacHga\nMBKaIgbwN72rW1t/MK0ijogmLR1ASY4FlMn7OBHIEUzO+dWFBh+gPDjoBECTTH8W\n5AK9TnYdxwAtJRYWmnVqtLoT3bImtSfI4YLUtpr9r13Kv5FkYVbXov1KBrQPbYyp\n72uT2ZgDJT4YUuWyKpMppgw1VcG3MosCAwEAAaM0MDIwMAYDVR0RBCkwJ4cEChda\nCoIfaW5mb2Jsb3guc29mLW1idS5lbmcudm13YXJlLmNvbTANBgkqhkiG9w0BAQUF\nAAOCAQEAXFPIh00VI55Sdfx+czbBb4rJz3c1xgN7pbV46K0nGI8S6ufAQPgLvZJ6\ng2T/mpo0FTuWCz1IE9PC28276vwv+xJZQwQyoUq4lhT6At84NWN+ZdLEe+aBAq+Y\nxUcIWzcKv8WdnlS5DRQxnw6pQCBdisnaFoEIzngQV8oYeIemW4Hcmb//yeykbZKJ\n0GTtK5Pud+kCkYmMHpmhH21q+3aRIcdzOYIoXhdzmIKG0Och97HthqpvRfOeWQ/A\nPDbxqQ2R/3D0gt9jWPCG7c0lB8Ynl24jLBB0RhY6mBrYpFbtXBQSEciUDRJVB2zL\nV8nJiMdhj+Q+ZmtSwhNRvi2qvWAUJQ==\n-----END CERTIFICATE-----\n"
|
||||||
|
authCredentialsLink: "/core/auth/credentials/13c9cbade08950755898c4b89c4a0"
|
||||||
|
timeoutSeconds: 600
|
||||||
|
deploymentTimeoutSeconds: 600
|
||||||
|
actionType: "SCRIPT"
|
||||||
|
configuration:
|
||||||
|
const-providers:
|
||||||
|
- ""
|
||||||
|
const_azure-system_managed_identity: false
|
||||||
|
actionTemplateName: "Custom script"
|
||||||
|
actionTemplateNamespace: "com.vmware.automation.abx"
|
||||||
|
memoryInMB: 3000
|
53
src/main/resources/bundle/allocate_ip_range.abx
Normal file
53
src/main/resources/bundle/allocate_ip_range.abx
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
---
|
||||||
|
exportVersion: "1"
|
||||||
|
exportId: "@provider.name@_AllocateIPRange"
|
||||||
|
name: "@provider.name@_AllocateIPRange"
|
||||||
|
runtime: "python"
|
||||||
|
entrypoint: "source.handler"
|
||||||
|
inputs:
|
||||||
|
resourceInfo:
|
||||||
|
id: "/resources/sub-networks/255ac10c-0198-4a92-9414-b8e0c23c0204"
|
||||||
|
name: net1-mcm223-126361015194
|
||||||
|
type: SUBNET
|
||||||
|
owner: "mdzhigarov@vmware.com"
|
||||||
|
orgId: "ce811934-ea1a-4f53-b6ec-465e6ca7d126"
|
||||||
|
properties:
|
||||||
|
networkType: PRIVATE
|
||||||
|
datacenterId: Datacenter:datacenter-21
|
||||||
|
__networkCidr: 192.168.197.0/28
|
||||||
|
__deploymentLink: "/resources/deployments/f77fbe4d-9e78-4b1b-93b0-024d342d0872"
|
||||||
|
__infrastructureUse: 'true'
|
||||||
|
__composition_context_id: f77fbe4d-9e78-4b1b-93b0-024d342d0872
|
||||||
|
__isInfrastructureShareable: 'true'
|
||||||
|
|
||||||
|
ipRangeAllocation:
|
||||||
|
name: net1-mcm223-126361015194
|
||||||
|
ipBlockIds: ["block1", "block2"]
|
||||||
|
properties:
|
||||||
|
networkType: PRIVATE
|
||||||
|
datacenterId: Datacenter:datacenter-21
|
||||||
|
__networkCidr: 192.168.197.0/28
|
||||||
|
__deploymentLink: "/resources/deployments/f77fbe4d-9e78-4b1b-93b0-024d342d0872"
|
||||||
|
__infrastructureUse: 'true'
|
||||||
|
__composition_context_id: f77fbe4d-9e78-4b1b-93b0-024d342d0872
|
||||||
|
__isInfrastructureShareable: 'true'
|
||||||
|
subnetCidr: 192.168.197.0/28
|
||||||
|
addressSpaceId: default
|
||||||
|
endpoint:
|
||||||
|
id: "f097759d8736675585c4c5d272cd"
|
||||||
|
endpointProperties:
|
||||||
|
hostName: "sampleipam.sof-mbu.eng.vmware.com"
|
||||||
|
projectId: "111bb2f0-02fd-4983-94d2-8ac11768150f"
|
||||||
|
providerId: "d8a5e3f2-d839-4365-af5b-f48de588fdc1"
|
||||||
|
certificate: "-----BEGIN CERTIFICATE-----\nMIID0jCCArqgAwIBAgIQQaJF55UCb58f9KgQLD/QgTANBgkqhkiG9w0BAQUFADCB\niTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExEjAQBgNVBAcTCVN1\nbm55dmFsZTERMA8GA1UEChMISW5mb2Jsb3gxFDASBgNVBAsTC0VuZ2luZWVyaW5n\nMSgwJgYDVQQDEx9pbmZvYmxveC5zb2YtbWJ1LmVuZy52bXdhcmUuY29tMB4XDTE5\nMDEyOTEzMDExMloXDTIwMDEyOTEzMDExMlowgYkxCzAJBgNVBAYTAlVTMRMwEQYD\nVQQIEwpDYWxpZm9ybmlhMRIwEAYDVQQHEwlTdW5ueXZhbGUxETAPBgNVBAoTCElu\nZm9ibG94MRQwEgYDVQQLEwtFbmdpbmVlcmluZzEoMCYGA1UEAxMfaW5mb2Jsb3gu\nc29mLW1idS5lbmcudm13YXJlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC\nAQoCggEBAMMLNTqbAri6rt/H8iC4UgRdN0qj+wk0R2blmD9h1BiZJTeQk1r9i2rz\nzUOZHvE8Bld8m8xJ+nysWHaoFFGTX8bOd/p20oJBGbCLqXtoLMMBGAlP7nzWGBXH\nBYUS7kMv/CG+PSX0uuB0pRbhwOFq8Y69m4HRnn2X0WJGuu+v0FmRK/1m/kCacHga\nMBKaIgbwN72rW1t/MK0ijogmLR1ASY4FlMn7OBHIEUzO+dWFBh+gPDjoBECTTH8W\n5AK9TnYdxwAtJRYWmnVqtLoT3bImtSfI4YLUtpr9r13Kv5FkYVbXov1KBrQPbYyp\n72uT2ZgDJT4YUuWyKpMppgw1VcG3MosCAwEAAaM0MDIwMAYDVR0RBCkwJ4cEChda\nCoIfaW5mb2Jsb3guc29mLW1idS5lbmcudm13YXJlLmNvbTANBgkqhkiG9w0BAQUF\nAAOCAQEAXFPIh00VI55Sdfx+czbBb4rJz3c1xgN7pbV46K0nGI8S6ufAQPgLvZJ6\ng2T/mpo0FTuWCz1IE9PC28276vwv+xJZQwQyoUq4lhT6At84NWN+ZdLEe+aBAq+Y\nxUcIWzcKv8WdnlS5DRQxnw6pQCBdisnaFoEIzngQV8oYeIemW4Hcmb//yeykbZKJ\n0GTtK5Pud+kCkYmMHpmhH21q+3aRIcdzOYIoXhdzmIKG0Och97HthqpvRfOeWQ/A\nPDbxqQ2R/3D0gt9jWPCG7c0lB8Ynl24jLBB0RhY6mBrYpFbtXBQSEciUDRJVB2zL\nV8nJiMdhj+Q+ZmtSwhNRvi2qvWAUJQ==\n-----END CERTIFICATE-----\n"
|
||||||
|
authCredentialsLink: "/core/auth/credentials/13c9cbade08950755898c4b89c4a0"
|
||||||
|
timeoutSeconds: 600
|
||||||
|
deploymentTimeoutSeconds: 600
|
||||||
|
actionType: "SCRIPT"
|
||||||
|
configuration:
|
||||||
|
const-providers:
|
||||||
|
- ""
|
||||||
|
const_azure-system_managed_identity: false
|
||||||
|
actionTemplateName: "Custom script"
|
||||||
|
actionTemplateNamespace: "com.vmware.automation.abx"
|
||||||
|
memoryInMB: 3000
|
50
src/main/resources/bundle/deallocate_ip.abx
Normal file
50
src/main/resources/bundle/deallocate_ip.abx
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
---
|
||||||
|
exportVersion: "1"
|
||||||
|
exportId: "@provider.name@_DeallocateIP"
|
||||||
|
name: "@provider.name@_DeallocateIP"
|
||||||
|
runtime: "python"
|
||||||
|
entrypoint: "source.handler"
|
||||||
|
inputs:
|
||||||
|
resourceInfo:
|
||||||
|
id: "11f912e71454a075574a728848458"
|
||||||
|
name: "external-ipam-it-mcm-323412"
|
||||||
|
description: "test"
|
||||||
|
type: "VM"
|
||||||
|
owner: "mdzhigarov@vmware.com"
|
||||||
|
orgId: "ce811934-ea1a-4f53-b6ec-465e6ca7d126"
|
||||||
|
properties:
|
||||||
|
osType: "WINDOWS"
|
||||||
|
vcUuid: "ff257ed9-070b-45eb-b2e7-d63926d5bdd7"
|
||||||
|
__moref: "VirtualMachine:vm-288560"
|
||||||
|
memoryGB: "4"
|
||||||
|
datacenter: "Datacenter:datacenter-2"
|
||||||
|
provisionGB: "1"
|
||||||
|
__dcSelfLink: "/resources/groups/b28c7b8de065f07558b1612fce028"
|
||||||
|
softwareName: "Microsoft Windows XP Professional (32-bit)"
|
||||||
|
__computeType: "VirtualMachine"
|
||||||
|
__hasSnapshot: "false"
|
||||||
|
__placementLink: "/resources/compute/9bdc98681fb8b27557252188607b8"
|
||||||
|
__computeHostLink: "/resources/compute/9bdc98681fb8b27557252188607b8"
|
||||||
|
|
||||||
|
ipDeallocations:
|
||||||
|
- id: "111bb2f0-02fd-4983-94d2-8ac11768150f"
|
||||||
|
ipRangeId: "network/ZG5zLm5ldHdvcmskMTAuMjMuMTE3LjAvMjQvMA:10.23.117.0/24/default"
|
||||||
|
ipAddress: "10.23.117.5"
|
||||||
|
endpoint:
|
||||||
|
id: "f097759d8736675585c4c5d272cd"
|
||||||
|
endpointProperties:
|
||||||
|
hostName: "sampleipam.sof-mbu.eng.vmware.com"
|
||||||
|
projectId: "111bb2f0-02fd-4983-94d2-8ac11768150f"
|
||||||
|
providerId: "d8a5e3f2-d839-4365-af5b-f48de588fdc1"
|
||||||
|
certificate: "-----BEGIN CERTIFICATE-----\nMIID0jCCArqgAwIBAgIQQaJF55UCb58f9KgQLD/QgTANBgkqhkiG9w0BAQUFADCB\niTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExEjAQBgNVBAcTCVN1\nbm55dmFsZTERMA8GA1UEChMISW5mb2Jsb3gxFDASBgNVBAsTC0VuZ2luZWVyaW5n\nMSgwJgYDVQQDEx9pbmZvYmxveC5zb2YtbWJ1LmVuZy52bXdhcmUuY29tMB4XDTE5\nMDEyOTEzMDExMloXDTIwMDEyOTEzMDExMlowgYkxCzAJBgNVBAYTAlVTMRMwEQYD\nVQQIEwpDYWxpZm9ybmlhMRIwEAYDVQQHEwlTdW5ueXZhbGUxETAPBgNVBAoTCElu\nZm9ibG94MRQwEgYDVQQLEwtFbmdpbmVlcmluZzEoMCYGA1UEAxMfaW5mb2Jsb3gu\nc29mLW1idS5lbmcudm13YXJlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC\nAQoCggEBAMMLNTqbAri6rt/H8iC4UgRdN0qj+wk0R2blmD9h1BiZJTeQk1r9i2rz\nzUOZHvE8Bld8m8xJ+nysWHaoFFGTX8bOd/p20oJBGbCLqXtoLMMBGAlP7nzWGBXH\nBYUS7kMv/CG+PSX0uuB0pRbhwOFq8Y69m4HRnn2X0WJGuu+v0FmRK/1m/kCacHga\nMBKaIgbwN72rW1t/MK0ijogmLR1ASY4FlMn7OBHIEUzO+dWFBh+gPDjoBECTTH8W\n5AK9TnYdxwAtJRYWmnVqtLoT3bImtSfI4YLUtpr9r13Kv5FkYVbXov1KBrQPbYyp\n72uT2ZgDJT4YUuWyKpMppgw1VcG3MosCAwEAAaM0MDIwMAYDVR0RBCkwJ4cEChda\nCoIfaW5mb2Jsb3guc29mLW1idS5lbmcudm13YXJlLmNvbTANBgkqhkiG9w0BAQUF\nAAOCAQEAXFPIh00VI55Sdfx+czbBb4rJz3c1xgN7pbV46K0nGI8S6ufAQPgLvZJ6\ng2T/mpo0FTuWCz1IE9PC28276vwv+xJZQwQyoUq4lhT6At84NWN+ZdLEe+aBAq+Y\nxUcIWzcKv8WdnlS5DRQxnw6pQCBdisnaFoEIzngQV8oYeIemW4Hcmb//yeykbZKJ\n0GTtK5Pud+kCkYmMHpmhH21q+3aRIcdzOYIoXhdzmIKG0Och97HthqpvRfOeWQ/A\nPDbxqQ2R/3D0gt9jWPCG7c0lB8Ynl24jLBB0RhY6mBrYpFbtXBQSEciUDRJVB2zL\nV8nJiMdhj+Q+ZmtSwhNRvi2qvWAUJQ==\n-----END CERTIFICATE-----\n"
|
||||||
|
authCredentialsLink: "/core/auth/credentials/13c9cbade08950755898c4b89c4a0"
|
||||||
|
timeoutSeconds: 600
|
||||||
|
deploymentTimeoutSeconds: 600
|
||||||
|
actionType: "SCRIPT"
|
||||||
|
configuration:
|
||||||
|
const-providers:
|
||||||
|
- ""
|
||||||
|
const_azure-system_managed_identity: false
|
||||||
|
actionTemplateName: "Custom script"
|
||||||
|
actionTemplateNamespace: "com.vmware.automation.abx"
|
||||||
|
memoryInMB: 3000
|
38
src/main/resources/bundle/deallocate_ip_range.abx
Normal file
38
src/main/resources/bundle/deallocate_ip_range.abx
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
---
|
||||||
|
exportVersion: "1"
|
||||||
|
exportId: "@provider.name@_DeallocateIPRange"
|
||||||
|
name: "@provider.name@_DeallocateIPRange"
|
||||||
|
runtime: "python"
|
||||||
|
entrypoint: "source.handler"
|
||||||
|
inputs:
|
||||||
|
resourceInfo:
|
||||||
|
id: "/resources/sub-networks/255ac10c-0198-4a92-9414-b8e0c23c0204"
|
||||||
|
name: "net1-mcm223-126361015194"
|
||||||
|
type: "SUBNET"
|
||||||
|
owner: "mdzhigarov@vmware.com"
|
||||||
|
orgId: "ce811934-ea1a-4f53-b6ec-465e6ca7d126"
|
||||||
|
|
||||||
|
ipRangeDeallocation:
|
||||||
|
ipRangeId: "network/ZG5zLm5ldHdvcmskMTAuMjMuMTE3LjAvMjQvMA:10.23.117.0/24/default"
|
||||||
|
addressSpaceIs: "default"
|
||||||
|
properties:
|
||||||
|
__subnetName: "net1-mcm223-126361015194"
|
||||||
|
__subnetRangeCidr: "10.23.117.0/24"
|
||||||
|
endpoint:
|
||||||
|
id: "f097759d8736675585c4c5d272cd"
|
||||||
|
endpointProperties:
|
||||||
|
hostName: "sampleipam.sof-mbu.eng.vmware.com"
|
||||||
|
projectId: "111bb2f0-02fd-4983-94d2-8ac11768150f"
|
||||||
|
providerId: "d8a5e3f2-d839-4365-af5b-f48de588fdc1"
|
||||||
|
certificate: "-----BEGIN CERTIFICATE-----\nMIID0jCCArqgAwIBAgIQQaJF55UCb58f9KgQLD/QgTANBgkqhkiG9w0BAQUFADCB\niTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExEjAQBgNVBAcTCVN1\nbm55dmFsZTERMA8GA1UEChMISW5mb2Jsb3gxFDASBgNVBAsTC0VuZ2luZWVyaW5n\nMSgwJgYDVQQDEx9pbmZvYmxveC5zb2YtbWJ1LmVuZy52bXdhcmUuY29tMB4XDTE5\nMDEyOTEzMDExMloXDTIwMDEyOTEzMDExMlowgYkxCzAJBgNVBAYTAlVTMRMwEQYD\nVQQIEwpDYWxpZm9ybmlhMRIwEAYDVQQHEwlTdW5ueXZhbGUxETAPBgNVBAoTCElu\nZm9ibG94MRQwEgYDVQQLEwtFbmdpbmVlcmluZzEoMCYGA1UEAxMfaW5mb2Jsb3gu\nc29mLW1idS5lbmcudm13YXJlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC\nAQoCggEBAMMLNTqbAri6rt/H8iC4UgRdN0qj+wk0R2blmD9h1BiZJTeQk1r9i2rz\nzUOZHvE8Bld8m8xJ+nysWHaoFFGTX8bOd/p20oJBGbCLqXtoLMMBGAlP7nzWGBXH\nBYUS7kMv/CG+PSX0uuB0pRbhwOFq8Y69m4HRnn2X0WJGuu+v0FmRK/1m/kCacHga\nMBKaIgbwN72rW1t/MK0ijogmLR1ASY4FlMn7OBHIEUzO+dWFBh+gPDjoBECTTH8W\n5AK9TnYdxwAtJRYWmnVqtLoT3bImtSfI4YLUtpr9r13Kv5FkYVbXov1KBrQPbYyp\n72uT2ZgDJT4YUuWyKpMppgw1VcG3MosCAwEAAaM0MDIwMAYDVR0RBCkwJ4cEChda\nCoIfaW5mb2Jsb3guc29mLW1idS5lbmcudm13YXJlLmNvbTANBgkqhkiG9w0BAQUF\nAAOCAQEAXFPIh00VI55Sdfx+czbBb4rJz3c1xgN7pbV46K0nGI8S6ufAQPgLvZJ6\ng2T/mpo0FTuWCz1IE9PC28276vwv+xJZQwQyoUq4lhT6At84NWN+ZdLEe+aBAq+Y\nxUcIWzcKv8WdnlS5DRQxnw6pQCBdisnaFoEIzngQV8oYeIemW4Hcmb//yeykbZKJ\n0GTtK5Pud+kCkYmMHpmhH21q+3aRIcdzOYIoXhdzmIKG0Och97HthqpvRfOeWQ/A\nPDbxqQ2R/3D0gt9jWPCG7c0lB8Ynl24jLBB0RhY6mBrYpFbtXBQSEciUDRJVB2zL\nV8nJiMdhj+Q+ZmtSwhNRvi2qvWAUJQ==\n-----END CERTIFICATE-----\n"
|
||||||
|
authCredentialsLink: "/core/auth/credentials/13c9cbade08950755898c4b89c4a0"
|
||||||
|
timeoutSeconds: 600
|
||||||
|
deploymentTimeoutSeconds: 600
|
||||||
|
actionType: "SCRIPT"
|
||||||
|
configuration:
|
||||||
|
const-providers:
|
||||||
|
- ""
|
||||||
|
const_azure-system_managed_identity: false
|
||||||
|
actionTemplateName: "Custom script"
|
||||||
|
actionTemplateNamespace: "com.vmware.automation.abx"
|
||||||
|
memoryInMB: 3000
|
25
src/main/resources/bundle/get_ip_blocks.abx
Normal file
25
src/main/resources/bundle/get_ip_blocks.abx
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
---
|
||||||
|
exportVersion: "1"
|
||||||
|
exportId: "@provider.name@_GetIPBlocks"
|
||||||
|
name: "@provider.name@_GetIPBlocks"
|
||||||
|
runtime: "python"
|
||||||
|
entrypoint: "source.handler"
|
||||||
|
inputs:
|
||||||
|
endpoint:
|
||||||
|
id: "f097759d8736675585c4c5d272cd"
|
||||||
|
authCredentialsLink: "/core/auth/credentials/13c9cbade08950755898c4b89c4a0"
|
||||||
|
endpointProperties:
|
||||||
|
hostName: "sampleipam.sof-mbu.eng.vmware.com"
|
||||||
|
pagingAndSorting:
|
||||||
|
maxResults: 1000
|
||||||
|
pageToken: "789c55905d6e02310c84df7d91452a456481168ec04b55950344f9db55dadd384abc056e5f3b42adfa12299f279ec9ac7c5670e9b0045a4ad2430c93af7a465f3bc83d4f9e3aa8976e6681ce660c827770de2aa1a68c72dfc3cae74393999b2e4df302e72691373aa60199bd827398efac18810f87a952591c61817c849513999df0b6c11436d6d400effcfacc14f2099cd6768913c5a435a0fd0c8e20ab2dbcd147564a2228c93b60b99ae2d94efde6ac640a09d9331130c539367078c41c915067ac9122268dc350439bf3379e9bc01b32025e9bd111aa65c829e89e83f0135ba740572c5f525c73f95faa608e39e55e62c6fcbd37de9775b891212a758d59bceb7a0eb30d7c7f6cd35c1399984291053b30f29fc5feed6cedf7adfe21962ab17b8ebde5089b1fec0d97d7-e5c4e5a1d726f600c22ebfd9f186148a1449755fd79a69ceabfe2aa"
|
||||||
|
timeoutSeconds: 600
|
||||||
|
deploymentTimeoutSeconds: 600
|
||||||
|
actionType: "SCRIPT"
|
||||||
|
configuration:
|
||||||
|
const-providers:
|
||||||
|
- ""
|
||||||
|
const_azure-system_managed_identity: false
|
||||||
|
actionTemplateName: "Custom script"
|
||||||
|
actionTemplateNamespace: "com.vmware.automation.abx"
|
||||||
|
memoryInMB: 3000
|
25
src/main/resources/bundle/get_ip_ranges.abx
Normal file
25
src/main/resources/bundle/get_ip_ranges.abx
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
---
|
||||||
|
exportVersion: "1"
|
||||||
|
exportId: "@provider.name@_GetIPRanges"
|
||||||
|
name: "@provider.name@_GetIPRanges"
|
||||||
|
runtime: "python"
|
||||||
|
entrypoint: "source.handler"
|
||||||
|
inputs:
|
||||||
|
endpoint:
|
||||||
|
id: "f097759d8736675585c4c5d272cd"
|
||||||
|
authCredentialsLink: "/core/auth/credentials/13c9cbade08950755898c4b89c4a0"
|
||||||
|
endpointProperties:
|
||||||
|
hostName: "sampleipam.sof-mbu.eng.vmware.com"
|
||||||
|
pagingAndSorting:
|
||||||
|
maxResults: 1000
|
||||||
|
pageToken: "789c55905d6e02310c84df7d91452a456481168ec04b55950344f9db55dadd384abc056e5f3b42adfa12299f279ec9ac7c5670e9b0045a4ad2430c93af7a465f3bc83d4f9e3aa8976e6681ce660c827770de2aa1a68c72dfc3cae74393999b2e4df302e72691373aa60199bd827398efac18810f87a952591c61817c849513999df0b6c11436d6d400effcfacc14f2099cd6768913c5a435a0fd0c8e20ab2dbcd147564a2228c93b60b99ae2d94efde6ac640a09d9331130c539367078c41c915067ac9122268dc350439bf3379e9bc01b32025e9bd111aa65c829e89e83f0135ba740572c5f525c73f95faa608e39e55e62c6fcbd37de9775b891212a758d59bceb7a0eb30d7c7f6cd35c1399984291053b30f29fc5feed6cedf7adfe21962ab17b8ebde5089b1fec0d97d7-e5c4e5a1d726f600c22ebfd9f186148a1449755fd79a69ceabfe2aa"
|
||||||
|
timeoutSeconds: 600
|
||||||
|
deploymentTimeoutSeconds: 600
|
||||||
|
actionType: "SCRIPT"
|
||||||
|
configuration:
|
||||||
|
const-providers:
|
||||||
|
- ""
|
||||||
|
const_azure-system_managed_identity: false
|
||||||
|
actionTemplateName: "Custom script"
|
||||||
|
actionTemplateNamespace: "com.vmware.automation.abx"
|
||||||
|
memoryInMB: 3000
|
50
src/main/resources/bundle/update_record.abx
Normal file
50
src/main/resources/bundle/update_record.abx
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
---
|
||||||
|
exportVersion: "1"
|
||||||
|
exportId: "@provider.name@_Update"
|
||||||
|
name: "@provider.name@_Update"
|
||||||
|
runtime: "python"
|
||||||
|
entrypoint: "source.handler"
|
||||||
|
inputs:
|
||||||
|
resourceInfo:
|
||||||
|
id: "11f912e71454a075574a728848458"
|
||||||
|
name: "external-ipam-it-mcm-323412"
|
||||||
|
description: "test"
|
||||||
|
type: "VM"
|
||||||
|
owner: "mdzhigarov@vmware.com"
|
||||||
|
orgId: "ce811934-ea1a-4f53-b6ec-465e6ca7d126"
|
||||||
|
properties:
|
||||||
|
osType: "WINDOWS"
|
||||||
|
vcUuid: "ff257ed9-070b-45eb-b2e7-d63926d5bdd7"
|
||||||
|
__moref: "VirtualMachine:vm-288560"
|
||||||
|
memoryGB: "4"
|
||||||
|
datacenter: "Datacenter:datacenter-2"
|
||||||
|
provisionGB: "1"
|
||||||
|
__dcSelfLink: "/resources/groups/b28c7b8de065f07558b1612fce028"
|
||||||
|
softwareName: "Microsoft Windows XP Professional (32-bit)"
|
||||||
|
__computeType: "VirtualMachine"
|
||||||
|
__hasSnapshot: "false"
|
||||||
|
__placementLink: "/resources/compute/9bdc98681fb8b27557252188607b8"
|
||||||
|
__computeHostLink: "/resources/compute/9bdc98681fb8b27557252188607b8"
|
||||||
|
|
||||||
|
addressInfos:
|
||||||
|
- nicIndex: 0
|
||||||
|
address: "10.23.117.1"
|
||||||
|
macAddress: "00:30:26:a7:23:26"
|
||||||
|
endpoint:
|
||||||
|
id: "f097759d8736675585c4c5d272cd"
|
||||||
|
endpointProperties:
|
||||||
|
hostName: "sampleipam.sof-mbu.eng.vmware.com"
|
||||||
|
projectId: "111bb2f0-02fd-4983-94d2-8ac11768150f"
|
||||||
|
providerId: "d8a5e3f2-d839-4365-af5b-f48de588fdc1"
|
||||||
|
certificate: "-----BEGIN CERTIFICATE-----\nMIID0jCCArqgAwIBAgIQQaJF55UCb58f9KgQLD/QgTANBgkqhkiG9w0BAQUFADCB\niTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExEjAQBgNVBAcTCVN1\nbm55dmFsZTERMA8GA1UEChMISW5mb2Jsb3gxFDASBgNVBAsTC0VuZ2luZWVyaW5n\nMSgwJgYDVQQDEx9pbmZvYmxveC5zb2YtbWJ1LmVuZy52bXdhcmUuY29tMB4XDTE5\nMDEyOTEzMDExMloXDTIwMDEyOTEzMDExMlowgYkxCzAJBgNVBAYTAlVTMRMwEQYD\nVQQIEwpDYWxpZm9ybmlhMRIwEAYDVQQHEwlTdW5ueXZhbGUxETAPBgNVBAoTCElu\nZm9ibG94MRQwEgYDVQQLEwtFbmdpbmVlcmluZzEoMCYGA1UEAxMfaW5mb2Jsb3gu\nc29mLW1idS5lbmcudm13YXJlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC\nAQoCggEBAMMLNTqbAri6rt/H8iC4UgRdN0qj+wk0R2blmD9h1BiZJTeQk1r9i2rz\nzUOZHvE8Bld8m8xJ+nysWHaoFFGTX8bOd/p20oJBGbCLqXtoLMMBGAlP7nzWGBXH\nBYUS7kMv/CG+PSX0uuB0pRbhwOFq8Y69m4HRnn2X0WJGuu+v0FmRK/1m/kCacHga\nMBKaIgbwN72rW1t/MK0ijogmLR1ASY4FlMn7OBHIEUzO+dWFBh+gPDjoBECTTH8W\n5AK9TnYdxwAtJRYWmnVqtLoT3bImtSfI4YLUtpr9r13Kv5FkYVbXov1KBrQPbYyp\n72uT2ZgDJT4YUuWyKpMppgw1VcG3MosCAwEAAaM0MDIwMAYDVR0RBCkwJ4cEChda\nCoIfaW5mb2Jsb3guc29mLW1idS5lbmcudm13YXJlLmNvbTANBgkqhkiG9w0BAQUF\nAAOCAQEAXFPIh00VI55Sdfx+czbBb4rJz3c1xgN7pbV46K0nGI8S6ufAQPgLvZJ6\ng2T/mpo0FTuWCz1IE9PC28276vwv+xJZQwQyoUq4lhT6At84NWN+ZdLEe+aBAq+Y\nxUcIWzcKv8WdnlS5DRQxnw6pQCBdisnaFoEIzngQV8oYeIemW4Hcmb//yeykbZKJ\n0GTtK5Pud+kCkYmMHpmhH21q+3aRIcdzOYIoXhdzmIKG0Och97HthqpvRfOeWQ/A\nPDbxqQ2R/3D0gt9jWPCG7c0lB8Ynl24jLBB0RhY6mBrYpFbtXBQSEciUDRJVB2zL\nV8nJiMdhj+Q+ZmtSwhNRvi2qvWAUJQ==\n-----END CERTIFICATE-----\n"
|
||||||
|
authCredentialsLink: "/core/auth/credentials/13c9cbade08950755898c4b89c4a0"
|
||||||
|
timeoutSeconds: 600
|
||||||
|
deploymentTimeoutSeconds: 600
|
||||||
|
actionType: "SCRIPT"
|
||||||
|
configuration:
|
||||||
|
const-providers:
|
||||||
|
- ""
|
||||||
|
const_azure-system_managed_identity: false
|
||||||
|
actionTemplateName: "Custom script"
|
||||||
|
actionTemplateNamespace: "com.vmware.automation.abx"
|
||||||
|
memoryInMB: 3000
|
20
src/main/resources/bundle/validate_endpoint.abx
Normal file
20
src/main/resources/bundle/validate_endpoint.abx
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
---
|
||||||
|
exportVersion: "1"
|
||||||
|
exportId: "@provider.name@_ValidateEndpoint"
|
||||||
|
name: "@provider.name@_ValidateEndpoint"
|
||||||
|
runtime: "python"
|
||||||
|
entrypoint: "source.handler"
|
||||||
|
inputs:
|
||||||
|
authCredentialsLink: "/core/auth/credentials/13c9cbade08950755898c4b89c4a0"
|
||||||
|
endpointProperties:
|
||||||
|
hostName: "sampleipam.sof-mbu.eng.vmware.com"
|
||||||
|
timeoutSeconds: 600
|
||||||
|
deploymentTimeoutSeconds: 600
|
||||||
|
actionType: "SCRIPT"
|
||||||
|
configuration:
|
||||||
|
const-providers:
|
||||||
|
- ""
|
||||||
|
const_azure-system_managed_identity: false
|
||||||
|
actionTemplateName: "Custom script"
|
||||||
|
actionTemplateNamespace: "com.vmware.automation.abx"
|
||||||
|
memoryInMB: 600
|
0
src/main/resources/dependencies.collected.flag
Normal file
0
src/main/resources/dependencies.collected.flag
Normal file
74
src/main/resources/endpoint-schema.json
Normal file
74
src/main/resources/endpoint-schema.json
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
{
|
||||||
|
"layout":{
|
||||||
|
"pages":[
|
||||||
|
{
|
||||||
|
"id":"Sample IPAM",
|
||||||
|
"title":"Sample IPAM endpoint",
|
||||||
|
"sections":[
|
||||||
|
{
|
||||||
|
"id":"section_1",
|
||||||
|
"fields":[
|
||||||
|
{
|
||||||
|
"id":"apiAppId",
|
||||||
|
"display":"textField"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":"privateKeyId",
|
||||||
|
"display":"textField"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":"privateKey",
|
||||||
|
"display":"passwordField"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":"hostName",
|
||||||
|
"display":"textField"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"schema":{
|
||||||
|
"apiAppId":{
|
||||||
|
"type":{
|
||||||
|
"dataType":"string"
|
||||||
|
},
|
||||||
|
"label":"API App ID",
|
||||||
|
"constraints":{
|
||||||
|
"required":true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"privateKeyId":{
|
||||||
|
"type":{
|
||||||
|
"dataType":"string"
|
||||||
|
},
|
||||||
|
"label":"Username",
|
||||||
|
"constraints":{
|
||||||
|
"required":true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"privateKey":{
|
||||||
|
"label":"Password",
|
||||||
|
"type":{
|
||||||
|
"dataType":"secureString"
|
||||||
|
},
|
||||||
|
"constraints":{
|
||||||
|
"required":true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"hostName":{
|
||||||
|
"type":{
|
||||||
|
"dataType":"string"
|
||||||
|
},
|
||||||
|
"label":"Hostname",
|
||||||
|
"constraints":{
|
||||||
|
"required":true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"options":{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
BIN
src/main/resources/logo.png
Normal file
BIN
src/main/resources/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
19
src/main/resources/registration.yaml
Normal file
19
src/main/resources/registration.yaml
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
---
|
||||||
|
name: "@provider.name@"
|
||||||
|
description: "@provider.description@"
|
||||||
|
version: "@provider.version@"
|
||||||
|
|
||||||
|
abxConfig:
|
||||||
|
allocateIPActionId: "@provider.name@_AllocateIP"
|
||||||
|
deallocateIPActionId: "@provider.name@_DeallocateIP"
|
||||||
|
validateEndpointActionId: "@provider.name@_ValidateEndpoint"
|
||||||
|
updateResourceActionId: "@provider.name@_Update"
|
||||||
|
getIPRangesActionId: "@provider.name@_GetIPRanges"
|
||||||
|
allocateNetworkActionId: "@provider.name@_AllocateIPRange"
|
||||||
|
deallocateNetworkActionId: "@provider.name@_DeallocateIPRange"
|
||||||
|
getIPBlocksActionId: "@provider.name@_GetIPBlocks"
|
||||||
|
|
||||||
|
properties:
|
||||||
|
@supportsAddressSpaces@
|
||||||
|
supportsUpdateRecord: @provider.supportsUpdateRecord@
|
||||||
|
supportsOnDemandNetworks: @provider.supportsOnDemandNetworks@
|
63
src/test/python/mocks_for_manual_testing/AllocateIP_mock.py
Normal file
63
src/test/python/mocks_for_manual_testing/AllocateIP_mock.py
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
input = {
|
||||||
|
"resourceInfo": {
|
||||||
|
"id": "11f912e71454a075574a728848458",
|
||||||
|
"name": "external-ipam-it-mcm-3234139",
|
||||||
|
"description": "test",
|
||||||
|
"type": "VM",
|
||||||
|
"owner": "mdzhigarov@vmware.com",
|
||||||
|
"orgId": "ce811934-ea1a-4f53-b6ec-465e6ca7d126",
|
||||||
|
"properties": {
|
||||||
|
"osType": "WINDOWS",
|
||||||
|
"vcUuid": "ff257ed9-070b-45eb-b2e7-d63926d5bdd7",
|
||||||
|
"__moref": "VirtualMachine:vm-288560",
|
||||||
|
"memoryGB": "4",
|
||||||
|
"datacenter": "Datacenter:datacenter-2",
|
||||||
|
"provisionGB": "1",
|
||||||
|
"__dcSelfLink": "/resources/groups/b28c7b8de065f07558b1612fce028",
|
||||||
|
"softwareName": "Microsoft Windows XP Professional (32-bit)",
|
||||||
|
"__computeType": "VirtualMachine",
|
||||||
|
"__hasSnapshot": "false",
|
||||||
|
"__placementLink": "/resources/compute/9bdc98681fb8b27557252188607b8",
|
||||||
|
"__computeHostLink": "/resources/compute/9bdc98681fb8b27557252188607b8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ipAllocations": [{
|
||||||
|
"id": "111bb2f0-02fd-4983-94d2-8ac11768150f",
|
||||||
|
"ipRangeIds": ["range/ZG5zLmRoY3BfcmFuZ2UkMTAuMTAuMjQuMjEvMTAuMTAuMjQuMjIvLy8xLw:10.10.24.21/10.10.24.22/mdzh-net", "range/ZG5zLmRoY3BfcmFuZ2UkMTAuMTAuMjQuMTAvMTAuMTAuMjQuMjAvLy8xLw:10.10.24.10/10.10.24.20/mdzh-net"],
|
||||||
|
#"ipRangeIds": ["network/ZG5zLm5ldHdvcmskMTAuMTAuMjMuMTYvMjgvMQ:10.10.23.16/28/mdzh-net"],
|
||||||
|
"nicIndex": "0",
|
||||||
|
"isPrimary": "true",
|
||||||
|
"size": "1",
|
||||||
|
"properties": {
|
||||||
|
"__moref": "DistributedVirtualPortgroup:dvportgroup-307087",
|
||||||
|
"__dvsUuid": "0c 8c 0b 50 46 b6 1c f2-e8 63 f4 24 24 d7 24 6c",
|
||||||
|
"__dcSelfLink": "/resources/groups/abe46b8cfa663a7558b28a6ffe088",
|
||||||
|
"__computeType": "DistributedVirtualPortgroup",
|
||||||
|
"__portgroupKey": "dvportgroup-307087"
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
"endpoint": {
|
||||||
|
"id": "112bb240-02fd-4983-9432-8ac11768150f",
|
||||||
|
"endpointProperties": {
|
||||||
|
"hostName": "infoblox.sof-mbu.eng.vmware.com",
|
||||||
|
"projectId": "111bb2f0-02fd-4983-94d2-8ac11768150f",
|
||||||
|
"providerId": "d8a5e3f2-d839-4365-af5b-f48de588fdc1",
|
||||||
|
"isLocalEnv":"true",
|
||||||
|
"certificate": """-----BEGIN CERTIFICATE-----\nMIID0jCCArqgAwIBAgIQQaJF55UCb58f9KgQLD/QgTANBgkqhkiG9w0BAQUFADCB\niTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExEjAQBgNVBAcTCVN1\nbm55dmFsZTERMA8GA1UEChMISW5mb2Jsb3gxFDASBgNVBAsTC0VuZ2luZWVyaW5n\nMSgwJgYDVQQDEx9pbmZvYmxveC5zb2YtbWJ1LmVuZy52bXdhcmUuY29tMB4XDTE5\nMDEyOTEzMDExMloXDTIwMDEyOTEzMDExMlowgYkxCzAJBgNVBAYTAlVTMRMwEQYD\nVQQIEwpDYWxpZm9ybmlhMRIwEAYDVQQHEwlTdW5ueXZhbGUxETAPBgNVBAoTCElu\nZm9ibG94MRQwEgYDVQQLEwtFbmdpbmVlcmluZzEoMCYGA1UEAxMfaW5mb2Jsb3gu\nc29mLW1idS5lbmcudm13YXJlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC\nAQoCggEBAMMLNTqbAri6rt/H8iC4UgRdN0qj+wk0R2blmD9h1BiZJTeQk1r9i2rz\nzUOZHvE8Bld8m8xJ+nysWHaoFFGTX8bOd/p20oJBGbCLqXtoLMMBGAlP7nzWGBXH\nBYUS7kMv/CG+PSX0uuB0pRbhwOFq8Y69m4HRnn2X0WJGuu+v0FmRK/1m/kCacHga\nMBKaIgbwN72rW1t/MK0ijogmLR1ASY4FlMn7OBHIEUzO+dWFBh+gPDjoBECTTH8W\n5AK9TnYdxwAtJRYWmnVqtLoT3bImtSfI4YLUtpr9r13Kv5FkYVbXov1KBrQPbYyp\n72uT2ZgDJT4YUuWyKpMppgw1VcG3MosCAwEAAaM0MDIwMAYDVR0RBCkwJ4cEChda\nCoIfaW5mb2Jsb3guc29mLW1idS5lbmcudm13YXJlLmNvbTANBgkqhkiG9w0BAQUF\nAAOCAQEAXFPIh00VI55Sdfx+czbBb4rJz3c1xgN7pbV46K0nGI8S6ufAQPgLvZJ6\ng2T/mpo0FTuWCz1IE9PC28276vwv+xJZQwQyoUq4lhT6At84NWN+ZdLEe+aBAq+Y\nxUcIWzcKv8WdnlS5DRQxnw6pQCBdisnaFoEIzngQV8oYeIemW4Hcmb//yeykbZKJ\n0GTtK5Pud+kCkYmMHpmhH21q+3aRIcdzOYIoXhdzmIKG0Och97HthqpvRfOeWQ/A\nPDbxqQ2R/3D0gt9jWPCG7c0lB8Ynl24jLBB0RhY6mBrYpFbtXBQSEciUDRJVB2zL\nV8nJiMdhj+Q+ZmtSwhNRvi2qvWAUJQ==\n-----END CERTIFICATE-----\n"""
|
||||||
|
},
|
||||||
|
"authCredentialsLink": "/core/auth/credentials/13c9cbade08950755898c4b89c4a0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
from unittest import TestCase
|
||||||
|
from unittest.mock import MagicMock
|
||||||
|
from unittest.mock import Mock
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
context = MagicMock()
|
||||||
|
auth_credentials = {"status": 200, "content": "{\"privateKeyId\": \"admin\", \"privateKey\": \"VMware1!\"}"}
|
||||||
|
subnet_ranges = {"status": 200, "content": "{\"totalCount\": 1, \"documents\": {\"/resources/subnet-ranges/c19bd2921af950755777fd33fe060\": {\"domain\": \"test.local\"}}}"}
|
||||||
|
context.request.side_effect = [auth_credentials, subnet_ranges, subnet_ranges]
|
||||||
|
|
||||||
|
print(handler(context, input))
|
|
@ -0,0 +1,60 @@
|
||||||
|
from src.main.python.deallocate_ip.source import handler
|
||||||
|
|
||||||
|
input = {
|
||||||
|
"resourceInfo": {
|
||||||
|
"id": "/resources/compute/226478cf7e3296b7",
|
||||||
|
"name": "ipantchev-test",
|
||||||
|
"description": "test",
|
||||||
|
"type": "VM",
|
||||||
|
"owner": "ipantchev@vmware.com",
|
||||||
|
"orgId": "ce811934-ea1a-4f53-b6ec-465e6ca7d126",
|
||||||
|
"properties": {
|
||||||
|
"osType": "WINDOWS",
|
||||||
|
"vcUuid": "ff257ed9-070b-45eb-b2e7-d63926d5bdd7",
|
||||||
|
"__moref": "VirtualMachine:vm-288560",
|
||||||
|
"memoryGB": "4",
|
||||||
|
"datacenter": "Datacenter:datacenter-2",
|
||||||
|
"provisionGB": "1",
|
||||||
|
"__dcSelfLink": "/resources/groups/b28c7b8de065f07558b1612fce028",
|
||||||
|
"softwareName": "Microsoft Windows XP Professional (32-bit)",
|
||||||
|
"__computeType": "VirtualMachine",
|
||||||
|
"__hasSnapshot": "false",
|
||||||
|
"__placementLink": "/resources/compute/9bdc98681fb8b27557252188607b8",
|
||||||
|
"__computeHostLink": "/resources/compute/9bdc98681fb8b27557252188607b8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ipDeallocations": [{
|
||||||
|
"id": "111bb2f0-02fd-4983-94d2-8ac11768150f",
|
||||||
|
"ipAddress": "10.10.24.1",
|
||||||
|
"ipRangeId": "range/ZG5zLmRoY3BfcmFuZ2UkMTAuMTAuMjQuMjEvMTAuMTAuMjQuMjIvLy8xLw:10.10.24.21/10.10.24.22/mdzh-net",
|
||||||
|
"nicIndex": "0",
|
||||||
|
"isPrimary": "true",
|
||||||
|
"size": "1",
|
||||||
|
"properties": {
|
||||||
|
"__moref": "DistributedVirtualPortgroup:dvportgroup-307087",
|
||||||
|
"__dvsUuid": "0c 8c 0b 50 46 b6 1c f2-e8 63 f4 24 24 d7 24 6c",
|
||||||
|
"__dcSelfLink": "/resources/groups/abe46b8cfa663a7558b28a6ffe088",
|
||||||
|
"__computeType": "DistributedVirtualPortgroup",
|
||||||
|
"__portgroupKey": "dvportgroup-307087"
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
"endpoint": {
|
||||||
|
"endpointProperties": {
|
||||||
|
"hostName": "infoblox.sof-mbu.eng.vmware.com",
|
||||||
|
"projectId": "111bb2f0-02fd-4983-94d2-8ac11768150f",
|
||||||
|
"providerId": "d8a5e3f2-d839-4365-af5b-f48de588fdc1",
|
||||||
|
"isLocalEnv":"true",
|
||||||
|
"certificate": """-----BEGIN CERTIFICATE-----\nMIID0jCCArqgAwIBAgIQQaJF55UCb58f9KgQLD/QgTANBgkqhkiG9w0BAQUFADCB\niTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExEjAQBgNVBAcTCVN1\nbm55dmFsZTERMA8GA1UEChMISW5mb2Jsb3gxFDASBgNVBAsTC0VuZ2luZWVyaW5n\nMSgwJgYDVQQDEx9pbmZvYmxveC5zb2YtbWJ1LmVuZy52bXdhcmUuY29tMB4XDTE5\nMDEyOTEzMDExMloXDTIwMDEyOTEzMDExMlowgYkxCzAJBgNVBAYTAlVTMRMwEQYD\nVQQIEwpDYWxpZm9ybmlhMRIwEAYDVQQHEwlTdW5ueXZhbGUxETAPBgNVBAoTCElu\nZm9ibG94MRQwEgYDVQQLEwtFbmdpbmVlcmluZzEoMCYGA1UEAxMfaW5mb2Jsb3gu\nc29mLW1idS5lbmcudm13YXJlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC\nAQoCggEBAMMLNTqbAri6rt/H8iC4UgRdN0qj+wk0R2blmD9h1BiZJTeQk1r9i2rz\nzUOZHvE8Bld8m8xJ+nysWHaoFFGTX8bOd/p20oJBGbCLqXtoLMMBGAlP7nzWGBXH\nBYUS7kMv/CG+PSX0uuB0pRbhwOFq8Y69m4HRnn2X0WJGuu+v0FmRK/1m/kCacHga\nMBKaIgbwN72rW1t/MK0ijogmLR1ASY4FlMn7OBHIEUzO+dWFBh+gPDjoBECTTH8W\n5AK9TnYdxwAtJRYWmnVqtLoT3bImtSfI4YLUtpr9r13Kv5FkYVbXov1KBrQPbYyp\n72uT2ZgDJT4YUuWyKpMppgw1VcG3MosCAwEAAaM0MDIwMAYDVR0RBCkwJ4cEChda\nCoIfaW5mb2Jsb3guc29mLW1idS5lbmcudm13YXJlLmNvbTANBgkqhkiG9w0BAQUF\nAAOCAQEAXFPIh00VI55Sdfx+czbBb4rJz3c1xgN7pbV46K0nGI8S6ufAQPgLvZJ6\ng2T/mpo0FTuWCz1IE9PC28276vwv+xJZQwQyoUq4lhT6At84NWN+ZdLEe+aBAq+Y\nxUcIWzcKv8WdnlS5DRQxnw6pQCBdisnaFoEIzngQV8oYeIemW4Hcmb//yeykbZKJ\n0GTtK5Pud+kCkYmMHpmhH21q+3aRIcdzOYIoXhdzmIKG0Och97HthqpvRfOeWQ/A\nPDbxqQ2R/3D0gt9jWPCG7c0lB8Ynl24jLBB0RhY6mBrYpFbtXBQSEciUDRJVB2zL\nV8nJiMdhj+Q+ZmtSwhNRvi2qvWAUJQ==\n-----END CERTIFICATE-----\n"""
|
||||||
|
},
|
||||||
|
"authCredentialsLink": "/core/auth/credentials/13c9cbade08950755898c4b89c4a0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
from unittest.mock import MagicMock
|
||||||
|
|
||||||
|
context = MagicMock()
|
||||||
|
auth_credentials = {"status": 200, "content": "{\"privateKeyId\": \"admin\", \"privateKey\": \"VMware1!\"}"}
|
||||||
|
subnet_ranges = {"status": 200, "content": "{\"totalCount\": 1, \"documents\": {\"/resources/subnet-ranges/c19bd2921af950755777fd33fe060\": {\"domain\": \"test.local\"}}}"}
|
||||||
|
context.request.side_effect = [auth_credentials, auth_credentials, subnet_ranges, subnet_ranges]
|
||||||
|
|
||||||
|
print(handler(context, input))
|
29
src/test/python/mocks_for_manual_testing/GetIPRanges_mock.py
Normal file
29
src/test/python/mocks_for_manual_testing/GetIPRanges_mock.py
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
input = {
|
||||||
|
"pagingAndSorting": {
|
||||||
|
"maxResults": 1000,
|
||||||
|
},
|
||||||
|
"endpoint": {
|
||||||
|
"id": "112bb240-02fd-4983-9432-8ac11768150f",
|
||||||
|
"endpointProperties": {
|
||||||
|
"hostName": "infoblox.sof-mbu.eng.vmware.com",
|
||||||
|
"projectId": "111bb2f0-02fd-4983-94d2-8ac11768150f",
|
||||||
|
"providerId": "d8a5e3f2-d839-4365-af5b-f48de588fdc1",
|
||||||
|
"isLocalEnv":"true",
|
||||||
|
"certificate": """-----BEGIN CERTIFICATE-----\nMIID0jCCArqgAwIBAgIQQaJF55UCb58f9KgQLD/QgTANBgkqhkiG9w0BAQUFADCB\niTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExEjAQBgNVBAcTCVN1\nbm55dmFsZTERMA8GA1UEChMISW5mb2Jsb3gxFDASBgNVBAsTC0VuZ2luZWVyaW5n\nMSgwJgYDVQQDEx9pbmZvYmxveC5zb2YtbWJ1LmVuZy52bXdhcmUuY29tMB4XDTE5\nMDEyOTEzMDExMloXDTIwMDEyOTEzMDExMlowgYkxCzAJBgNVBAYTAlVTMRMwEQYD\nVQQIEwpDYWxpZm9ybmlhMRIwEAYDVQQHEwlTdW5ueXZhbGUxETAPBgNVBAoTCElu\nZm9ibG94MRQwEgYDVQQLEwtFbmdpbmVlcmluZzEoMCYGA1UEAxMfaW5mb2Jsb3gu\nc29mLW1idS5lbmcudm13YXJlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC\nAQoCggEBAMMLNTqbAri6rt/H8iC4UgRdN0qj+wk0R2blmD9h1BiZJTeQk1r9i2rz\nzUOZHvE8Bld8m8xJ+nysWHaoFFGTX8bOd/p20oJBGbCLqXtoLMMBGAlP7nzWGBXH\nBYUS7kMv/CG+PSX0uuB0pRbhwOFq8Y69m4HRnn2X0WJGuu+v0FmRK/1m/kCacHga\nMBKaIgbwN72rW1t/MK0ijogmLR1ASY4FlMn7OBHIEUzO+dWFBh+gPDjoBECTTH8W\n5AK9TnYdxwAtJRYWmnVqtLoT3bImtSfI4YLUtpr9r13Kv5FkYVbXov1KBrQPbYyp\n72uT2ZgDJT4YUuWyKpMppgw1VcG3MosCAwEAAaM0MDIwMAYDVR0RBCkwJ4cEChda\nCoIfaW5mb2Jsb3guc29mLW1idS5lbmcudm13YXJlLmNvbTANBgkqhkiG9w0BAQUF\nAAOCAQEAXFPIh00VI55Sdfx+czbBb4rJz3c1xgN7pbV46K0nGI8S6ufAQPgLvZJ6\ng2T/mpo0FTuWCz1IE9PC28276vwv+xJZQwQyoUq4lhT6At84NWN+ZdLEe+aBAq+Y\nxUcIWzcKv8WdnlS5DRQxnw6pQCBdisnaFoEIzngQV8oYeIemW4Hcmb//yeykbZKJ\n0GTtK5Pud+kCkYmMHpmhH21q+3aRIcdzOYIoXhdzmIKG0Och97HthqpvRfOeWQ/A\nPDbxqQ2R/3D0gt9jWPCG7c0lB8Ynl24jLBB0RhY6mBrYpFbtXBQSEciUDRJVB2zL\nV8nJiMdhj+Q+ZmtSwhNRvi2qvWAUJQ==\n-----END CERTIFICATE-----\n"""
|
||||||
|
},
|
||||||
|
"authCredentialsLink": "/core/auth/credentials/13c9cbade08950755898c4b89c4a0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
from unittest import TestCase
|
||||||
|
from unittest.mock import MagicMock
|
||||||
|
from unittest.mock import Mock
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
context = MagicMock()
|
||||||
|
auth_credentials = {"status": 200, "content": "{\"privateKeyId\": \"admin\", \"privateKey\": \"VMware1!\"}"}
|
||||||
|
subnet_ranges = {"status": 200, "content": "{\"totalCount\": 1, \"documents\": {\"/resources/subnet-ranges/c19bd2921af950755777fd33fe060\": {\"domain\": \"test.local\"}}}"}
|
||||||
|
context.request.side_effect = [auth_credentials, subnet_ranges, subnet_ranges]
|
||||||
|
|
||||||
|
print(handler(context, input))
|
53
src/test/python/mocks_for_manual_testing/Update_mock.py
Normal file
53
src/test/python/mocks_for_manual_testing/Update_mock.py
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
input = {
|
||||||
|
"resourceInfo": {
|
||||||
|
"id": "5613490d-e64d-4797-ad70-3062d648b332",
|
||||||
|
"name": "external-ipam-it-mcm-3234139",
|
||||||
|
"description": "test",
|
||||||
|
"type": "VM",
|
||||||
|
"owner": "vraikov@vmware.com",
|
||||||
|
"hostname": "bond-006",
|
||||||
|
"orgId": "ce811934-ea1a-4f53-b6ec-465e6ca7d126",
|
||||||
|
"properties": {
|
||||||
|
"osType": "WINDOWS",
|
||||||
|
"vcUuid": "ff257ed9-070b-45eb-b2e7-d63926d5bdd7",
|
||||||
|
"__moref": "VirtualMachine:vm-288560",
|
||||||
|
"memoryGB": "4",
|
||||||
|
"datacenter": "Datacenter:datacenter-2",
|
||||||
|
"provisionGB": "1",
|
||||||
|
"__dcSelfLink": "/resources/groups/b28c7b8de065f07558b1612fce028",
|
||||||
|
"softwareName": "Microsoft Windows XP Professional (32-bit)",
|
||||||
|
"__computeType": "VirtualMachine",
|
||||||
|
"__hasSnapshot": "false",
|
||||||
|
"__placementLink": "/resources/compute/9bdc98681fb8b27557252188607b8",
|
||||||
|
"__computeHostLink": "/resources/compute/9bdc98681fb8b27557252188607b8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"addressInfos": [{
|
||||||
|
"nicIndex": 0,
|
||||||
|
"address": "10.23.117.1",
|
||||||
|
"macAddress": "00:30:26:a7:23:26"
|
||||||
|
}],
|
||||||
|
"endpoint": {
|
||||||
|
"endpointProperties": {
|
||||||
|
"hostName": "infoblox.sof-mbu.eng.vmware.com",
|
||||||
|
"projectId": "111bb2f0-02fd-4983-94d2-8ac11768150f",
|
||||||
|
"providerId": "d8a5e3f2-d839-4365-af5b-f48de588fdc1",
|
||||||
|
"isLocalEnv":"true",
|
||||||
|
"certificate": """-----BEGIN CERTIFICATE-----\nMIID0jCCArqgAwIBAgIQQaJF55UCb58f9KgQLD/QgTANBgkqhkiG9w0BAQUFADCB\niTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExEjAQBgNVBAcTCVN1\nbm55dmFsZTERMA8GA1UEChMISW5mb2Jsb3gxFDASBgNVBAsTC0VuZ2luZWVyaW5n\nMSgwJgYDVQQDEx9pbmZvYmxveC5zb2YtbWJ1LmVuZy52bXdhcmUuY29tMB4XDTE5\nMDEyOTEzMDExMloXDTIwMDEyOTEzMDExMlowgYkxCzAJBgNVBAYTAlVTMRMwEQYD\nVQQIEwpDYWxpZm9ybmlhMRIwEAYDVQQHEwlTdW5ueXZhbGUxETAPBgNVBAoTCElu\nZm9ibG94MRQwEgYDVQQLEwtFbmdpbmVlcmluZzEoMCYGA1UEAxMfaW5mb2Jsb3gu\nc29mLW1idS5lbmcudm13YXJlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC\nAQoCggEBAMMLNTqbAri6rt/H8iC4UgRdN0qj+wk0R2blmD9h1BiZJTeQk1r9i2rz\nzUOZHvE8Bld8m8xJ+nysWHaoFFGTX8bOd/p20oJBGbCLqXtoLMMBGAlP7nzWGBXH\nBYUS7kMv/CG+PSX0uuB0pRbhwOFq8Y69m4HRnn2X0WJGuu+v0FmRK/1m/kCacHga\nMBKaIgbwN72rW1t/MK0ijogmLR1ASY4FlMn7OBHIEUzO+dWFBh+gPDjoBECTTH8W\n5AK9TnYdxwAtJRYWmnVqtLoT3bImtSfI4YLUtpr9r13Kv5FkYVbXov1KBrQPbYyp\n72uT2ZgDJT4YUuWyKpMppgw1VcG3MosCAwEAAaM0MDIwMAYDVR0RBCkwJ4cEChda\nCoIfaW5mb2Jsb3guc29mLW1idS5lbmcudm13YXJlLmNvbTANBgkqhkiG9w0BAQUF\nAAOCAQEAXFPIh00VI55Sdfx+czbBb4rJz3c1xgN7pbV46K0nGI8S6ufAQPgLvZJ6\ng2T/mpo0FTuWCz1IE9PC28276vwv+xJZQwQyoUq4lhT6At84NWN+ZdLEe+aBAq+Y\nxUcIWzcKv8WdnlS5DRQxnw6pQCBdisnaFoEIzngQV8oYeIemW4Hcmb//yeykbZKJ\n0GTtK5Pud+kCkYmMHpmhH21q+3aRIcdzOYIoXhdzmIKG0Och97HthqpvRfOeWQ/A\nPDbxqQ2R/3D0gt9jWPCG7c0lB8Ynl24jLBB0RhY6mBrYpFbtXBQSEciUDRJVB2zL\nV8nJiMdhj+Q+ZmtSwhNRvi2qvWAUJQ==\n-----END CERTIFICATE-----\n"""
|
||||||
|
},
|
||||||
|
"authCredentialsLink": "/core/auth/credentials/13c9cbade08950755898c4b89c4a0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
from unittest import TestCase
|
||||||
|
from unittest.mock import MagicMock
|
||||||
|
from unittest.mock import Mock
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
context = MagicMock()
|
||||||
|
auth_credentials = {"status": 200, "content": "{\"privateKeyId\": \"admin\", \"privateKey\": \"VMware1!\"}"}
|
||||||
|
subnet_ranges = {"status": 200, "content": "{\"totalCount\": 1, \"documents\": {\"/resources/subnet-ranges/c19bd2921af950755777fd33fe060\": {\"domain\": \"test.local\"}}}"}
|
||||||
|
context.request.side_effect = [auth_credentials, auth_credentials, subnet_ranges, subnet_ranges]
|
||||||
|
|
||||||
|
print(handler(context, input))
|
78
venv_tango/bin/activate
Normal file
78
venv_tango/bin/activate
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
# This file must be used with "source bin/activate" *from bash*
|
||||||
|
# you cannot run it directly
|
||||||
|
|
||||||
|
deactivate () {
|
||||||
|
unset -f pydoc >/dev/null 2>&1
|
||||||
|
|
||||||
|
# reset old environment variables
|
||||||
|
# ! [ -z ${VAR+_} ] returns true if VAR is declared at all
|
||||||
|
if ! [ -z "${_OLD_VIRTUAL_PATH+_}" ] ; then
|
||||||
|
PATH="$_OLD_VIRTUAL_PATH"
|
||||||
|
export PATH
|
||||||
|
unset _OLD_VIRTUAL_PATH
|
||||||
|
fi
|
||||||
|
if ! [ -z "${_OLD_VIRTUAL_PYTHONHOME+_}" ] ; then
|
||||||
|
PYTHONHOME="$_OLD_VIRTUAL_PYTHONHOME"
|
||||||
|
export PYTHONHOME
|
||||||
|
unset _OLD_VIRTUAL_PYTHONHOME
|
||||||
|
fi
|
||||||
|
|
||||||
|
# This should detect bash and zsh, which have a hash command that must
|
||||||
|
# be called to get it to forget past commands. Without forgetting
|
||||||
|
# past commands the $PATH changes we made may not be respected
|
||||||
|
if [ -n "${BASH-}" ] || [ -n "${ZSH_VERSION-}" ] ; then
|
||||||
|
hash -r 2>/dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! [ -z "${_OLD_VIRTUAL_PS1+_}" ] ; then
|
||||||
|
PS1="$_OLD_VIRTUAL_PS1"
|
||||||
|
export PS1
|
||||||
|
unset _OLD_VIRTUAL_PS1
|
||||||
|
fi
|
||||||
|
|
||||||
|
unset VIRTUAL_ENV
|
||||||
|
if [ ! "${1-}" = "nondestructive" ] ; then
|
||||||
|
# Self destruct!
|
||||||
|
unset -f deactivate
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# unset irrelevant variables
|
||||||
|
deactivate nondestructive
|
||||||
|
|
||||||
|
VIRTUAL_ENV="/home/jbowdre/projects/tango-ipam-sdk/venv_tango"
|
||||||
|
export VIRTUAL_ENV
|
||||||
|
|
||||||
|
_OLD_VIRTUAL_PATH="$PATH"
|
||||||
|
PATH="$VIRTUAL_ENV/bin:$PATH"
|
||||||
|
export PATH
|
||||||
|
|
||||||
|
# unset PYTHONHOME if set
|
||||||
|
if ! [ -z "${PYTHONHOME+_}" ] ; then
|
||||||
|
_OLD_VIRTUAL_PYTHONHOME="$PYTHONHOME"
|
||||||
|
unset PYTHONHOME
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT-}" ] ; then
|
||||||
|
_OLD_VIRTUAL_PS1="$PS1"
|
||||||
|
if [ "x" != x ] ; then
|
||||||
|
PS1="$PS1"
|
||||||
|
else
|
||||||
|
PS1="(`basename \"$VIRTUAL_ENV\"`) $PS1"
|
||||||
|
fi
|
||||||
|
export PS1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Make sure to unalias pydoc if it's already there
|
||||||
|
alias pydoc 2>/dev/null >/dev/null && unalias pydoc
|
||||||
|
|
||||||
|
pydoc () {
|
||||||
|
python -m pydoc "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
# This should detect bash and zsh, which have a hash command that must
|
||||||
|
# be called to get it to forget past commands. Without forgetting
|
||||||
|
# past commands the $PATH changes we made may not be respected
|
||||||
|
if [ -n "${BASH-}" ] || [ -n "${ZSH_VERSION-}" ] ; then
|
||||||
|
hash -r 2>/dev/null
|
||||||
|
fi
|
36
venv_tango/bin/activate.csh
Normal file
36
venv_tango/bin/activate.csh
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
# This file must be used with "source bin/activate.csh" *from csh*.
|
||||||
|
# You cannot run it directly.
|
||||||
|
# Created by Davide Di Blasi <davidedb@gmail.com>.
|
||||||
|
|
||||||
|
alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; test "\!:*" != "nondestructive" && unalias deactivate && unalias pydoc'
|
||||||
|
|
||||||
|
# Unset irrelevant variables.
|
||||||
|
deactivate nondestructive
|
||||||
|
|
||||||
|
setenv VIRTUAL_ENV "/home/jbowdre/projects/tango-ipam-sdk/venv_tango"
|
||||||
|
|
||||||
|
set _OLD_VIRTUAL_PATH="$PATH"
|
||||||
|
setenv PATH "$VIRTUAL_ENV/bin:$PATH"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if ("" != "") then
|
||||||
|
set env_name = ""
|
||||||
|
else
|
||||||
|
set env_name = `basename "$VIRTUAL_ENV"`
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Could be in a non-interactive environment,
|
||||||
|
# in which case, $prompt is undefined and we wouldn't
|
||||||
|
# care about the prompt anyway.
|
||||||
|
if ( $?prompt ) then
|
||||||
|
set _OLD_VIRTUAL_PROMPT="$prompt"
|
||||||
|
set prompt = "[$env_name] $prompt"
|
||||||
|
endif
|
||||||
|
|
||||||
|
unset env_name
|
||||||
|
|
||||||
|
alias pydoc python -m pydoc
|
||||||
|
|
||||||
|
rehash
|
||||||
|
|
76
venv_tango/bin/activate.fish
Normal file
76
venv_tango/bin/activate.fish
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
# This file must be used using `. bin/activate.fish` *within a running fish ( http://fishshell.com ) session*.
|
||||||
|
# Do not run it directly.
|
||||||
|
|
||||||
|
function deactivate -d 'Exit virtualenv mode and return to the normal environment.'
|
||||||
|
# reset old environment variables
|
||||||
|
if test -n "$_OLD_VIRTUAL_PATH"
|
||||||
|
set -gx PATH $_OLD_VIRTUAL_PATH
|
||||||
|
set -e _OLD_VIRTUAL_PATH
|
||||||
|
end
|
||||||
|
|
||||||
|
if test -n "$_OLD_VIRTUAL_PYTHONHOME"
|
||||||
|
set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME
|
||||||
|
set -e _OLD_VIRTUAL_PYTHONHOME
|
||||||
|
end
|
||||||
|
|
||||||
|
if test -n "$_OLD_FISH_PROMPT_OVERRIDE"
|
||||||
|
# Set an empty local `$fish_function_path` to allow the removal of `fish_prompt` using `functions -e`.
|
||||||
|
set -l fish_function_path
|
||||||
|
|
||||||
|
# Erase virtualenv's `fish_prompt` and restore the original.
|
||||||
|
functions -e fish_prompt
|
||||||
|
functions -c _old_fish_prompt fish_prompt
|
||||||
|
functions -e _old_fish_prompt
|
||||||
|
set -e _OLD_FISH_PROMPT_OVERRIDE
|
||||||
|
end
|
||||||
|
|
||||||
|
set -e VIRTUAL_ENV
|
||||||
|
|
||||||
|
if test "$argv[1]" != 'nondestructive'
|
||||||
|
# Self-destruct!
|
||||||
|
functions -e pydoc
|
||||||
|
functions -e deactivate
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Unset irrelevant variables.
|
||||||
|
deactivate nondestructive
|
||||||
|
|
||||||
|
set -gx VIRTUAL_ENV "/home/jbowdre/projects/tango-ipam-sdk/venv_tango"
|
||||||
|
|
||||||
|
set -gx _OLD_VIRTUAL_PATH $PATH
|
||||||
|
set -gx PATH "$VIRTUAL_ENV/bin" $PATH
|
||||||
|
|
||||||
|
# Unset `$PYTHONHOME` if set.
|
||||||
|
if set -q PYTHONHOME
|
||||||
|
set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME
|
||||||
|
set -e PYTHONHOME
|
||||||
|
end
|
||||||
|
|
||||||
|
function pydoc
|
||||||
|
python -m pydoc $argv
|
||||||
|
end
|
||||||
|
|
||||||
|
if test -z "$VIRTUAL_ENV_DISABLE_PROMPT"
|
||||||
|
# Copy the current `fish_prompt` function as `_old_fish_prompt`.
|
||||||
|
functions -c fish_prompt _old_fish_prompt
|
||||||
|
|
||||||
|
function fish_prompt
|
||||||
|
# Save the current $status, for fish_prompts that display it.
|
||||||
|
set -l old_status $status
|
||||||
|
|
||||||
|
# Prompt override provided?
|
||||||
|
# If not, just prepend the environment name.
|
||||||
|
if test -n ""
|
||||||
|
printf '%s%s' "" (set_color normal)
|
||||||
|
else
|
||||||
|
printf '%s(%s) ' (set_color normal) (basename "$VIRTUAL_ENV")
|
||||||
|
end
|
||||||
|
|
||||||
|
# Restore the original $status
|
||||||
|
echo "exit $old_status" | source
|
||||||
|
_old_fish_prompt
|
||||||
|
end
|
||||||
|
|
||||||
|
set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV"
|
||||||
|
end
|
34
venv_tango/bin/activate_this.py
Normal file
34
venv_tango/bin/activate_this.py
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
"""By using execfile(this_file, dict(__file__=this_file)) you will
|
||||||
|
activate this virtualenv environment.
|
||||||
|
|
||||||
|
This can be used when you must use an existing Python interpreter, not
|
||||||
|
the virtualenv bin/python
|
||||||
|
"""
|
||||||
|
|
||||||
|
try:
|
||||||
|
__file__
|
||||||
|
except NameError:
|
||||||
|
raise AssertionError(
|
||||||
|
"You must run this like execfile('path/to/activate_this.py', dict(__file__='path/to/activate_this.py'))")
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
|
old_os_path = os.environ.get('PATH', '')
|
||||||
|
os.environ['PATH'] = os.path.dirname(os.path.abspath(__file__)) + os.pathsep + old_os_path
|
||||||
|
base = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
if sys.platform == 'win32':
|
||||||
|
site_packages = os.path.join(base, 'Lib', 'site-packages')
|
||||||
|
else:
|
||||||
|
site_packages = os.path.join(base, 'lib', 'python%s' % sys.version[:3], 'site-packages')
|
||||||
|
prev_sys_path = list(sys.path)
|
||||||
|
import site
|
||||||
|
site.addsitedir(site_packages)
|
||||||
|
sys.real_prefix = sys.prefix
|
||||||
|
sys.prefix = base
|
||||||
|
# Move the added items to the front of the path:
|
||||||
|
new_sys_path = []
|
||||||
|
for item in list(sys.path):
|
||||||
|
if item not in prev_sys_path:
|
||||||
|
new_sys_path.append(item)
|
||||||
|
sys.path.remove(item)
|
||||||
|
sys.path[:0] = new_sys_path
|
8
venv_tango/bin/chardetect
Executable file
8
venv_tango/bin/chardetect
Executable file
|
@ -0,0 +1,8 @@
|
||||||
|
#!/home/jbowdre/projects/tango-ipam-sdk/venv_tango/bin/python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from chardet.cli.chardetect import main
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||||
|
sys.exit(main())
|
10
venv_tango/bin/easy_install
Executable file
10
venv_tango/bin/easy_install
Executable file
|
@ -0,0 +1,10 @@
|
||||||
|
#!/home/jbowdre/projects/tango-ipam-sdk/venv_tango/bin/python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from setuptools.command.easy_install import main
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
|
||||||
|
sys.exit(main())
|
10
venv_tango/bin/easy_install-3.7
Executable file
10
venv_tango/bin/easy_install-3.7
Executable file
|
@ -0,0 +1,10 @@
|
||||||
|
#!/home/jbowdre/projects/tango-ipam-sdk/venv_tango/bin/python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from setuptools.command.easy_install import main
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
|
||||||
|
sys.exit(main())
|
10
venv_tango/bin/pip
Executable file
10
venv_tango/bin/pip
Executable file
|
@ -0,0 +1,10 @@
|
||||||
|
#!/home/jbowdre/projects/tango-ipam-sdk/venv_tango/bin/python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from pip._internal.cli.main import main
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
|
||||||
|
sys.exit(main())
|
10
venv_tango/bin/pip3
Executable file
10
venv_tango/bin/pip3
Executable file
|
@ -0,0 +1,10 @@
|
||||||
|
#!/home/jbowdre/projects/tango-ipam-sdk/venv_tango/bin/python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from pip._internal.cli.main import main
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
|
||||||
|
sys.exit(main())
|
10
venv_tango/bin/pip3.7
Executable file
10
venv_tango/bin/pip3.7
Executable file
|
@ -0,0 +1,10 @@
|
||||||
|
#!/home/jbowdre/projects/tango-ipam-sdk/venv_tango/bin/python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from pip._internal.cli.main import main
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
|
||||||
|
sys.exit(main())
|
1
venv_tango/bin/python
Symbolic link
1
venv_tango/bin/python
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
python3
|
78
venv_tango/bin/python-config
Executable file
78
venv_tango/bin/python-config
Executable file
|
@ -0,0 +1,78 @@
|
||||||
|
#!/home/jbowdre/projects/tango-ipam-sdk/venv_tango/bin/python
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import getopt
|
||||||
|
import sysconfig
|
||||||
|
|
||||||
|
valid_opts = ['prefix', 'exec-prefix', 'includes', 'libs', 'cflags',
|
||||||
|
'ldflags', 'help']
|
||||||
|
|
||||||
|
if sys.version_info >= (3, 2):
|
||||||
|
valid_opts.insert(-1, 'extension-suffix')
|
||||||
|
valid_opts.append('abiflags')
|
||||||
|
if sys.version_info >= (3, 3):
|
||||||
|
valid_opts.append('configdir')
|
||||||
|
|
||||||
|
|
||||||
|
def exit_with_usage(code=1):
|
||||||
|
sys.stderr.write("Usage: {0} [{1}]\n".format(
|
||||||
|
sys.argv[0], '|'.join('--'+opt for opt in valid_opts)))
|
||||||
|
sys.exit(code)
|
||||||
|
|
||||||
|
try:
|
||||||
|
opts, args = getopt.getopt(sys.argv[1:], '', valid_opts)
|
||||||
|
except getopt.error:
|
||||||
|
exit_with_usage()
|
||||||
|
|
||||||
|
if not opts:
|
||||||
|
exit_with_usage()
|
||||||
|
|
||||||
|
pyver = sysconfig.get_config_var('VERSION')
|
||||||
|
getvar = sysconfig.get_config_var
|
||||||
|
|
||||||
|
opt_flags = [flag for (flag, val) in opts]
|
||||||
|
|
||||||
|
if '--help' in opt_flags:
|
||||||
|
exit_with_usage(code=0)
|
||||||
|
|
||||||
|
for opt in opt_flags:
|
||||||
|
if opt == '--prefix':
|
||||||
|
print(sysconfig.get_config_var('prefix'))
|
||||||
|
|
||||||
|
elif opt == '--exec-prefix':
|
||||||
|
print(sysconfig.get_config_var('exec_prefix'))
|
||||||
|
|
||||||
|
elif opt in ('--includes', '--cflags'):
|
||||||
|
flags = ['-I' + sysconfig.get_path('include'),
|
||||||
|
'-I' + sysconfig.get_path('platinclude')]
|
||||||
|
if opt == '--cflags':
|
||||||
|
flags.extend(getvar('CFLAGS').split())
|
||||||
|
print(' '.join(flags))
|
||||||
|
|
||||||
|
elif opt in ('--libs', '--ldflags'):
|
||||||
|
abiflags = getattr(sys, 'abiflags', '')
|
||||||
|
libs = ['-lpython' + pyver + abiflags]
|
||||||
|
libs += getvar('LIBS').split()
|
||||||
|
libs += getvar('SYSLIBS').split()
|
||||||
|
# add the prefix/lib/pythonX.Y/config dir, but only if there is no
|
||||||
|
# shared library in prefix/lib/.
|
||||||
|
if opt == '--ldflags':
|
||||||
|
if not getvar('Py_ENABLE_SHARED'):
|
||||||
|
libs.insert(0, '-L' + getvar('LIBPL'))
|
||||||
|
if not getvar('PYTHONFRAMEWORK'):
|
||||||
|
libs.extend(getvar('LINKFORSHARED').split())
|
||||||
|
print(' '.join(libs))
|
||||||
|
|
||||||
|
elif opt == '--extension-suffix':
|
||||||
|
ext_suffix = sysconfig.get_config_var('EXT_SUFFIX')
|
||||||
|
if ext_suffix is None:
|
||||||
|
ext_suffix = sysconfig.get_config_var('SO')
|
||||||
|
print(ext_suffix)
|
||||||
|
|
||||||
|
elif opt == '--abiflags':
|
||||||
|
if not getattr(sys, 'abiflags', None):
|
||||||
|
exit_with_usage()
|
||||||
|
print(sys.abiflags)
|
||||||
|
|
||||||
|
elif opt == '--configdir':
|
||||||
|
print(sysconfig.get_config_var('LIBPL'))
|
BIN
venv_tango/bin/python3
Executable file
BIN
venv_tango/bin/python3
Executable file
Binary file not shown.
1
venv_tango/bin/python3.7
Symbolic link
1
venv_tango/bin/python3.7
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
python3
|
10
venv_tango/bin/wheel
Executable file
10
venv_tango/bin/wheel
Executable file
|
@ -0,0 +1,10 @@
|
||||||
|
#!/home/jbowdre/projects/tango-ipam-sdk/venv_tango/bin/python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from wheel.cli import main
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
|
||||||
|
sys.exit(main())
|
1
venv_tango/lib/python3.7/__future__.py
Symbolic link
1
venv_tango/lib/python3.7/__future__.py
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
/usr/lib/python3.7/__future__.py
|
BIN
venv_tango/lib/python3.7/__pycache__/__future__.cpython-37.pyc
Normal file
BIN
venv_tango/lib/python3.7/__pycache__/__future__.cpython-37.pyc
Normal file
Binary file not shown.
BIN
venv_tango/lib/python3.7/__pycache__/_bootlocale.cpython-37.pyc
Normal file
BIN
venv_tango/lib/python3.7/__pycache__/_bootlocale.cpython-37.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
venv_tango/lib/python3.7/__pycache__/_weakrefset.cpython-37.pyc
Normal file
BIN
venv_tango/lib/python3.7/__pycache__/_weakrefset.cpython-37.pyc
Normal file
Binary file not shown.
BIN
venv_tango/lib/python3.7/__pycache__/abc.cpython-37.pyc
Normal file
BIN
venv_tango/lib/python3.7/__pycache__/abc.cpython-37.pyc
Normal file
Binary file not shown.
BIN
venv_tango/lib/python3.7/__pycache__/base64.cpython-37.pyc
Normal file
BIN
venv_tango/lib/python3.7/__pycache__/base64.cpython-37.pyc
Normal file
Binary file not shown.
BIN
venv_tango/lib/python3.7/__pycache__/bisect.cpython-37.pyc
Normal file
BIN
venv_tango/lib/python3.7/__pycache__/bisect.cpython-37.pyc
Normal file
Binary file not shown.
BIN
venv_tango/lib/python3.7/__pycache__/codecs.cpython-37.pyc
Normal file
BIN
venv_tango/lib/python3.7/__pycache__/codecs.cpython-37.pyc
Normal file
Binary file not shown.
BIN
venv_tango/lib/python3.7/__pycache__/copy.cpython-37.pyc
Normal file
BIN
venv_tango/lib/python3.7/__pycache__/copy.cpython-37.pyc
Normal file
Binary file not shown.
BIN
venv_tango/lib/python3.7/__pycache__/copyreg.cpython-37.pyc
Normal file
BIN
venv_tango/lib/python3.7/__pycache__/copyreg.cpython-37.pyc
Normal file
Binary file not shown.
BIN
venv_tango/lib/python3.7/__pycache__/enum.cpython-37.pyc
Normal file
BIN
venv_tango/lib/python3.7/__pycache__/enum.cpython-37.pyc
Normal file
Binary file not shown.
BIN
venv_tango/lib/python3.7/__pycache__/fnmatch.cpython-37.pyc
Normal file
BIN
venv_tango/lib/python3.7/__pycache__/fnmatch.cpython-37.pyc
Normal file
Binary file not shown.
BIN
venv_tango/lib/python3.7/__pycache__/functools.cpython-37.pyc
Normal file
BIN
venv_tango/lib/python3.7/__pycache__/functools.cpython-37.pyc
Normal file
Binary file not shown.
BIN
venv_tango/lib/python3.7/__pycache__/genericpath.cpython-37.pyc
Normal file
BIN
venv_tango/lib/python3.7/__pycache__/genericpath.cpython-37.pyc
Normal file
Binary file not shown.
BIN
venv_tango/lib/python3.7/__pycache__/hashlib.cpython-37.pyc
Normal file
BIN
venv_tango/lib/python3.7/__pycache__/hashlib.cpython-37.pyc
Normal file
Binary file not shown.
BIN
venv_tango/lib/python3.7/__pycache__/heapq.cpython-37.pyc
Normal file
BIN
venv_tango/lib/python3.7/__pycache__/heapq.cpython-37.pyc
Normal file
Binary file not shown.
BIN
venv_tango/lib/python3.7/__pycache__/hmac.cpython-37.pyc
Normal file
BIN
venv_tango/lib/python3.7/__pycache__/hmac.cpython-37.pyc
Normal file
Binary file not shown.
BIN
venv_tango/lib/python3.7/__pycache__/imp.cpython-37.pyc
Normal file
BIN
venv_tango/lib/python3.7/__pycache__/imp.cpython-37.pyc
Normal file
Binary file not shown.
BIN
venv_tango/lib/python3.7/__pycache__/io.cpython-37.pyc
Normal file
BIN
venv_tango/lib/python3.7/__pycache__/io.cpython-37.pyc
Normal file
Binary file not shown.
BIN
venv_tango/lib/python3.7/__pycache__/keyword.cpython-37.pyc
Normal file
BIN
venv_tango/lib/python3.7/__pycache__/keyword.cpython-37.pyc
Normal file
Binary file not shown.
BIN
venv_tango/lib/python3.7/__pycache__/linecache.cpython-37.pyc
Normal file
BIN
venv_tango/lib/python3.7/__pycache__/linecache.cpython-37.pyc
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue