├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Dockerfile ├── LICENSE.txt ├── NOTICE.txt ├── README.md ├── README.pdf ├── config.ini.example ├── docs ├── 1-csp_help.txt ├── 10-dfw_help.txt ├── 11-nsxaf_help.txt ├── 12-inventory_help.txt ├── 13-system_help.txt ├── 14-search-nsx_help.txt ├── 15-vcdr_help.txt ├── 16-flexcompute_help.txt ├── 2-sddc_help.txt ├── 3-tkg_help.txt ├── 4-segment_help.txt ├── 5-vpn_help.txt ├── 6-nat_help.txt ├── 7-t1_help.txt ├── 8-vtc_help.txt ├── 9-gwfw_help.txt ├── all-supported-commands.md ├── all-supported-commands.pdf ├── images │ ├── argparse_structure.png │ └── pyvmc_refactor.png ├── pyvmc-structure.md └── release-notes.md ├── import └── aws.json ├── json └── rbvpn-prefix-list.json.sample.json ├── pyVMC.py ├── pyvmc_csp.py ├── pyvmc_flexcomp.py ├── pyvmc_fxns.py ├── pyvmc_nsx.py ├── pyvmc_vcdr.py ├── pyvmc_vmc.py └── requirements.txt /.gitignore: -------------------------------------------------------------------------------- 1 | config.ini 2 | __pycache__ 3 | .DS_Store 4 | .idea 5 | *.code-workspace 6 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Contributor Covenant Code of Conduct 4 | 5 | ## Our Pledge 6 | 7 | In the interest of fostering an open and welcoming environment, we as 8 | contributors and maintainers pledge to making participation in python-client-for-vmware-cloud-on-aws project and 9 | our community a harassment-free experience for everyone, regardless of age, body 10 | size, disability, ethnicity, sex characteristics, gender identity and expression, 11 | level of experience, education, socio-economic status, nationality, personal 12 | appearance, race, religion, or sexual identity and orientation. 13 | 14 | ## Our Standards 15 | 16 | Examples of behavior that contributes to creating a positive environment 17 | include: 18 | 19 | * Using welcoming and inclusive language 20 | * Being respectful of differing viewpoints and experiences 21 | * Gracefully accepting constructive criticism 22 | * Focusing on what is best for the community 23 | * Showing empathy towards other community members 24 | 25 | Examples of unacceptable behavior by participants include: 26 | 27 | * The use of sexualized language or imagery and unwelcome sexual attention or 28 | advances 29 | * Trolling, insulting/derogatory comments, and personal or political attacks 30 | * Public or private harassment 31 | * Publishing others' private information, such as a physical or electronic 32 | address, without explicit permission 33 | * Other conduct which could reasonably be considered inappropriate in a 34 | professional setting 35 | 36 | ## Our Responsibilities 37 | 38 | Project maintainers are responsible for clarifying the standards of acceptable 39 | behavior and are expected to take appropriate and fair corrective action in 40 | response to any instances of unacceptable behavior. 41 | 42 | Project maintainers have the right and responsibility to remove, edit, or 43 | reject comments, commits, code, wiki edits, issues, and other contributions 44 | that are not aligned to this Code of Conduct, or to ban temporarily or 45 | permanently any contributor for other behaviors that they deem inappropriate, 46 | threatening, offensive, or harmful. 47 | 48 | ## Scope 49 | 50 | This Code of Conduct applies both within project spaces and in public spaces 51 | when an individual is representing the project or its community. Examples of 52 | representing a project or community include using an official project e-mail 53 | address, posting via an official social media account, or acting as an appointed 54 | representative at an online or offline event. Representation of a project may be 55 | further defined and clarified by project maintainers. 56 | 57 | ## Enforcement 58 | 59 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 60 | reported by contacting the project team at oss-coc@vmware.com. All 61 | complaints will be reviewed and investigated and will result in a response that 62 | is deemed necessary and appropriate to the circumstances. The project team is 63 | obligated to maintain confidentiality with regard to the reporter of an incident. 64 | Further details of specific enforcement policies may be posted separately. 65 | 66 | Project maintainers who do not follow or enforce the Code of Conduct in good 67 | faith may face temporary or permanent repercussions as determined by other 68 | members of the project's leadership. 69 | 70 | ## Attribution 71 | 72 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 73 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 74 | 75 | [homepage]: https://www.contributor-covenant.org 76 | 77 | For answers to common questions about this code of conduct, see 78 | https://www.contributor-covenant.org/faq 79 | 80 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Contributing to python-client-for-vmware-cloud-on-aws 4 | 5 | The python-client-for-vmware-cloud-on-aws project team welcomes contributions from the community. Before you start working with python-client-for-vmware-cloud-on-aws, please 6 | read our [Developer Certificate of Origin](https://cla.vmware.com/dco). All contributions to this repository must be 7 | signed as described on that page. Your signature certifies that you wrote the patch or have the right to pass it on 8 | as an open-source patch. 9 | 10 | ## Contribution Flow 11 | 12 | This is a rough outline of what a contributor's workflow looks like: 13 | 14 | - Create a topic branch from where you want to base your work 15 | - Make commits of logical units 16 | - Make sure your commit messages are in the proper format (see below) 17 | - Push your changes to a topic branch in your fork of the repository 18 | - Submit a pull request 19 | 20 | Example: 21 | 22 | ``` shell 23 | git remote add upstream https://github.com/vmware/python-client-for-vmware-cloud-on-aws.git 24 | git checkout -b my-new-feature master 25 | git commit -a 26 | git push origin my-new-feature 27 | ``` 28 | 29 | ### Staying In Sync With Upstream 30 | 31 | When your branch gets out of sync with the vmware/master branch, use the following to update: 32 | 33 | ``` shell 34 | git checkout my-new-feature 35 | git fetch -a 36 | git pull --rebase upstream master 37 | git push --force-with-lease origin my-new-feature 38 | ``` 39 | 40 | ### Updating pull requests 41 | 42 | If your PR fails to pass CI or needs changes based on code review, you'll most likely want to squash these changes into 43 | existing commits. 44 | 45 | If your pull request contains a single commit or your changes are related to the most recent commit, you can simply 46 | amend the commit. 47 | 48 | ``` shell 49 | git add . 50 | git commit --amend 51 | git push --force-with-lease origin my-new-feature 52 | ``` 53 | 54 | If you need to squash changes into an earlier commit, you can use: 55 | 56 | ``` shell 57 | git add . 58 | git commit --fixup 59 | git rebase -i --autosquash master 60 | git push --force-with-lease origin my-new-feature 61 | ``` 62 | 63 | Be sure to add a comment to the PR indicating your new changes are ready to review, as GitHub does not generate a 64 | notification when you git push. 65 | 66 | ### Code Style 67 | 68 | ### Formatting Commit Messages 69 | 70 | We follow the conventions on [How to Write a Git Commit Message](http://chris.beams.io/posts/git-commit/). 71 | 72 | Be sure to include any related GitHub issue references in the commit message. See 73 | [GFM syntax](https://guides.github.com/features/mastering-markdown/#GitHub-flavored-markdown) for referencing issues 74 | and commits. 75 | 76 | ## Reporting Bugs and Creating Issues 77 | 78 | When opening a new issue, try to roughly follow the commit message format conventions above. 79 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.11.4-alpine 2 | 3 | COPY . /app 4 | 5 | WORKDIR /app 6 | 7 | RUN pip install -r requirements.txt 8 | RUN apk add --no-cache bash 9 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Python Client for VMware Cloud on AWS 2 | Copyright (c) 2020 VMware, Inc. All rights reserved 3 | 4 | The BSD-2 license (the "License") set forth below applies to all parts of the Python Client for VMware Cloud on AWS project. You may not use this file except in compliance with the License. 5 | 6 | BSD-2 License 7 | 8 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 9 | 10 | Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 11 | 12 | Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /NOTICE.txt: -------------------------------------------------------------------------------- 1 | Python Client for VMware Cloud on AWS 2 | Copyright (c) 2020 VMware, Inc. All Rights Reserved. 3 | 4 | This product is licensed to you under the BSD-2 license (the "License"). You may not use this product except in compliance with the BSD-2 License. 5 | 6 | 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. 7 | 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Python Client For VMware Cloud on AWS 2 | ## Table of Contents 3 | 4 | 5 | - [1. Whats is pyVMC](#what-is-pyvmc) 6 | - [2. Overview](#overview) 7 | - [3. Getting Started](#getting-started) 8 | - [3.1 Install Python](#install-python) 9 | - [3.2 Download code](#download-code) 10 | - [3.3 Install Python modules and packages](#install-python-modules-and-packages) 11 | - [3.4 Update config.ini](#update-configini) 12 | - [4. Running the Script](#running-the-script) 13 | - [5. Authentication](#authentication) 14 | - [6. Support](#support) 15 | - [7. Documentation](#documentation) 16 | - [8. Release Notes](#release-notes) 17 | - [9. Known Issues](#known-issues) 18 | - [10. Contributing](#contributing) 19 | - [11. License](#license) 20 | 21 | ## What is pyVMC? 22 | Welcome to the Python Client for VMware Cloud on AWS! PyVMC is a Python tool developed for assisting system administrators with the deployment, configuration, and management of the VMware Cloud on AWS service. 23 | 24 | ## Overview 25 | 26 | pyVMC was created by Nicolas Vibert and Matt Dreyer. While it started as a series of a few commands used for creating some network and firewall rules, it has grown to become a fairly comprehensive CLI that can be used for anything from adding users to your VMware Cloud organization, viewing and manipulating the route tables associated with your SDDC, configuring and updating IDS rules, or even enabling and monitoring services like Tanzu Kubernetes Service or VMware Cloud DR. 27 | 28 | Over time, pyVMC has grown it its capabilities, in the number of commands it supports and ultimately in its complexity. Functionality has been separated amongst several files to make navigating and updating the code easier - however this may make understanding how the project is put together a bit more challenging to understand. 29 | 30 | As mentioned above, the functionality of the project is split up into multiple files.... 31 | 32 | ![pyvmc structure](docs/images/pyvmc_refactor.png) 33 | 34 | Everything begins with... 35 | 36 | **pyVMC.py** is the file where _main_ is defined, where the commands and arguments are defined for controlling user input, and where the 'business logic'/ functions are housed for handling user input and ultimately returning a result back to the screen. 37 | 38 | A great deal of work has gone into incorporating python argparse into the project for defining and handling commands and arguments in the CLI - so the first thing you should do before adding / updating a command or function for the project is think through how the user your new functionality: 39 | - Are you simply adding new functionality to a command that already exists? 40 | - Are you instead adding a new command for an existing feature? 41 | - Are you adding new commands for an entirely new API? 42 | 43 | The answers to the questions above will ultimately help determine if you are adding a new category of commands ("super-command"), a new sub-command under a super-command that already exists, or just a new option for an existing subcommand. 44 | 45 | See the image below for a graphical representation of how argparse is being used to structure commands in a hierarchical fashion. 46 | 47 | ![argparse structure](docs/images/argparse_structure.png) 48 | 49 | ## Getting Started 50 | 51 | ### Install Python 52 | This tool is dependent on Python3, you can find installation instructions for your operating system in the Python documentation (https://wiki.python.org/moin/BeginnersGuide/Download). 53 | 54 | ### Download code 55 | Download the [pyVMC.zip](https://flings.vmware.com/python-client-for-vmc-on-aws) from the Flings site 56 | 57 | If you know git, clone the repo with 58 | 59 | ```git clone https://github.com/vmware/python-client-for-vmware-cloud-on-aws.git ``` 60 | 61 | ### Install Python modules and packages 62 | When you navigate to the python-client-for-vmware-cloud-on-aws folder, you will find a requirements.txt file that lists all your Python packages. They can all be installed by running the following command on Linux/Mac: 63 | 64 | ```pip3 install -r requirements.txt``` 65 | 66 | On Windows, use 67 | 68 | ```python -m pip install -r requirements.txt``` 69 | 70 | ### Update config.ini 71 | Obtain a refresh token from the VMware Cloud Service Portal, as well as the ORG ID and SDDC ID of the environment you wish to interact with . Copy config.ini.example to config.ini and edit the config.ini with your own SDDC ID, Organization (Org) ID and your access token. 72 | 73 | > Note: The token must be scoped as either `Org Member` or `Org Owner`. It must be given the VMware Cloud on AWS roles of `NSX Cloud Admin` and `Administrator`. API calls with a role of `Administrator (Delete Restricted)` do not work. If you are using the VCDR components of PyVMC, the token must also have a role with full administrative rights to VCDR. 74 | 75 | ### Do I need to know Python? 76 | No! You can simply use it to consume and manage your VMware Cloud on AWS SDDC (Software-Defined Data Center). 77 | 78 | ## Running the Script 79 | This is super easy... 80 | - run ./pyVMC.py to see the current list of supported commands. 81 | - use '-h' with any super-command or with any subcommand to see the supported arguments / parameters. 82 | 83 | 84 | For example, to see the supported sub-commands for the 'system' super-command: 85 | ```./pyVMC.py system -h ``` 86 | 87 | To see the arguments for the show-routes command: 88 | ``` ./pyVMC.py system show-routes -h ``` 89 | 90 | Try to view the route table for your SDDC: 91 | ``` ./pyVMC.py system show-routes -rt t0 ``` 92 | 93 | ## Authentication 94 | pyVMC supports both **refresh_token** and **OAuth AppId/Secret** way to authenticate. 95 | Values for it needs to be specified in config.ini file. Default auth method is to use **refresh_token**. 96 | 97 | If one wants to use OAuth, then **--oauth** switch needs to be provided when running the command. 98 | 99 | Examples: 100 | 101 | Using default 'refresh_token' 102 | ```shell 103 | ./pyVMC.py sddc show-sddcs 104 | ``` 105 | 106 | Using OAuth 107 | ```shell 108 | ./pyVMC.py sddc show-sddcs --oauth 109 | ``` 110 | 111 | ## Support 112 | 113 | ### Is it officially supported by VMware? 114 | Sorry but no, this is a community-based effort. Use it at your own risk. It has extensively been tested though and we'll endeavour to fix any bugs. 115 | 116 | ### Which version of VMware Cloud on AWS has it been tested against? 117 | Versions 1.9, 1.10, 1.11, 1.12, 1.14... all the way up through 1.20. We don't guarantee support with previous versions. 118 | We will, however, endeavour to verify compatibility as we release new versions. 119 | 120 | ### What if I find a bug or need a new feature? 121 | Please raise it on GitHub and we will look into it. 122 | 123 | ## Documentation 124 | 125 | ### Where can I find documentation about VMware Cloud on AWS: 126 | Please check the online documentation: 127 | https://docs.vmware.com/en/VMware-Cloud-on-AWS/index.html 128 | 129 | ### Where can I find documentation about each pyVMC commands? 130 | 131 | #### Current Supported Commands 132 | Here are the currently supported 'super' commands: 133 | ```shell 134 | csp Commands related to the Cloud Service Portal itself. 135 | sddc Commands related to the Software Defined Datacenter (SDDC) itself. 136 | tkg Commands related to the Tanzu Kubernetes Service (TKG). 137 | segment Create, delete, update, and show Virtual Machine network segments. 138 | vpn Create, delete, update, and show virtual private network (VPN) settings. 139 | nat Show and update Network Address Translation (NAT) rules. 140 | t1 Create, delete, update, and show secondary T1 gateways. 141 | vtc Commands related to VMware Transit Connect (VTC). 142 | gwfw Show and update policies and rules associated with NSX Gateway Firewall (mgw, cgw, etc.). 143 | dfw Show and update policies and rules associated with NSX Distributed Firewall. 144 | nsxaf Commands related to the NSX Advanced Firewall - e.g. IDS. 145 | inventory Show and update objects in the NSX Inventory (groups, services, etc). 146 | system Show and update configuration data associated with the NSX-T System (DNS, public IP, etc). 147 | search-nsx Search the NSX Manager inventory. 148 | vcdr Create, delete, update, and show information about VMware Cloud Disaster Recovery. 149 | flexcomp Commands related to the Cloud Flex Compute itself. ([VMware Cloud Flex Compute](https://blogs.vmware.com/cloud/2022/08/30/announcing-vmware-cloud-flex-compute/) is currently in technical preview and any related functionality is subject to change until Cloud Flex Compute is made generally available in the future.) 150 | ``` 151 | 152 | #### Getting Help 153 | 154 | To see the supported commands for any given category / super-command, simply use '-h'... for example: 155 | 156 | ```shell 157 | ./pyVMC.py vcdr -h 158 | usage: vcdr [-h] {scfs,pg,snaps,rsddc,psite,vms} ... 159 | 160 | positional arguments: 161 | {scfs,pg,snaps,rsddc,psite,vms} 162 | vcdr sub-command help 163 | scfs VCDR cloud file system - use '-h' for help. 164 | pg VCDR Protection Groups - use '-h' for help. 165 | snaps VCDR Snapshots - use '-h' for help. 166 | rsddc VCDR Recovery SDDC - use '-h' for help. 167 | psite VCDR Protected Site - use '-h' for help. 168 | vms VCDR cloud file system - use '-h' for help. 169 | 170 | optional arguments: 171 | -h, --help show this help message and exit 172 | ``` 173 | 174 | Similarly, to see the options for any given command, run the individual command with the -h option: 175 | 176 | ```shell 177 | ./pyVMC.py vcdr scfs -h 178 | usage: vcdr scfs [-h] {show} ... 179 | 180 | positional arguments: 181 | {show} vcdr scfs sub-command help 182 | show Show information about the VCDR Scale-out file System(s). 183 | 184 | optional arguments: 185 | --oauth [OAUTH] Used to specify use of OAuth app ID and secret in config.ini instead of 'refresh_token' (default) 186 | -h, --help show this help message and exit 187 | ``` 188 | 189 | Check comprehensive listing of [all currently supported commands](/docs/all-supported-commands.md). 190 | 191 | ## Release Notes: 192 | 193 | [Please see the release notes found here.](docs/release-notes.md) 194 | 195 | ## Known Issues: 196 | 197 | [Please see the release notes found here.](docs/release-notes.md) 198 | 199 | ## Contributing 200 | 201 | For a quick overview of how the project is structured as well as how the files relate to each other, how the argparse module is being used, etc, [please refer to the pyvmc-structure.md](docs/pyvmc-structure.md). 202 | 203 | The python-client-for-vmware-cloud-on-aws project team welcomes contributions from the community. Before you start working with python-client-for-vmware-cloud-on-aws, please 204 | read our [Developer Certificate of Origin](https://cla.vmware.com/dco). All contributions to this repository must be 205 | signed as described on that page. Your signature certifies that you wrote the patch or have the right to pass it on 206 | as an open-source patch. For more detailed information, refer to [CONTRIBUTING.md](CONTRIBUTING.md). 207 | 208 | ## License 209 | 210 | SPDX-License-Identifier: BSD-2-Clause 211 | -------------------------------------------------------------------------------- /README.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vmware/python-client-for-vmware-cloud-on-aws/6b2375fad709c679817809883c28a2c08e0ff31c/README.pdf -------------------------------------------------------------------------------- /config.ini.example: -------------------------------------------------------------------------------- 1 | [vmcConfig] 2 | strProdURL = https://vmc.vmware.com 3 | strCSPProdURL = https://console.cloud.vmware.com 4 | strVCDRProdURL = https://vcdr-xxx-xxx-xxx-xxx.app.vcdr.vmware.com/ 5 | 6 | refresh_Token = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 7 | #OR 8 | oauth_clientId = xxxxxxxxxxxxxxxxxxxxxxxxxxxxx 9 | oauth_clientSecret = xxxxxxxxxxxxxxxxxxxxxxxxxxxxx 10 | 11 | org_id = xxxxxxxxxxxxxxxxxxxxxxxxxxxxx 12 | sddc_id = xxxxxxxxxxxxxxxxxxxxxxxxxxxxx -------------------------------------------------------------------------------- /docs/1-csp_help.txt: -------------------------------------------------------------------------------- 1 | usage: csp [-h] 2 | {show-csp-services,show-csp-service-roles,get-access-token,add-users-to-csp-group,show-csp-group-diff,show-csp-group-members,show-csp-groups,search-csp-org-users,find-csp-user-by-service-role,show-org-users} 3 | ... 4 | 5 | positional arguments: 6 | {show-csp-services,show-csp-service-roles,get-access-token,add-users-to-csp-group,show-csp-group-diff,show-csp-group-members,show-csp-groups,search-csp-org-users,find-csp-user-by-service-role,show-org-users} 7 | csp sub-command help 8 | show-csp-services Show the entitled services in the 9 | VMware Cloud Service Console. 10 | show-csp-service-roles Show the entitled service roles in the 11 | VMware Cloud Service Console. 12 | get-access-token show your access token 13 | add-users-to-csp-group CSP user to a group 14 | show-csp-group-diff this compares the roles in the 15 | specified group with every user in the 16 | org and prints out a user-by-user diff 17 | show-csp-group-members show CSP group members 18 | show-csp-groups To show CSP groups which contain 19 | GROUP_SEARCH_TERM string 20 | search-csp-org-users Search for users in the CSP or org. 21 | find-csp-user-by-service-role Search for CSP users with a specific 22 | service role. First use show-csp- 23 | service-roles to see entitled roles 24 | show-org-users Show all organization users 25 | 26 | optional arguments: 27 | -h, --help show this help message and exit 28 | -------------------------------------------------------------------------------- /docs/10-dfw_help.txt: -------------------------------------------------------------------------------- 1 | usage: dfw [-h] 2 | {new-dfw-rule,new-dfw-section,remove-dfw-rule,remove-dfw-section,show-dfw-section,show-dfw-section-rules} 3 | ... 4 | 5 | positional arguments: 6 | {new-dfw-rule,new-dfw-section,remove-dfw-rule,remove-dfw-section,show-dfw-section,show-dfw-section-rules} 7 | dfw sub-command help 8 | new-dfw-rule create a new DFW security rule 9 | new-dfw-section create a new DFW section 10 | remove-dfw-rule delete a DFW rule 11 | remove-dfw-section delete a DFW section 12 | show-dfw-section show the DFW sections 13 | show-dfw-section-rules 14 | show the DFW security rules within a section 15 | 16 | optional arguments: 17 | -h, --help show this help message and exit 18 | -------------------------------------------------------------------------------- /docs/11-nsxaf_help.txt: -------------------------------------------------------------------------------- 1 | usage: nsxaf [-h] 2 | {show-nsxaf-status,show-ids-cluster-status,enable-cluster-ids,disable-cluster-ids,enable-all-cluster-ids,disable-all-cluster-ids,enable-ids-auto-update,ids-update-signatures,show-ids-signature-versions,show-ids-profiles,search-product-affected,create-ids-profile,show-ids-policies,create-ids-policy,show-ids-rules,create-ids-rule} 3 | ... 4 | 5 | positional arguments: 6 | {show-nsxaf-status,show-ids-cluster-status,enable-cluster-ids,disable-cluster-ids,enable-all-cluster-ids,disable-all-cluster-ids,enable-ids-auto-update,ids-update-signatures,show-ids-signature-versions,show-ids-profiles,search-product-affected,create-ids-profile,show-ids-policies,create-ids-policy,show-ids-rules,create-ids-rule} 7 | nsxaf sub-command help 8 | show-nsxaf-status Display the status of the NSX Advanced 9 | Firewall Add-on 10 | show-ids-cluster-status Show IDS status for each cluster in 11 | the SDDC 12 | enable-cluster-ids Enable IDS on cluster 13 | disable-cluster-ids Disable IDS on cluster 14 | enable-all-cluster-ids Enable IDS on all clusters 15 | disable-all-cluster-ids Disable IDS on all clusters 16 | enable-ids-auto-update Enable IDS signature auto update 17 | ids-update-signatures Force update of IDS signatures 18 | show-ids-signature-versions Show downloaded signature versions 19 | show-ids-profiles Show all IDS profiles 20 | search-product-affected Search through the active IDS 21 | signature for specific product 22 | affected. Useful when building an IDS 23 | Profile 24 | create-ids-profile Create an IDS profile with either 25 | Product Affected, CVSS or both. 26 | show-ids-policies List all IDS policies 27 | create-ids-policy Create an IDS policy 28 | show-ids-rules List all IDS rules 29 | create-ids-rule Create an IDS rule using previously 30 | created IDS profile and inventory 31 | groups 32 | 33 | optional arguments: 34 | -h, --help show this help message and exit 35 | -------------------------------------------------------------------------------- /docs/12-inventory_help.txt: -------------------------------------------------------------------------------- 1 | usage: inventory [-h] 2 | {new-group,remove-group,show-group,show-group-association,new-service,remove-service,show-services} 3 | ... 4 | 5 | positional arguments: 6 | {new-group,remove-group,show-group,show-group-association,new-service,remove-service,show-services} 7 | inventory sub-command help 8 | new-group create a new group 9 | remove-group remove a group 10 | show-group show existing groups 11 | show-group-association 12 | show security rules used by a groups 13 | new-service create a new service 14 | remove-service remove a service 15 | show-services show services 16 | 17 | optional arguments: 18 | -h, --help show this help message and exit 19 | -------------------------------------------------------------------------------- /docs/13-system_help.txt: -------------------------------------------------------------------------------- 1 | usage: system [-h] 2 | {show-dns-services,show-dns-zones,new-sddc-public-ip,remove-sddc-public-ip,set-sddc-public-ip,show-sddc-public-ip,mtu,asn,dx-admin-cost,show-egress-interface-counters,show-routes} 3 | ... 4 | 5 | positional arguments: 6 | {show-dns-services,show-dns-zones,new-sddc-public-ip,remove-sddc-public-ip,set-sddc-public-ip,show-sddc-public-ip,mtu,asn,dx-admin-cost,show-egress-interface-counters,show-routes} 7 | system sub-command help 8 | show-dns-services Show currently configured DNS services 9 | show-dns-zones Show currently configured DNS zone services. 10 | new-sddc-public-ip request a new public IP 11 | remove-sddc-public-ip 12 | remove an existing public IP 13 | set-sddc-public-ip update the description of an existing public IP 14 | show-sddc-public-ip 15 | show the public IPs 16 | mtu Show and update configuration data associated with 17 | Maximum Transmission Unit value for the Intranet 18 | Interface. 19 | asn Show and update configuration data associated with 20 | Autonomous System Number value for the Intranet 21 | Interface. 22 | dx-admin-cost Use to view currently configured routing preference / 23 | admin cost - VPN or DX. 24 | show-egress-interface-counters 25 | show current Internet interface egress counters 26 | show-routes Show SDDC routes 27 | 28 | optional arguments: 29 | -h, --help show this help message and exit 30 | -------------------------------------------------------------------------------- /docs/14-search-nsx_help.txt: -------------------------------------------------------------------------------- 1 | usage: search-nsx [-h] [--nsxm [NSXM]] 2 | [-ot {BgpNeighborConfig,BgpRoutingConfig,Group,IdsSignature,PrefixList,RouteBasedIPSecVPNSession,Segment,Service,StaticRoute,Tier0,Tier1,VirtualMachine,VirtualNetworkInterface}] 3 | [-oid OBJECT_ID] 4 | 5 | optional arguments: 6 | -h, --help show this help message and exit 7 | --nsxm [NSXM] Used to specify NSX Manager instead of 8 | NSX proxy (Default). 9 | -ot {BgpNeighborConfig,BgpRoutingConfig,Group,IdsSignature,PrefixList,RouteBasedIPSecVPNSession,Segment,Service,StaticRoute,Tier0,Tier1,VirtualMachine,VirtualNetworkInterface}, --object_type {BgpNeighborConfig,BgpRoutingConfig,Group,IdsSignature,PrefixList,RouteBasedIPSecVPNSession,Segment,Service,StaticRoute,Tier0,Tier1,VirtualMachine,VirtualNetworkInterface} 10 | The type of object to search for. 11 | -oid OBJECT_ID, --object_id OBJECT_ID 12 | The name of the object you are 13 | searching for. 14 | -------------------------------------------------------------------------------- /docs/15-vcdr_help.txt: -------------------------------------------------------------------------------- 1 | usage: vcdr [-h] {scfs,pg,snaps,rsddc,psite,vms} ... 2 | 3 | positional arguments: 4 | {scfs,pg,snaps,rsddc,psite,vms} 5 | vcdr sub-command help 6 | scfs VCDR cloud file system - use '-h' for help. 7 | pg VCDR Protection Groups - use '-h' for help. 8 | snaps VCDR Snapshots - use '-h' for help. 9 | rsddc VCDR Recovery SDDC - use '-h' for help. 10 | psite VCDR Protected Site - use '-h' for help. 11 | vms VCDR cloud file system - use '-h' for help. 12 | 13 | optional arguments: 14 | -h, --help show this help message and exit 15 | -------------------------------------------------------------------------------- /docs/16-flexcompute_help.txt: -------------------------------------------------------------------------------- 1 | [VMware Cloud Flex Compute](https://blogs.vmware.com/cloud/2022/08/30/announcing-vmware-cloud-flex-compute/) is currently in technical preview and any related functionality is subject to change until Cloud Flex Compute is made generally available in the future. 2 | 3 | usage: flexcomp [-h] 4 | {activity-status,show-all-namespaces,validate-network,create-flexcompute,delete-flexcomp,show-flex-comp-regions,show-flex-comp-templates,show-all-vms,show-all-images,create-vm,power-operation,delete-vm} 5 | ... 6 | 7 | positional arguments: 8 | {activity-status,show-all-namespaces,validate-network,create-flexcompute,delete-flexcomp,show-flex-comp-regions,show-flex-comp-templates,show-all-vms,show-all-images,create-vm,power-operation,delete-vm} 9 | flexcomp sub-command help 10 | activity-status Get activity status of long running tasks 11 | show-all-namespaces Show all present Cloud Flex Compute Name Spaces 12 | validate-network Validate network CIDR before creating Cloud Flex Compute Name Space 13 | create-flexcompute Create new Cloud Flex Compute 14 | delete-flexcomp Delete existing Cloud Flex Compute 15 | show-flex-comp-regions Show available Cloud Flex Compute regions 16 | show-flex-comp-templates Show available Cloud Flex Compute resource templates to create Name Space 17 | show-all-vms Show all VMs in Cloud Flex Compute instance 18 | show-all-images Show all images available to create VMs from 19 | create-vm Create VM 20 | power-operation Perform Power Operations on VM 21 | delete-vm Delete VM. Make sure VM is in powerd OFF state. 22 | 23 | options: 24 | -h, --help -------------------------------------------------------------------------------- /docs/2-sddc_help.txt: -------------------------------------------------------------------------------- 1 | usage: sddc [-h] 2 | {show-compatible-subnets,show-connected-accounts,set-sddc-connected-services,show-sddc-connected-vpc,show-shadow-account,show-sddc-state,show-sddc-hosts,show-sddcs,show-vms} 3 | ... 4 | 5 | positional arguments: 6 | {show-compatible-subnets,show-connected-accounts,set-sddc-connected-services,show-sddc-connected-vpc,show-shadow-account,show-sddc-state,show-sddc-hosts,show-sddcs,show-vms} 7 | sddc sub-command help 8 | show-compatible-subnets show compatible native AWS subnets 9 | connected to the SDDC 10 | show-connected-accounts show native AWS accounts connected to 11 | the SDDC 12 | set-sddc-connected-services change whether to use S3 over the 13 | Internet(false) or via the ENI(true) 14 | show-sddc-connected-vpc show the VPC connected to the SDDC 15 | show-shadow-account show the Shadow AWS Account VMC is 16 | deployed in 17 | show-sddc-state get a view of your selected SDDC 18 | show-sddc-hosts display a list of the hosts in your 19 | SDDC 20 | show-sddcs display a list of your SDDCs 21 | show-vms get a list of your VMs 22 | create create an SDDC 23 | delete delete an sddc 24 | watch-task watch a task for a long running sddc create or delete 25 | cancel-task cancel a long running task 26 | 27 | optional arguments: 28 | -h, --help show this help message and exit 29 | -------------------------------------------------------------------------------- /docs/3-tkg_help.txt: -------------------------------------------------------------------------------- 1 | usage: tkg [-h] {enable-tkg,disable-tkg} ... 2 | 3 | positional arguments: 4 | {enable-tkg,disable-tkg} sddc sub-command help 5 | enable-tkg Enable Tanzu Kubernetes Grid on an SDDC 6 | disable-tkg Disable Tanzu Kubernetes Grid on an SDDC 7 | 8 | optional arguments: 9 | -h, --help show this help message and exit 10 | -------------------------------------------------------------------------------- /docs/4-segment_help.txt: -------------------------------------------------------------------------------- 1 | usage: segment [-h] {create,delete,show,update} ... 2 | 3 | positional arguments: 4 | {create,delete,show,update} 5 | segment sub-command help 6 | create Create a new virtual machine network segment. 7 | delete Delete a virtual machine network segment. 8 | show Show the current virtual machine network segments. 9 | update Update the configuration of a virtual machine network 10 | segment. 11 | 12 | optional arguments: 13 | -h, --help show this help message and exit 14 | -------------------------------------------------------------------------------- /docs/5-vpn_help.txt: -------------------------------------------------------------------------------- 1 | usage: vpn [-h] 2 | {new-ike-profile,new-ipsec-profile,new-dpd-profile,new-t1-vpn-service,new-local-endpoint,new-t1-ipsec-session,new-t1-l2vpn-session,new-sddc-ipsec-vpn,new-sddc-l2vpn,remove-sddc-ipsec-vpn,remove-sddc-l2VPN,remove-tier1-ipsec-vpn,remove-tier1-l2vpn,remove-t1-vpn-local-endpoint,remove-t1-vpn-service,remove-vpn-profile,show-sddc-vpn,show-vpn-endpoints,show-sddc-l2vpn,show-vpn-ike-profiles,show-vpn-ipsec-profiles,show-vpn-dpd-profiles,show-tier1-vpn-services,show-tier1-vpn-local-endpoints,show-tier1-vpn,show-tier1-vpn-details,show-tier1-l2vpn,show-tier1-l2vpn-details,rbvpn-prefix-list,rbvpn-neighbors} 3 | ... 4 | 5 | positional arguments: 6 | {new-ike-profile,new-ipsec-profile,new-dpd-profile,new-t1-vpn-service,new-local-endpoint,new-t1-ipsec-session,new-t1-l2vpn-session,new-sddc-ipsec-vpn,new-sddc-l2vpn,remove-sddc-ipsec-vpn,remove-sddc-l2VPN,remove-tier1-ipsec-vpn,remove-tier1-l2vpn,remove-t1-vpn-local-endpoint,remove-t1-vpn-service,remove-vpn-profile,show-sddc-vpn,show-vpn-endpoints,show-sddc-l2vpn,show-vpn-ike-profiles,show-vpn-ipsec-profiles,show-vpn-dpd-profiles,show-tier1-vpn-services,show-tier1-vpn-local-endpoints,show-tier1-vpn,show-tier1-vpn-details,show-tier1-l2vpn,show-tier1-l2vpn-details,rbvpn-prefix-list,rbvpn-neighbors} 7 | vpn sub-command help 8 | new-ike-profile Create a new VPN IKE Profile 9 | new-ipsec-profile Create a new VPN IPSEC Tunnel Profile 10 | new-dpd-profile Create a new IPSEC DPD profile 11 | new-t1-vpn-service Create a new Tier-1 gateway VPN service 12 | new-local-endpoint Create a new Tier-1 VPN local endpoint 13 | new-t1-ipsec-session 14 | Create a new Tier-1 gateway VPN session 15 | new-t1-l2vpn-session 16 | Create a new Tier-1 gateay L2VPN session 17 | new-sddc-ipsec-vpn Create a new IPSEC VPN tunnel for the SDDC 18 | new-sddc-l2vpn create a new L2VPN for the SDDC 19 | remove-sddc-ipsec-vpn 20 | remove a SDDC IPSec VPN 21 | remove-sddc-l2VPN remove a SDDC L2VPN 22 | remove-tier1-ipsec-vpn 23 | remove a Tier-1 IPSec VPN 24 | remove-tier1-l2vpn remove a Tier-1 L2VPN 25 | remove-t1-vpn-local-endpoint 26 | remove a Tier-1 Local Endpoint 27 | remove-t1-vpn-service 28 | Remove a Tier-1 VPN Service 29 | remove-vpn-profile remove a VPN IKE profile 30 | show-sddc-vpn show the SDDC VPNs 31 | show-vpn-endpoints Show the SDDC VPN endpoints 32 | show-sddc-l2vpn show the SDDC L2VPN 33 | show-vpn-ike-profiles 34 | show the VPN IKE profiles 35 | show-vpn-ipsec-profiles 36 | Show the VPN IPSec Tunnel Profiles 37 | show-vpn-dpd-profiles 38 | Show the VPN DPD Profiles 39 | show-tier1-vpn-services 40 | Show Tier-1 VPN Services 41 | show-tier1-vpn-local-endpoints 42 | Show Tier-1 Local Endpoints 43 | show-tier1-vpn Show Tier-1 IPSec VPN sessions 44 | show-tier1-vpn-details 45 | Show IPSec VPN details for a provided Tier1 VPN name 46 | show-tier1-l2vpn Show Tier-1 L2VPN sessions 47 | show-tier1-l2vpn-details 48 | Show Tier-1 L2VPN Session Details 49 | rbvpn-prefix-list Create and configure route-based VPN prefix lists. 50 | rbvpn-neighbors Show and configure BGP Neighbors for route-based VPN. 51 | 52 | options: 53 | -h, --help show this help message and exit -------------------------------------------------------------------------------- /docs/6-nat_help.txt: -------------------------------------------------------------------------------- 1 | usage: nat [-h] {new-nat-rule,remove-nat-rule,show-nat} ... 2 | 3 | positional arguments: 4 | {new-nat-rule,remove-nat-rule,show-nat} 5 | nat sub-command help 6 | new-nat-rule To create a new NAT rule 7 | remove-nat-rule remove a NAT rule 8 | show-nat show the configured NAT rules 9 | 10 | optional arguments: 11 | -h, --help show this help message and exit 12 | -------------------------------------------------------------------------------- /docs/7-t1_help.txt: -------------------------------------------------------------------------------- 1 | usage: t1 [-h] {create,delete,update} ... 2 | 3 | positional arguments: 4 | {create,delete,update} 5 | t1 sub-command help 6 | create Create a new, secondary T1 gateway. 7 | delete Delete a secondary T1 gateway. 8 | update Update the configuration of a secondary T1 gateway. 9 | 10 | optional arguments: 11 | -h, --help show this help message and exit 12 | -------------------------------------------------------------------------------- /docs/8-vtc_help.txt: -------------------------------------------------------------------------------- 1 | usage: vtc [-h] 2 | {connect-aws,disconnect-aws,attach-dxgw,detach-dxgw,get-sddc-info,get-nsx-info,attach-sddc,detach-sddc,create-sddc-group,delete-sddc-group,get-group-info,attach-vpc,detach-vpc,vpc-prefixes} 3 | ... 4 | 5 | positional arguments: 6 | {connect-aws,disconnect-aws,attach-dxgw,detach-dxgw,get-sddc-info,get-nsx-info,attach-sddc,detach-sddc,create-sddc-group,delete-sddc-group,get-group-info,attach-vpc,detach-vpc,vpc-prefixes} 7 | vtc sub-command help 8 | connect-aws Connect an vTGW to an AWS account 9 | disconnect-aws Disconnect a vTGW from an AWS account 10 | attach-dxgw Attach a Direct Connect Gateway to a 11 | vTGW 12 | detach-dxgw Detach a Direct Connect Gateway from a 13 | vTGW 14 | get-sddc-info Display a list of all SDDCs 15 | get-nsx-info Display NSX credentials and URLs 16 | attach-sddc Attach an SDDC to a vTGW 17 | detach-sddc Detach an SDDC from a vTGW 18 | create-sddc-group Create an SDDC group 19 | delete-sddc-group Delete an SDDC group 20 | get-group-info Display details for an SDDC group 21 | attach-vpc Attach a VPC to a vTGW 22 | detach-vpc Detach VPC from a vTGW 23 | vpc-prefixes Add or remove vTGW static routes 24 | 25 | optional arguments: 26 | -h, --help show this help message and exit 27 | -------------------------------------------------------------------------------- /docs/9-gwfw_help.txt: -------------------------------------------------------------------------------- 1 | usage: gwfw [-h] 2 | {new-cgw-rule,new-mgw-rule,remove-cgw-rule,remove-mgw-rule,show-cgw-rule,show-mgw-rule} 3 | ... 4 | 5 | positional arguments: 6 | {new-cgw-rule,new-mgw-rule,remove-cgw-rule,remove-mgw-rule,show-cgw-rule,show-mgw-rule} 7 | gwfw sub-command help 8 | new-cgw-rule create a new CGW security rule 9 | new-mgw-rule create a new MGW security rule 10 | remove-cgw-rule delete a CGW security rule 11 | remove-mgw-rule delete a MGW security rule 12 | show-cgw-rule show the CGW security rules 13 | show-mgw-rule show the MGW security rules 14 | 15 | optional arguments: 16 | -h, --help show this help message and exit 17 | -------------------------------------------------------------------------------- /docs/all-supported-commands.md: -------------------------------------------------------------------------------- 1 | # pyVMC all supported Commands 2 | ## Table of Contents 3 | 4 | - [Current Supported Commands](#current-supported-commands) 5 | - [Authentication](#authentication) 6 | - [Getting Help](#getting-help) 7 | - [1. CSP - Cloud Service Portal related commands](#1-csp-commands) 8 | - [2. SDDC - Software Defined Datacenter related commands](#2-sddc-commands) 9 | - [3. TKG - Tanzu Kubernetes Service related commands](#3-tkg-commands) 10 | - [4. VTC - VMware Transit Connect related commands](#4-vtc-commands) 11 | - [5. NSX related commands](#5-nsx-related-commands) 12 | - [5.1 Segment - Virtual Machine network segment related commands](#51-segment-commands) 13 | - [5.2 VPN - Virtual private network related commands](#52-vpn-commands) 14 | - [5.3 NAT - Network Address Translation related commands](#53-nat-commands) 15 | - [5.4 T1 - T1 gateways related commands](#54-t1-commands) 16 | - [5.5 GWFW - NSX Gateway Firewall related commands](#55-gwfw-commands) 17 | - [5.6 DFW - NSX Distributed Firewall related commands](#56-dfw-commands) 18 | - [5.7 NSXAF - NSX Advanced Firewall related commands](#57-nsxaf-commands) 19 | - [5.8 Inventory - NSX Inventory related commands](#58-inventory-commands) 20 | - [5.9 System - NSX-T System related commands](#59-system-commands) 21 | - [5.10 serach-nsx - NSX Manager inventory related commands](#510-serach-nsx-commands) 22 | - [6. VCDR - VMware Cloud Disaster Recovery related commands](#6-vcdr-commands) 23 | - [7. Flexcomp - VMware Cloud Flex Compute related commands](#7-flex-compute-commands) 24 | 25 | 26 | ## Current Supported Commands 27 | Here are the currently supported 'super' commands: 28 | ```shell 29 | csp Commands related to the Cloud Service Portal itself. 30 | sddc Commands related to the Software Defined Datacenter (SDDC) itself. 31 | tkg Commands related to the Tanzu Kubernetes Service (TKG). 32 | segment Create, delete, update, and show Virtual Machine network segments. 33 | vpn Create, delete, update, and show virtual private network (VPN) settings. 34 | nat Show and update Network Address Translation (NAT) rules. 35 | t1 Create, delete, update, and show secondary T1 gateways. 36 | vtc Commands related to VMware Transit Connect (VTC). 37 | gwfw Show and update policies and rules associated with NSX Gateway Firewall (mgw, cgw, etc.). 38 | dfw Show and update policies and rules associated with NSX Distributed Firewall. 39 | nsxaf Commands related to the NSX Advanced Firewall - e.g. IDS. 40 | inventory Show and update objects in the NSX Inventory (groups, services, etc). 41 | system Show and update configuration data associated with the NSX-T System (DNS, public IP, etc). 42 | search-nsx Search the NSX Manager inventory. 43 | vcdr Create, delete, update, and show information about VMware Cloud Disaster Recovery. 44 | flexcomp Commands related to the Cloud Flex Compute itself. 45 | ``` 46 | ## Authentication 47 | pyVMC supports both **refresh_token** and **OAuth AppId/Secret** way to authenticate. 48 | Values for it needs to be specified in config.ini file. Default auth method is to use **refresh_token**. 49 | 50 | If one wants to use OAuth, then **--oauth** switch needs to be provided when running the command. 51 | 52 | Examples: 53 | 54 | Using default 'refresh_token' 55 | ```shell 56 | ./pyVMC.py sddc show-sddcs 57 | ``` 58 | 59 | Using OAuth 60 | ```shell 61 | ./pyVMC.py sddc show-sddcs --oauth 62 | ``` 63 | ## Getting Help 64 | 65 | To see the supported commands for any given category / super-command, simply use '-h'... for example: 66 | 67 | ```shell 68 | ./pyVMC.py vcdr -h 69 | usage: vcdr [-h] {scfs,pg,snaps,rsddc,psite,vms} ... 70 | 71 | positional arguments: 72 | {scfs,pg,snaps,rsddc,psite,vms} 73 | vcdr sub-command help 74 | scfs VCDR cloud file system - use '-h' for help. 75 | pg VCDR Protection Groups - use '-h' for help. 76 | snaps VCDR Snapshots - use '-h' for help. 77 | rsddc VCDR Recovery SDDC - use '-h' for help. 78 | psite VCDR Protected Site - use '-h' for help. 79 | vms VCDR cloud file system - use '-h' for help. 80 | 81 | optional arguments: 82 | -h, --help show this help message and exit 83 | ``` 84 | 85 | Similarly, to see the options for any given command, run the individual command with the -h option: 86 | 87 | ```shell 88 | ./pyVMC.py vcdr scfs -h 89 | usage: vcdr scfs [-h] {show} ... 90 | 91 | positional arguments: 92 | {show} vcdr scfs sub-command help 93 | show Show information about the VCDR Scale-out file System(s). 94 | 95 | optional arguments: 96 | --oauth [OAUTH] Used to specify use of OAuth app ID and secret in config.ini instead of 'refresh_token' (default) 97 | -h, --help show this help message and exit 98 | ``` 99 | 100 | ## 1. CSP commands 101 | ```shell 102 | usage: csp [-h] 103 | {show-csp-services,show-csp-service-roles,get-access-token,add-users-to-csp-group,show-csp-group-diff,show-csp-group-members,show-csp-groups,search-csp-org-users,find-csp-user-by-service-role,show-org-users} 104 | ... 105 | 106 | positional arguments: 107 | {show-csp-services,show-csp-service-roles,get-access-token,add-users-to-csp-group,show-csp-group-diff,show-csp-group-members,show-csp-groups,search-csp-org-users,find-csp-user-by-service-role,show-org-users} 108 | csp sub-command help 109 | show-csp-services Show the entitled services in the 110 | VMware Cloud Service Console. 111 | show-csp-service-roles Show the entitled service roles in the 112 | VMware Cloud Service Console. 113 | get-access-token show your access token 114 | add-users-to-csp-group CSP user to a group 115 | show-csp-group-diff this compares the roles in the 116 | specified group with every user in the 117 | org and prints out a user-by-user diff 118 | show-csp-group-members show CSP group members 119 | show-csp-groups To show CSP groups which contain 120 | GROUP_SEARCH_TERM string 121 | search-csp-org-users Search for users in the CSP or org. 122 | find-csp-user-by-service-role Search for CSP users with a specific 123 | service role. First use show-csp- 124 | service-roles to see entitled roles 125 | show-org-users Show all organization users 126 | 127 | optional arguments: 128 | -h, --help show this help message and exit 129 | ``` 130 | 131 | ## 2. SDDC commands 132 | ```shell 133 | usage: sddc [-h] 134 | {show-compatible-subnets,show-connected-accounts,set-sddc-connected-services,show-sddc-connected-vpc,show-shadow-account,show-sddc-state,show-sddc-hosts,show-sddcs,show-vms} 135 | ... 136 | 137 | positional arguments: 138 | {show-compatible-subnets,show-connected-accounts,set-sddc-connected-services,show-sddc-connected-vpc,show-shadow-account,show-sddc-state,show-sddc-hosts,show-sddcs,show-vms} 139 | sddc sub-command help 140 | show-compatible-subnets show compatible native AWS subnets 141 | connected to the SDDC 142 | show-connected-accounts show native AWS accounts connected to 143 | the SDDC 144 | set-sddc-connected-services change whether to use S3 over the 145 | Internet(false) or via the ENI(true) 146 | show-sddc-connected-vpc show the VPC connected to the SDDC 147 | show-shadow-account show the Shadow AWS Account VMC is 148 | deployed in 149 | show-sddc-state get a view of your selected SDDC 150 | show-sddc-hosts display a list of the hosts in your 151 | SDDC 152 | show-sddcs display a list of your SDDCs 153 | show-vms get a list of your VMs 154 | create create an SDDC 155 | delete delete an sddc 156 | watch-task watch a task for a long running sddc create or delete 157 | cancel-task cancel a long running task 158 | 159 | optional arguments: 160 | -h, --help show this help message and exit 161 | ``` 162 | 163 | ## 3. TKG commands 164 | ```shell 165 | usage: tkg [-h] {enable-tkg,disable-tkg} ... 166 | 167 | positional arguments: 168 | {enable-tkg,disable-tkg} sddc sub-command help 169 | enable-tkg Enable Tanzu Kubernetes Grid on an SDDC 170 | disable-tkg Disable Tanzu Kubernetes Grid on an SDDC 171 | 172 | optional arguments: 173 | -h, --help show this help message and exit 174 | ``` 175 | 176 | ## 4 VTC commands 177 | ```shell 178 | usage: vtc [-h] 179 | {connect-aws,disconnect-aws,attach-dxgw,detach-dxgw,get-sddc-info,get-nsx-info,attach-sddc,detach-sddc,create-sddc-group,delete-sddc-group,get-group-info,attach-vpc,detach-vpc,vpc-prefixes} 180 | ... 181 | 182 | positional arguments: 183 | {connect-aws,disconnect-aws,attach-dxgw,detach-dxgw,get-sddc-info,get-nsx-info,attach-sddc,detach-sddc,create-sddc-group,delete-sddc-group,get-group-info,attach-vpc,detach-vpc,vpc-prefixes} 184 | vtc sub-command help 185 | connect-aws Connect an vTGW to an AWS account 186 | disconnect-aws Disconnect a vTGW from an AWS account 187 | attach-dxgw Attach a Direct Connect Gateway to a 188 | vTGW 189 | detach-dxgw Detach a Direct Connect Gateway from a 190 | vTGW 191 | get-sddc-info Display a list of all SDDCs 192 | get-nsx-info Display NSX credentials and URLs 193 | attach-sddc Attach an SDDC to a vTGW 194 | detach-sddc Detach an SDDC from a vTGW 195 | create-sddc-group Create an SDDC group 196 | delete-sddc-group Delete an SDDC group 197 | get-group-info Display details for an SDDC group 198 | attach-vpc Attach a VPC to a vTGW 199 | detach-vpc Detach VPC from a vTGW 200 | vpc-prefixes Add or remove vTGW static routes 201 | 202 | optional arguments: 203 | -h, --help show this help message and exit 204 | ``` 205 | 206 | ## 5. NSX related commands 207 | ### 5.1 Segment commands 208 | ```shell 209 | usage: segment [-h] {create,delete,show,update} ... 210 | 211 | positional arguments: 212 | {create,delete,show,update} 213 | segment sub-command help 214 | create Create a new virtual machine network segment. 215 | delete Delete a virtual machine network segment. 216 | show Show the current virtual machine network segments. 217 | update Update the configuration of a virtual machine network 218 | segment. 219 | 220 | optional arguments: 221 | -h, --help show this help message and exit 222 | ``` 223 | ### 5.2 VPN commands 224 | ```shell 225 | usage: vpn [-h] 226 | {new-l2vpn,remove-l2VPN,remove-vpn,remove-vpn-ike-profile,remove-vpn-ipsec-tunnel-profile,show-l2vpn,show-l2vpn-services,show-vpn,show-vpn-ike-profile,show-vpn-internet-ip,show-vpn-ipsec-tunnel-profile,show-vpn-ipsec-endpoints,rbvpn-prefix-list,rbvpn-neighbors} 227 | ... 228 | 229 | positional arguments: 230 | {new-l2vpn,remove-l2VPN,remove-vpn,remove-vpn-ike-profile,remove-vpn-ipsec-tunnel-profile,show-l2vpn,show-l2vpn-services,show-vpn,show-vpn-ike-profile,show-vpn-internet-ip,show-vpn-ipsec-tunnel-profile,show-vpn-ipsec-endpoints,rbvpn-prefix-list,rbvpn-neighbors} 231 | vpn sub-command help 232 | new-l2vpn create a new L2VPN 233 | remove-l2VPN remove a L2VPN 234 | remove-vpn remove a VPN 235 | remove-vpn-ike-profile 236 | remove a VPN IKE profile 237 | remove-vpn-ipsec-tunnel-profile 238 | To remove a VPN IPSec Tunnel profile 239 | show-l2vpn show l2 vpn 240 | show-l2vpn-services 241 | show l2 vpn services 242 | show-vpn show the configured VPN 243 | show-vpn show the VPN statistics 244 | show-vpn-ike-profile 245 | show the VPN IKE profiles 246 | show-vpn-internet-ip 247 | show the public IP used for VPN services 248 | show-vpn-ipsec-tunnel-profile 249 | show the VPN tunnel profile 250 | show-vpn-ipsec-endpoints 251 | show the VPN IPSec endpoints 252 | rbvpn-prefix-list Create and configure route-based VPN prefix lists. 253 | rbvpn-neighbors Show and configure BGP Neighbors for route-based VPN. 254 | 255 | optional arguments: 256 | -h, --help show this help message and exit 257 | ``` 258 | ### 5.3 NAT commands 259 | ```shell 260 | usage: nat [-h] {new-nat-rule,remove-nat-rule,show-nat} ... 261 | 262 | positional arguments: 263 | {new-nat-rule,remove-nat-rule,show-nat} 264 | nat sub-command help 265 | new-nat-rule To create a new NAT rule 266 | remove-nat-rule remove a NAT rule 267 | show-nat show the configured NAT rules 268 | 269 | optional arguments: 270 | -h, --help show this help message and exit 271 | ``` 272 | ### 5.4 T1 commands 273 | ```shell 274 | usage: t1 [-h] {create,delete,update} ... 275 | 276 | positional arguments: 277 | {create,delete,update} 278 | t1 sub-command help 279 | create Create a new, secondary T1 gateway. 280 | delete Delete a secondary T1 gateway. 281 | update Update the configuration of a secondary T1 gateway. 282 | 283 | optional arguments: 284 | -h, --help show this help message and exit 285 | ``` 286 | ### 5.5 GWFW commands 287 | ```shell 288 | usage: gwfw [-h] 289 | {new-cgw-rule,new-mgw-rule,remove-cgw-rule,remove-mgw-rule,show-cgw-rule,show-mgw-rule} 290 | ... 291 | 292 | positional arguments: 293 | {new-cgw-rule,new-mgw-rule,remove-cgw-rule,remove-mgw-rule,show-cgw-rule,show-mgw-rule} 294 | gwfw sub-command help 295 | new-cgw-rule create a new CGW security rule 296 | new-mgw-rule create a new MGW security rule 297 | remove-cgw-rule delete a CGW security rule 298 | remove-mgw-rule delete a MGW security rule 299 | show-cgw-rule show the CGW security rules 300 | show-mgw-rule show the MGW security rules 301 | 302 | optional arguments: 303 | -h, --help show this help message and exit 304 | ``` 305 | ### 5.6 DFW commands 306 | ```shell 307 | usage: dfw [-h] 308 | {new-dfw-rule,new-dfw-section,remove-dfw-rule,remove-dfw-section,show-dfw-section,show-dfw-section-rules} 309 | ... 310 | 311 | positional arguments: 312 | {new-dfw-rule,new-dfw-section,remove-dfw-rule,remove-dfw-section,show-dfw-section,show-dfw-section-rules} 313 | dfw sub-command help 314 | new-dfw-rule create a new DFW security rule 315 | new-dfw-section create a new DFW section 316 | remove-dfw-rule delete a DFW rule 317 | remove-dfw-section delete a DFW section 318 | show-dfw-section show the DFW sections 319 | show-dfw-section-rules 320 | show the DFW security rules within a section 321 | 322 | optional arguments: 323 | -h, --help show this help message and exit 324 | ``` 325 | ### 5.7 NSXAF commands 326 | ```shell 327 | usage: nsxaf [-h] 328 | {show-nsxaf-status,show-ids-cluster-status,enable-cluster-ids,disable-cluster-ids,enable-all-cluster-ids,disable-all-cluster-ids,enable-ids-auto-update,ids-update-signatures,show-ids-signature-versions,show-ids-profiles,search-product-affected,create-ids-profile,show-ids-policies,create-ids-policy,show-ids-rules,create-ids-rule} 329 | ... 330 | 331 | positional arguments: 332 | {show-nsxaf-status,show-ids-cluster-status,enable-cluster-ids,disable-cluster-ids,enable-all-cluster-ids,disable-all-cluster-ids,enable-ids-auto-update,ids-update-signatures,show-ids-signature-versions,show-ids-profiles,search-product-affected,create-ids-profile,show-ids-policies,create-ids-policy,show-ids-rules,create-ids-rule} 333 | nsxaf sub-command help 334 | show-nsxaf-status Display the status of the NSX Advanced 335 | Firewall Add-on 336 | show-ids-cluster-status Show IDS status for each cluster in 337 | the SDDC 338 | enable-cluster-ids Enable IDS on cluster 339 | disable-cluster-ids Disable IDS on cluster 340 | enable-all-cluster-ids Enable IDS on all clusters 341 | disable-all-cluster-ids Disable IDS on all clusters 342 | enable-ids-auto-update Enable IDS signature auto update 343 | ids-update-signatures Force update of IDS signatures 344 | show-ids-signature-versions Show downloaded signature versions 345 | show-ids-profiles Show all IDS profiles 346 | search-product-affected Search through the active IDS 347 | signature for specific product 348 | affected. Useful when building an IDS 349 | Profile 350 | create-ids-profile Create an IDS profile with either 351 | Product Affected, CVSS or both. 352 | show-ids-policies List all IDS policies 353 | create-ids-policy Create an IDS policy 354 | show-ids-rules List all IDS rules 355 | create-ids-rule Create an IDS rule using previously 356 | created IDS profile and inventory 357 | groups 358 | 359 | optional arguments: 360 | -h, --help show this help message and exit 361 | ``` 362 | ### 5.8 Inventory commands 363 | ```shell 364 | usage: inventory [-h] 365 | {new-group,remove-group,show-group,show-group-association,new-service,remove-service,show-services} 366 | ... 367 | 368 | positional arguments: 369 | {new-group,remove-group,show-group,show-group-association,new-service,remove-service,show-services} 370 | inventory sub-command help 371 | new-group create a new group 372 | remove-group remove a group 373 | show-group show existing groups 374 | show-group-association 375 | show security rules used by a groups 376 | new-service create a new service 377 | remove-service remove a service 378 | show-services show services 379 | 380 | optional arguments: 381 | -h, --help show this help message and exit 382 | ``` 383 | ### 5.9 System commands 384 | ```shell 385 | usage: system [-h] 386 | {show-dns-services,show-dns-zones,new-sddc-public-ip,remove-sddc-public-ip,set-sddc-public-ip,show-sddc-public-ip,mtu,asn,dx-admin-cost,show-egress-interface-counters,show-routes} 387 | ... 388 | 389 | positional arguments: 390 | {show-dns-services,show-dns-zones,new-sddc-public-ip,remove-sddc-public-ip,set-sddc-public-ip,show-sddc-public-ip,mtu,asn,dx-admin-cost,show-egress-interface-counters,show-routes} 391 | system sub-command help 392 | show-dns-services Show currently configured DNS services 393 | show-dns-zones Show currently configured DNS zone services. 394 | new-sddc-public-ip request a new public IP 395 | remove-sddc-public-ip 396 | remove an existing public IP 397 | set-sddc-public-ip update the description of an existing public IP 398 | show-sddc-public-ip 399 | show the public IPs 400 | mtu Show and update configuration data associated with 401 | Maximum Transmission Unit value for the Intranet 402 | Interface. 403 | asn Show and update configuration data associated with 404 | Autonomous System Number value for the Intranet 405 | Interface. 406 | dx-admin-cost Use to view currently configured routing preference / 407 | admin cost - VPN or DX. 408 | show-egress-interface-counters 409 | show current Internet interface egress counters 410 | show-routes Show SDDC routes 411 | 412 | optional arguments: 413 | -h, --help show this help message and exit 414 | ``` 415 | ### 5.10 serach-nsx commands 416 | ```shell 417 | usage: search-nsx [-h] [--nsxm [NSXM]] 418 | [-ot {BgpNeighborConfig,BgpRoutingConfig,Group,IdsSignature,PrefixList,RouteBasedIPSecVPNSession,Segment,Service,StaticRoute,Tier0,Tier1,VirtualMachine,VirtualNetworkInterface}] 419 | [-oid OBJECT_ID] 420 | 421 | optional arguments: 422 | -h, --help show this help message and exit 423 | --nsxm [NSXM] Used to specify NSX Manager instead of NSX proxy (Default). 424 | -ot {BgpNeighborConfig,BgpRoutingConfig,Group,IdsSignature,PrefixList,RouteBasedIPSecVPNSession,Segment,Service,StaticRoute,Tier0,Tier1,VirtualMachine,VirtualNetworkInterface}, --object_type {BgpNeighborConfig,BgpRoutingConfig,Group,IdsSignature,PrefixList,RouteBasedIPSecVPNSession,Segment,Service,StaticRoute,Tier0,Tier1,VirtualMachine,VirtualNetworkInterface} 425 | The type of object to search for. 426 | -oid OBJECT_ID, --object_id OBJECT_ID 427 | The name of the object you are searching for. 428 | ``` 429 | 430 | ## 6. VCDR commands 431 | ```shell 432 | usage: vcdr [-h] {scfs,pg,snaps,rsddc,psite,vms} ... 433 | 434 | positional arguments: 435 | {scfs,pg,snaps,rsddc,psite,vms} 436 | vcdr sub-command help 437 | scfs VCDR cloud file system - use '-h' for help. 438 | pg VCDR Protection Groups - use '-h' for help. 439 | snaps VCDR Snapshots - use '-h' for help. 440 | rsddc VCDR Recovery SDDC - use '-h' for help. 441 | psite VCDR Protected Site - use '-h' for help. 442 | vms VCDR cloud file system - use '-h' for help. 443 | 444 | optional arguments: 445 | -h, --help show this help message and exit 446 | ``` 447 | 448 | ## 7. Flex Compute commands 449 | [VMware Cloud Flex Compute](https://blogs.vmware.com/cloud/2022/08/30/announcing-vmware-cloud-flex-compute/) is currently in technical preview and any related functionality is subject to change until Cloud Flex Compute is made generally available in the future. 450 | ```shell 451 | usage: flexcomp [-h] 452 | {activity-status,show-all-namespaces,validate-network,create-flexcompute,delete-flexcomp,show-flex-comp-regions,show-flex-comp-templates,show-all-vms,show-all-images,create-vm,power-operation,delete-vm} 453 | ... 454 | 455 | positional arguments: 456 | {activity-status,show-all-namespaces,validate-network,create-flexcompute,delete-flexcomp,show-flex-comp-regions,show-flex-comp-templates,show-all-vms,show-all-images,create-vm,power-operation,delete-vm} 457 | flexcomp sub-command help 458 | activity-status Get activity status of long running tasks 459 | show-all-namespaces Show all present Cloud Flex Compute Name Spaces 460 | validate-network Validate network CIDR before creating Cloud Flex Compute Name Space 461 | create-flexcompute Create new Cloud Flex Compute 462 | delete-flexcomp Delete existing Cloud Flex Compute 463 | show-flex-comp-regions Show available Cloud Flex Compute regions 464 | show-flex-comp-templates Show available Cloud Flex Compute resource templates to create Name Space 465 | show-all-vms Show all VMs in Cloud Flex Compute instance 466 | show-all-images Show all images available to create VMs from 467 | create-vm Create VM 468 | power-operation Perform Power Operations on VM 469 | delete-vm Delete VM. Make sure VM is in powerd OFF state. 470 | 471 | options: 472 | -h, --help 473 | ``` -------------------------------------------------------------------------------- /docs/all-supported-commands.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vmware/python-client-for-vmware-cloud-on-aws/6b2375fad709c679817809883c28a2c08e0ff31c/docs/all-supported-commands.pdf -------------------------------------------------------------------------------- /docs/images/argparse_structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vmware/python-client-for-vmware-cloud-on-aws/6b2375fad709c679817809883c28a2c08e0ff31c/docs/images/argparse_structure.png -------------------------------------------------------------------------------- /docs/images/pyvmc_refactor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vmware/python-client-for-vmware-cloud-on-aws/6b2375fad709c679817809883c28a2c08e0ff31c/docs/images/pyvmc_refactor.png -------------------------------------------------------------------------------- /docs/pyvmc-structure.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | Over time, PyVMC has grown it its capabilites, in the number of commands it supports and ultimately in its complexity. Functionality has been separated amongst several files to make navigating and updating the code easier - however this may make understanding how the project is put together a bit more challenging to understand. 3 | 4 | ## The Files 5 | 6 | As mentione above, the functionality of the project is split up into multiple files.... 7 | 8 | ![pyvmc structure](images/pyvmc_refactor.png) 9 | 10 | Everything begins with... 11 | 12 | **pyVMC.py** 13 | pyVMC.py is the file where _main_ is defined, where the commands and arguments are defined for controlling user input, and where the 'business logic'/ functions are housed for handling user input and ultimately returning a result back to the screen. 14 | 15 | A great deal of work has gone into incorporating python argparse into the project for defining and handling commands and arguments in the CLI - so the first thing you should do before adding / updating a command or function for the project is think through how the user your new functionality: 16 | - Are you simply adding new functionality to a command that already exists? 17 | - Are you instead adding a new command for an existing feature? 18 | - Are you adding new commands for an entirely new API? 19 | 20 | The answers to the questions above will ultimately help determine if you are adding a new category of commands ("super-command"), a new sub-command under a super-command that already exists, or just a new option for an existing subcommand. 21 | 22 | See the image below for a graphical representation of how argparse is being used to strucure commands in a hierarchical fashion. 23 | 24 | ![argparse structure](images/argparse_structure.png) 25 | 26 | **API modules** 27 | The functions that actually make calls to the API endpoint(s) are housed in separate files, aligned to the specific API: 28 | - pyvmc_csp.py: functions that make calls to the CSP URL - https://console.cloud.vmware.com 29 | - pyvmc_vmc.py: functions that make calls to the VMC service API - https://vmc.vmware.com 30 | - pyvmc_nsx.py: functions that make calls to the NSX API via the reverse proxy to directly to the NSX manager (this URL is unique to each customer and is determined via a query to the service) 31 | - pyvmc_vcdr.py: fuctions that make calls to the VCDR Orchestrator API (this URL is unique to each customer and must be manually updated in the config.ini file) 32 | 33 | ## Error Handling -------------------------------------------------------------------------------- /docs/release-notes.md: -------------------------------------------------------------------------------- 1 | # What's New - February 2023 2 | The refactoring work continues, as well as the introduction of some new things! 3 | 4 | ### Flex Compute 5 | Thanks to some wonderful contributions this past January, we are very plesed to report that VMWare Cloud Flex Compute! Of course the service isn't actually Generally Available (GA) yet, but once it's released, pyVMC will support it! 6 | 7 | ### OAuth Support 8 | Now, in addition to supporting authentication via an API refresh token, users may now configure authentication via an OAuth Application ID and Secret. Read more about how to authenticate applications with OAuth 2.0 here: https://docs.vmware.com/en/VMware-Cloud-services/services/Using-VMware-Cloud-Services/GUID-53D39337-D93A-4B84-BD18-DDF43C21479A.html. 9 | 10 | With this release, simply add the parameters for your OAuth Application and Secret to your config.ini file and you can authenticate using the "--oauth" flag! 11 | 12 | 13 | # What's New - November 14, 2022 14 | In this latest release, all commands have been refactored to use a command / sub-command syntax. This provides for greater ease of use, as commands can be grouped by category. Furthermore, a comprehensive argument framework has been implemented (argparse) which allows for passing parameters via the command line for better support for scripting. 15 | 16 | For example, in previous versions BGP prefix filters for your route-based VPN could only be created interactively at the command line. Now, however, prefix lists can be imported as JSON files to make it a lot easier to update your T0 route table via script for specific use cases - e.g. disaster recovery. 17 | 18 | ### New Features: 19 | - all commands refactored to use argument parsing with python argparse module 20 | - moving forward, all commands will be updated (over time) to use standardized create / update / delete verbs (CrUD) where applicable 21 | 22 | ### New Commands / options: 23 | - asn: replaces previous ASN commands show-sddc-bgp-as / set-sddc-bgp-as 24 | - csp: new super-command for all commands related to CSP 25 | - dfw: new supercommand for distributed firewall sub-commands (use -h to see sub-commands) 26 | - dns: replaces previous commands show-dns-services / show-dns-zones 27 | - dx-admin-cost: replaces previous command show-sddc-bgp-vpn 28 | - gwfw: new supercommand for gateway firewall sub-commands (use -h to see sub-commands) 29 | - mtu: replaces previous MTU commands show-mtu / set-mtu 30 | - nat: replaces previous commands new-nat-rule / remove-nat-rule / show-nat-rule 31 | - nsxaf: new super-command for all subcommands related to NSX Advanced Firewall (IDS, etc) (use -h to see sub-commands) 32 | - rbvpn-neighbors: replaces previous command show-t0-bgp-neighbors 33 | - rbvpn-prefix-list: replaces new-t0-prefix-list, remove-t0-prefix-list, attach-t0-prefix-list, detach-t0-prefix-list. Added ability to import or export prefix lists to / from JSON files 34 | - segment: replaces previous commands for creating and deleting VM networks (new-network, new-segment, etc) 35 | - show-routes command to replace show-t0-routes, show-static-routes, show-bgp-routes, show-tgw-routes 36 | - system: new super-command for all commands related to the SDDC/NSX system (DNS, ASN, MTU, etc) (use -h to see sub-commands) 37 | - t1: replaces previous commands for creating and deleting tier1 gateways (configure-t1, remove-t1) 38 | - tkg: new super-command for all subcommands related to Tanzu Kubernetes Service (use -h to see sub-commands) 39 | - vcdr: new super command replaces all previous vcdr commands (use -h to see sub-commands) 40 | - vpn: new super command replaces all previous vpn commands (use -h to see sub-commands) 41 | - vtc: new super-command for all subcommands related to VMware Transit Connect (use -h to see sub-commands) 42 | 43 | ### Known Issuesß: 44 | -------------------------------------------------------------------------------- /import/aws.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "service_entries": [ 4 | { 5 | "l4_protocol": "TCP", 6 | "source_ports": [], 7 | "destination_ports": [ 8 | "53","135","88","389","464","445","636","3268-3269","49152-65535" 9 | ], 10 | "resource_type": "L4PortSetServiceEntry", 11 | "id": "AWS_Directory_Service_TCP", 12 | "display_name": "Amazon Directory Service TCP ports", 13 | "path": "/infra/services/AWS_Directory_Service/service-entries/AWS_Directory_Service_TCP", 14 | "relative_path": "AWS_Directory_Service", 15 | "parent_path": "/infra/services/AWS_Directory_Service" 16 | }, 17 | { 18 | "l4_protocol": "UDP", 19 | "source_ports": [], 20 | "destination_ports": [ 21 | "53","88","123","389","464" 22 | ], 23 | "resource_type": "L4PortSetServiceEntry", 24 | "id": "AWS_Directory_Service_UDP", 25 | "display_name": "Amazon Directory Service UDP ports", 26 | "path": "/infra/services/AWS_Directory_Service/service-entries/AWS_Directory_Service_UDP", 27 | "relative_path": "AWS_Directory_Service", 28 | "parent_path": "/infra/services/AWS_Directory_Service" 29 | } 30 | ], 31 | "service_type": "NON_ETHER", 32 | "resource_type": "Service", 33 | "id": "AWS_Directory_Service", 34 | "display_name": "AWS Directory Service", 35 | "description": "AWS Directory Service", 36 | "path": "/infra/services/AWS_Directory_Service", 37 | "relative_path": "AWS_Directory_Service", 38 | "parent_path": "/infra" 39 | }, 40 | { 41 | "service_entries": [ 42 | { 43 | "l4_protocol": "TCP", 44 | "source_ports": [], 45 | "destination_ports": [ 46 | "2049" 47 | ], 48 | "resource_type": "L4PortSetServiceEntry", 49 | "id": "AWS_EFS_2049", 50 | "display_name": "Amazon EFS 2049", 51 | "path": "/infra/services/AWS_EFS/service-entries/AWS_EFS_2049", 52 | "relative_path": "AWS_EFS", 53 | "parent_path": "/infra/services/AWS_EFS" 54 | } 55 | ], 56 | "service_type": "NON_ETHER", 57 | "resource_type": "Service", 58 | "id": "AWS_EFS", 59 | "display_name": "Amazon Elastic File System", 60 | "description": "Amazon Elastic File System", 61 | "path": "/infra/services/AWS_EFS", 62 | "relative_path": "AWS_EFS", 63 | "parent_path": "/infra" 64 | }, 65 | { 66 | "service_entries": [ 67 | { 68 | "l4_protocol": "TCP", 69 | "source_ports": [], 70 | "destination_ports": [ 71 | "3260" 72 | ], 73 | "resource_type": "L4PortSetServiceEntry", 74 | "id": "AWS_FSX_ISCSI_3260", 75 | "display_name": "AWS FSx - iSCSI", 76 | "path": "/infra/services/AWS_FSX_ISCSI/service-entries/AWS_FSX_ISCSI_3260", 77 | "relative_path": "AWS_FSX_ISCSI", 78 | "parent_path": "/infra/services/AWS_FSX_ISCSI" 79 | } 80 | ], 81 | "service_type": "NON_ETHER", 82 | "resource_type": "Service", 83 | "id": "AWS_FSX_ISCSI", 84 | "display_name": "Amazon FSx - iSCSI", 85 | "description": "Amazon FSx - iSCSI", 86 | "path": "/infra/services/AWS_FSX_ISCSI", 87 | "relative_path": "AWS_FSX_ISCSI", 88 | "parent_path": "/infra" 89 | }, 90 | { 91 | "service_entries": [ 92 | { 93 | "l4_protocol": "TCP", 94 | "source_ports": [], 95 | "destination_ports": [ 96 | "111","635","2049" 97 | ], 98 | "resource_type": "L4PortSetServiceEntry", 99 | "id": "AWS_FSX_NFS_TCP", 100 | "display_name": "AWS FSx - NFS TCP ports", 101 | "path": "/infra/services/AWS_FSX_NFS/service-entries/AWS_FSX_NFS_TCP", 102 | "relative_path": "AWS_FSX_NFS", 103 | "parent_path": "/infra/services/AWS_FSX_NFS" 104 | }, 105 | { 106 | "l4_protocol": "UDP", 107 | "source_ports": [], 108 | "destination_ports": [ 109 | "111","635","2049" 110 | ], 111 | "resource_type": "L4PortSetServiceEntry", 112 | "id": "AWS_FSX_NFS_UDP", 113 | "display_name": "AWS FSx - NFS UDP ports", 114 | "path": "/infra/services/AWS_FSX_NFS/service-entries/AWS_FSX_NFS_UDP", 115 | "relative_path": "AWS_FSX_NFS", 116 | "parent_path": "/infra/services/AWS_FSX_NFS" 117 | } 118 | ], 119 | "service_type": "NON_ETHER", 120 | "resource_type": "Service", 121 | "id": "AWS_FSX_NFS", 122 | "display_name": "Amazon FSx - NFS", 123 | "description": "Amazon FSx - NFS", 124 | "path": "/infra/services/AWS_FSX_NFS", 125 | "relative_path": "AWS_FSX_NFS", 126 | "parent_path": "/infra" 127 | }, 128 | { 129 | "service_entries": [ 130 | { 131 | "l4_protocol": "TCP", 132 | "source_ports": [], 133 | "destination_ports": [ 134 | "445" 135 | ], 136 | "resource_type": "L4PortSetServiceEntry", 137 | "id": "AWS_FSX_WINDOWS_445", 138 | "display_name": "AWS FSx - SMB - Windows 445", 139 | "path": "/infra/services/AWS_FSX_WINDOWS_SMB/service-entries/AWS_FSX_WINDOWS_445", 140 | "relative_path": "AWS_FSX_WINDOWS_SMB", 141 | "parent_path": "/infra/services/AWS_FSX_WINDOWS_SMB" 142 | } 143 | ], 144 | "service_type": "NON_ETHER", 145 | "resource_type": "Service", 146 | "id": "AWS_FSX_WINDOWS_SMB", 147 | "display_name": "Amazon FSx SMB - Windows", 148 | "description": "Amazon FSx SMB - Windows", 149 | "path": "/infra/services/AWS_FSX_WINDOWS_SMB", 150 | "relative_path": "AWS_FSX_WINDOWS_SMB", 151 | "parent_path": "/infra" 152 | }, 153 | { 154 | "service_entries": [ 155 | { 156 | "l4_protocol": "TCP", 157 | "source_ports": [], 158 | "destination_ports": [ 159 | "5985" 160 | ], 161 | "resource_type": "L4PortSetServiceEntry", 162 | "id": "AWS_FSX_WINDOWS_5985", 163 | "display_name": "AWS FSx - WinRM - 5985", 164 | "path": "/infra/services/AWS_FSX_WINDOWS_WINRM/service-entries/AWS_FSX_WINDOWS_5985", 165 | "relative_path": "AWS_FSX_WINDOWS_WINRM", 166 | "parent_path": "/infra/services/AWS_FSX_WINDOWS_WINRM" 167 | } 168 | ], 169 | "service_type": "NON_ETHER", 170 | "resource_type": "Service", 171 | "id": "AWS_FSX_WINDOWS_WINRM", 172 | "display_name": "Amazon FSx WinRM - Windows", 173 | "description": "Amazon FSx WinRM - Windows", 174 | "path": "/infra/services/AWS_FSX_WINDOWS_WINRM", 175 | "relative_path": "AWS_FSX_WINDOWS_WINRM", 176 | "parent_path": "/infra" 177 | }, 178 | { 179 | "service_entries": [ 180 | { 181 | "l4_protocol": "TCP", 182 | "source_ports": [], 183 | "destination_ports": [ 184 | "3306" 185 | ], 186 | "resource_type": "L4PortSetServiceEntry", 187 | "id": "AWS_RDS_Aurora_3306", 188 | "display_name": "AWS RDS Aurora 3306", 189 | "path": "/infra/services/AWS_Aurora/service-entries/AWS_RDS_Aurora_3306", 190 | "relative_path": "AWS_RDS_Aurora", 191 | "parent_path": "/infra/services/AWS_RDS_Aurora" 192 | } 193 | ], 194 | "service_type": "NON_ETHER", 195 | "resource_type": "Service", 196 | "id": "AWS_RDS_Aurora", 197 | "display_name": "Amazon RDS - Aurora", 198 | "description": "Amazon Relational Database Service - Aurora", 199 | "path": "/infra/services/AWS_RDS_Aurora", 200 | "relative_path": "AWS_RDS_Aurora", 201 | "parent_path": "/infra" 202 | }, 203 | { 204 | "service_entries": [ 205 | { 206 | "l4_protocol": "TCP", 207 | "source_ports": [], 208 | "destination_ports": [ 209 | "3306" 210 | ], 211 | "resource_type": "L4PortSetServiceEntry", 212 | "id": "AWS_RDS_MariaDB_3306", 213 | "display_name": "Amazon RDS MariaDB 3306", 214 | "path": "/infra/services/AWS_RDS_MariaDB/service-entries/AWS_RDS_MariaDB_3306", 215 | "relative_path": "AWS_RDS_MariaDB", 216 | "parent_path": "/infra/services/AWS_RDS_MariaDB" 217 | } 218 | ], 219 | "service_type": "NON_ETHER", 220 | "resource_type": "Service", 221 | "id": "AWS_RDS_MariaDB", 222 | "display_name": "Amazon RDS - MariaDB", 223 | "description": "Amazon Relational Database Service - MariaDB", 224 | "path": "/infra/services/AWS_RDS_MariaDB", 225 | "relative_path": "AWS_RDS_MariaDB", 226 | "parent_path": "/infra" 227 | }, 228 | { 229 | "service_entries": [ 230 | { 231 | "l4_protocol": "TCP", 232 | "source_ports": [], 233 | "destination_ports": [ 234 | "3306" 235 | ], 236 | "resource_type": "L4PortSetServiceEntry", 237 | "id": "AWS_RDS_MySQL_3306", 238 | "display_name": "Amazon RDS MySQL 3306", 239 | "path": "/infra/services/AWS_RDS_MySQL/service-entries/AWS_RDS_MySQL_3306", 240 | "relative_path": "AWS_RDS_MySQL", 241 | "parent_path": "/infra/services/AWS_RDS_MySQL" 242 | } 243 | ], 244 | "service_type": "NON_ETHER", 245 | "resource_type": "Service", 246 | "id": "AWS_RDS_MySQL", 247 | "display_name": "Amazon RDS - MySQL", 248 | "description": "Amazon Relational Database Service - MySQL", 249 | "path": "/infra/services/AWS_RDS_MySQL", 250 | "relative_path": "AWS_RDS_MySQL", 251 | "parent_path": "/infra" 252 | }, 253 | { 254 | "service_entries": [ 255 | { 256 | "l4_protocol": "TCP", 257 | "source_ports": [], 258 | "destination_ports": [ 259 | "1433" 260 | ], 261 | "resource_type": "L4PortSetServiceEntry", 262 | "id": "AWS_RDS_MSSQL_3306", 263 | "display_name": "Amazon RDS MSSQL 1433", 264 | "path": "/infra/services/AWS_RDS_MSSQL/service-entries/AWS_RDS_MSSQL_1433", 265 | "relative_path": "AWS_RDS_MSSQL", 266 | "parent_path": "/infra/services/AWS_RDS_MSSQL" 267 | } 268 | ], 269 | "service_type": "NON_ETHER", 270 | "resource_type": "Service", 271 | "id": "AWS_RDS_MSSQL", 272 | "display_name": "Amazon RDS - MSSQL", 273 | "description": "Amazon Relational Database Service - MSSQL", 274 | "path": "/infra/services/AWS_RDS_MSSQL", 275 | "relative_path": "AWS_RDS_MSSQL", 276 | "parent_path": "/infra" 277 | }, 278 | { 279 | "service_entries": [ 280 | { 281 | "l4_protocol": "TCP", 282 | "source_ports": [], 283 | "destination_ports": [ 284 | "1521" 285 | ], 286 | "resource_type": "L4PortSetServiceEntry", 287 | "id": "AWS_RDS_Oracle_1521", 288 | "display_name": "Amazon RDS Oracle 1521", 289 | "path": "/infra/services/AWS_RDS_Oracle/service-entries/AWS_RDS_Oracle_1521", 290 | "relative_path": "AWS_RDS_Oracle", 291 | "parent_path": "/infra/services/AWS_RDS_Oracle" 292 | } 293 | ], 294 | "service_type": "NON_ETHER", 295 | "resource_type": "Service", 296 | "id": "AWS_RDS_Oracle", 297 | "display_name": "Amazon RDS - Oracle", 298 | "description": "Amazon Relational Database Service - Oracle", 299 | "path": "/infra/services/AWS_RDS_Oracle", 300 | "relative_path": "AWS_RDS_Oracle", 301 | "parent_path": "/infra" 302 | }, 303 | { 304 | "service_entries": [ 305 | { 306 | "l4_protocol": "TCP", 307 | "source_ports": [], 308 | "destination_ports": [ 309 | "5432" 310 | ], 311 | "resource_type": "L4PortSetServiceEntry", 312 | "id": "AWS_RDS_Postgres_5432", 313 | "display_name": "Amazon RDS Postgres 5432", 314 | "path": "/infra/services/AWS_RDS_Postgres/service-entries/AWS_RDS_Postgres_5432", 315 | "relative_path": "AWS_RDS_Postgres", 316 | "parent_path": "/infra/services/AWS_RDS_Postgres" 317 | } 318 | ], 319 | "service_type": "NON_ETHER", 320 | "resource_type": "Service", 321 | "id": "AWS_RDS_Postgres", 322 | "display_name": "Amazon RDS - PostgreSQL", 323 | "description": "Amazon Relational Database Service - PostgreSQL", 324 | "path": "/infra/services/AWS_RDS_Postgres", 325 | "relative_path": "AWS_RDS_Postgres", 326 | "parent_path": "/infra" 327 | } 328 | ] -------------------------------------------------------------------------------- /json/rbvpn-prefix-list.json.sample.json: -------------------------------------------------------------------------------- 1 | { 2 | "prefixes": [ 3 | { 4 | "network": "10.0.0.0/8", 5 | "action": "PERMIT" 6 | }, 7 | { 8 | "network": "172.16.0.0/12", 9 | "action": "PERMIT" 10 | }, 11 | { 12 | "network": "192.168.0.0/16", 13 | "action": "PERMIT" 14 | } 15 | ], 16 | "resource_type": "PrefixList", 17 | "id": "sample-prefix-list", 18 | "display_name": "sample-prefix-list" 19 | } -------------------------------------------------------------------------------- /pyvmc_csp.py: -------------------------------------------------------------------------------- 1 | # CSP Python library for PyVMC 2 | 3 | ################################################################################ 4 | ### Copyright (C) 2019-2022 VMware, Inc. All rights reserved. 5 | ### SPDX-License-Identifier: BSD-2-Clause 6 | ################################################################################ 7 | 8 | import json 9 | import requests 10 | import sys 11 | 12 | #In order to use the following function, all the functions in this file will have to be modified to use. 13 | def csp_error_handling(fxn_response): 14 | code = fxn_response.status_code 15 | print (f'API call failed with status code {code}.') 16 | if code == 400: 17 | print(f'Error {code}: "Bad Request"') 18 | print("Request was improperly formatted or contained an invalid parameter.") 19 | elif code == 401: 20 | print(f'Error {code}: "The user is not authorized to use the API"') 21 | print("It's likely your refresh token is out of date or otherwise incorrect.") 22 | elif code == 403: 23 | print(f'Error {code}: "The user is forbidden to use the API"') 24 | print("The client does not have sufficient privileges to execute the request.") 25 | print("The API is likely in read-only mode, or a request was made to modify a read-only property.") 26 | print("It's likely your refresh token does not provide sufficient access.") 27 | elif code == 404: 28 | print(f'Error {code}: "Organization with this identifier is not found."') 29 | print("Please confirm the ORG ID and SDDC ID entries in your config.ini are correct.") 30 | elif code == 409: 31 | print(f'Error {code}: "The request could not be processed due to a conflict"') 32 | print("The request can not be performed because it conflicts with configuration on a different entity, or because another client modified the same entity.") 33 | print("If the conflict arose because of a conflict with a different entity, modify the conflicting configuration. If the problem is due to a concurrent update, re-fetch the resource, apply the desired update, and reissue the request.") 34 | elif code == 429: 35 | print(f'Error {code}: "The user has sent too many requests"') 36 | elif code == 500: 37 | print(f'Error {code}: "An unexpected error has occurred while processing the request"') 38 | elif code == 503: 39 | print(f'Error {code}: "Service Unavailable"') 40 | print("The request can not be performed because the associated resource could not be reached or is temporarily busy. Please confirm the ORG ID and SDDC ID entries in your config.ini are correct.") 41 | else: 42 | print(f'Error: {code}: Unknown error') 43 | try: 44 | json_response = fxn_response.json() 45 | if 'message' in json_response: 46 | print(json_response['message']) 47 | except: 48 | print("No additional information in the error response.") 49 | return None 50 | 51 | 52 | # ============================ 53 | # Services 54 | # ============================ 55 | 56 | 57 | def get_csp_groups_json(strCSProdURL, ORG_ID, session_token): 58 | myHeader = {'csp-auth-token': session_token} 59 | myURL = f'{strCSProdURL}/csp/gateway/am/api/orgs/{ORG_ID}/groups' 60 | response = requests.get(myURL, headers=myHeader) 61 | json_response = response.json() 62 | if response.status_code == 200: 63 | return json_response 64 | else: 65 | csp_error_handling(response) 66 | sys.exit(1) 67 | 68 | 69 | def get_services_json(strCSPProdURL, ORG_ID, session_token): 70 | """Gets services and URI for associated access token and Org ID""" 71 | myHeader = {'csp-auth-token': session_token} 72 | myURL = f'{strCSPProdURL}/csp/gateway/slc/api/v2/ui/definitions/?orgId={ORG_ID}' 73 | response = requests.get(myURL, headers=myHeader) 74 | json_response = response.json() 75 | if response.status_code == 200: 76 | return json_response 77 | else: 78 | csp_error_handling(response) 79 | sys.exit(1) 80 | 81 | 82 | # ============================ 83 | # User and Group Management 84 | # ============================ 85 | 86 | 87 | def get_csp_users_json(strCSPProdURL, orgID, session_token): 88 | """Returns all CSP Users in the select ORG in JSON format""" 89 | myHeader = {'csp-auth-token': session_token} 90 | myURL = f'{strCSPProdURL}/csp/gateway/am/api/v2/orgs/{orgID}/users' 91 | response = requests.get(myURL, headers=myHeader) 92 | json_response = response.json() 93 | if response.status_code == 200: 94 | return json_response 95 | else: 96 | csp_error_handling(response) 97 | sys.exit(1) 98 | 99 | 100 | def get_csp_groups_searchterm_json(strCSProdURL, org_id, session_token,search_term): 101 | """make the call to the API looking for groups that CONTAIN the search term - br""" 102 | myHeader = {'csp-auth-token': session_token} 103 | 104 | myURL = f'{strCSProdURL}/csp/gateway/am/api/orgs/{org_id}/groups-search?groupSearchTerm={search_term}' 105 | response = requests.get(myURL, headers=myHeader) 106 | json_response = response.json() 107 | # 108 | # For error handling, print out some text, but use the reason/message that comes from the API. 109 | # 110 | if response.status_code == 200: 111 | return json_response 112 | else: 113 | csp_error_handling(response) 114 | sys.exit(1) 115 | 116 | 117 | def get_csp_group_info_json(strCSProdURL, org_id, session_token, group_id): 118 | myHeader = {'csp-auth-token': session_token} 119 | myURL = f'{strCSProdURL}/csp/gateway/am/api/orgs/{org_id}/groups/{group_id}' 120 | response = requests.get(myURL, headers=myHeader) 121 | json_response = response.json() 122 | if response.status_code == 200: 123 | return json_response 124 | else: 125 | csp_error_handling(response) 126 | sys.exit(1) 127 | 128 | 129 | def get_csp_users_group_json(strCSProdURL, org_id, session_token, group_id): 130 | myHeader = {'csp-auth-token': session_token} 131 | myURL = f'{strCSProdURL}/csp/gateway/am/api/orgs/{org_id}/groups/{group_id}/users' 132 | response = requests.get(myURL, headers=myHeader) 133 | json_response = response.json() 134 | if response.status_code == 200: 135 | return json_response 136 | else: 137 | csp_error_handling(response) 138 | sys.exit(1) 139 | 140 | 141 | def get_csp_service_roles_json(strCSProdURL, org_id, session_token): 142 | myHeader = {'csp-auth-token': session_token} 143 | myURL = f'{strCSProdURL}/csp/gateway/am/api/loggedin/user/orgs/{org_id}/service-roles' 144 | response = requests.get(myURL, headers=myHeader) 145 | json_response = response.json() 146 | if response.status_code == 200: 147 | return json_response 148 | else: 149 | csp_error_handling(response) 150 | sys.exit(1) 151 | 152 | 153 | def search_csp_users_json(strCSProdURL, session_token, json_data, org_id): 154 | my_header = {'csp-auth-token': session_token, 'Content-Type': 'application/json'} 155 | my_url = f'{strCSProdURL}/csp/gateway/am/api/orgs/{org_id}/users/search' 156 | response = requests.get(my_url, headers=my_header, params=json_data) 157 | json_response = response.json() 158 | if response.status_code == 200: 159 | return json_response 160 | else: 161 | csp_error_handling(response) 162 | sys.exit(1) 163 | 164 | 165 | def add_users_csp_group_json(strCSProdURL, org_id, session_token, group_id, json_data): 166 | myHeader = {'csp-auth-token': session_token, 'Content-Type': 'application/json'} 167 | myURL = f'{strCSProdURL}/csp/gateway/am/api/orgs/{org_id}/groups/{group_id}/users' 168 | response = requests.post(myURL, data=json.dumps(json_data), headers=myHeader) 169 | json_response = response.json() 170 | if response.status_code == 200: 171 | return json_response 172 | else: 173 | csp_error_handling(response) 174 | sys.exit(1) 175 | -------------------------------------------------------------------------------- /pyvmc_flexcomp.py: -------------------------------------------------------------------------------- 1 | # Flex Compute Python library for PyVMC 2 | 3 | ################################################################################ 4 | ### Copyright (C) 2019-2023 VMware, Inc. All rights reserved. 5 | ### SPDX-License-Identifier: BSD-2-Clause 6 | ################################################################################ 7 | 8 | import sys 9 | import json 10 | from weakref import proxy 11 | import requests 12 | from requests.sessions import session 13 | from requests.auth import HTTPBasicAuth 14 | 15 | # ============================ 16 | # Flex Compute Namespace 17 | # ============================ 18 | 19 | 20 | def get_activity_status(strProdURL, session_token, org_id, activity_id): 21 | pyvmc_header = {"csp-auth-token": session_token} 22 | url = strProdURL+"/api/activity/"+org_id+"/activities/"+activity_id+"?expand=true" 23 | response = requests.get(url, headers=pyvmc_header) 24 | json_response = response.json() 25 | if response.status_code == 200: 26 | return json_response 27 | else: 28 | print("There was an error. Check the syntax.") 29 | print(f"API call failed with status code {response.status_code}. URL: {url}.") 30 | print(json_response['error_message']) 31 | return None 32 | 33 | 34 | def get_flexcomp_namesapces(strProdURL, session_token, org_id): 35 | pyvmc_header = {"csp-auth-token": session_token} 36 | url = strProdURL+"/api/infrastructure/"+org_id+"/core/namespaces" 37 | response = requests.get(url, headers=pyvmc_header) 38 | json_response = response.json() 39 | if response.status_code == 200: 40 | return json_response 41 | else: 42 | print("There was an error. Check the syntax.") 43 | print(f"API call failed with status code {response.status_code}. URL: {url}.") 44 | print(json_response['error_message']) 45 | return None 46 | 47 | 48 | def flexcomp_validate_network(strProdURL, session_token, org_id, cidr, seg_name, seg_cidr): 49 | data = {} 50 | temp_data = {} 51 | pyvmc_header = {"csp-auth-token": session_token, 52 | "Content-Type": "application/json"} 53 | url = strProdURL+"/api/infrastructure/"+org_id+"/core/namespaces:validate-network" 54 | data['ens_cidr'] = cidr 55 | data['segment_configs'] = [] 56 | temp_data['segment_cidr'] = seg_cidr 57 | temp_data['segment_name'] = seg_name 58 | temp_data['segment_type'] = "ROUTED" 59 | data['segment_configs'].append(temp_data) 60 | payload = json.dumps(data) 61 | 62 | response = requests.post(url, headers=pyvmc_header, data=payload) 63 | json_response = response.json() 64 | if response.status_code == 200: 65 | return json_response 66 | else: 67 | print("There was an error. Check the syntax.") 68 | print(f'API call failed with status code {response.status_code}. URL: {url}.') 69 | print(json_response['error_message']) 70 | return None 71 | 72 | 73 | def create_flexcomp_namespace(strProdURL, session_token, org_id, name, desc, ens_size_id, region, cidr, seg_name, seg_cidr): 74 | data = {} 75 | pyvmc_header = {"csp-auth-token": session_token, 76 | "Content-Type": "application/json"} 77 | url = strProdURL+"/api/infrastructure/"+org_id+"/core/namespaces:create" 78 | data['name'] = name 79 | data['region'] = region 80 | data['provider'] = "AWS" 81 | data['description'] = desc 82 | data['type'] = "BASIC" 83 | data['tenancy_type'] = "HARD" 84 | data['capacity_profiles'] = [ 85 | { 86 | "fault_domains": 1, 87 | "size_id": ens_size_id, 88 | "infra_type": "GENERAL_PURPOSE" 89 | } 90 | ] 91 | data['network_config'] = { 92 | "segment_configs": [ 93 | { 94 | "segment_cidr": seg_cidr, 95 | "segment_name": seg_name, 96 | "segment_type": "ROUTED" 97 | } 98 | ], 99 | "ens_cidr": cidr, 100 | "internet_connectivity": True 101 | } 102 | payload = json.dumps(data) 103 | 104 | response = requests.post(url, headers=pyvmc_header, data=payload) 105 | json_response = response.json() 106 | if response.status_code == 201: 107 | return json_response 108 | else: 109 | print("There was an error. Check the syntax.") 110 | print(f'API call failed with status code {response.status_code}. URL: {url}.') 111 | print(json_response['error_message']) 112 | return None 113 | 114 | 115 | def delete_flexcomp_namespace(strProdURL, session_token, org_id, nsId): 116 | pyvmc_header = {"csp-auth-token": session_token, 117 | "Content-Type": "application/json"} 118 | url = strProdURL+"/api/infrastructure/"+org_id+"/core/namespaces/"+nsId+":delete" 119 | response = requests.post(url, headers=pyvmc_header) 120 | json_response = response.json() 121 | if response.status_code == 201: 122 | return json_response 123 | else: 124 | print("There was an error. Check the syntax.") 125 | print(f'API call failed with status code {response.status_code}. URL: {url}.') 126 | print(json_response['error_message']) 127 | return None 128 | 129 | # ============================ 130 | # Flex Compute Profiles 131 | # ============================ 132 | 133 | 134 | def get_namespace_region(strProdURL, session_token, org_id): 135 | pyvmc_header = {"csp-auth-token": session_token} 136 | url = strProdURL+"/api/infrastructure/"+org_id+"/core/namespaces/regions" 137 | response = requests.get(url, headers=pyvmc_header) 138 | json_response = response.json() 139 | if response.status_code == 200: 140 | return json_response 141 | else: 142 | print("There was an error. Check the syntax.") 143 | print(f"API call failed with status code {response.status_code}. URL: {url}.") 144 | print(json_response['error_message']) 145 | return None 146 | 147 | 148 | def get_namespace_profiles(strProdURL, session_token, org_id): 149 | pyvmc_header = {"csp-auth-token": session_token} 150 | url = strProdURL + "/api/infrastructure/" + org_id + "/core/namespaces/profiles" 151 | response = requests.get(url, headers=pyvmc_header) 152 | json_response = response.json() 153 | if response.status_code == 200: 154 | return json_response 155 | else: 156 | print("There was an error. Check the syntax.") 157 | print(f"API call failed with status code {response.status_code}. URL: {url}.") 158 | print(json_response['error_message']) 159 | return None 160 | 161 | # ============================ 162 | # Flex Compute VM operations 163 | # ============================ 164 | 165 | 166 | def get_all_images(strProdURL, session_token, org_id): 167 | pyvmc_header = {"csp-auth-token": session_token} 168 | url = strProdURL + "/api/c3s/" + org_id + "/core/vmimages?size=100" 169 | response = requests.get(url, headers=pyvmc_header) 170 | json_response = response.json() 171 | if response.status_code == 200: 172 | return json_response 173 | else: 174 | print("There was an error. Check the syntax.") 175 | print(f"API call failed with status code {response.status_code}. URL: {url}.") 176 | print(json_response['error_message']) 177 | return None 178 | 179 | 180 | def get_all_vms(strProdURL, session_token, org_id): 181 | pyvmc_header = {"csp-auth-token": session_token} 182 | url = strProdURL + "/api/workload/" + org_id + "/core/namespace/virtual-machines" 183 | response = requests.get(url, headers=pyvmc_header) 184 | json_response = response.json() 185 | if response.status_code == 200: 186 | return json_response 187 | else: 188 | print("There was an error. Check the syntax.") 189 | print(f"API call failed with status code {response.status_code}. URL: {url}.") 190 | print(json_response['error_message']) 191 | return None 192 | 193 | 194 | def vm_power_operation(strProdURL, session_token, org_id, vmId, powerOperation): 195 | data = {} 196 | powerOnOperations = ['power_on', 'reset', 'guest_os_restart'] 197 | powerOffOperations = ['power_off', 'hard_stop', 'guest_os_shutdown'] 198 | if powerOperation.lower() == 'suspend': 199 | powerState = 'suspended' 200 | if powerOperation.lower() in powerOffOperations: 201 | powerState = 'poweredOff' 202 | if powerOperation.lower() in powerOnOperations: 203 | powerState = 'poweredOn' 204 | 205 | pyvmc_header = {"csp-auth-token": session_token, 206 | "Content-Type": "application/json"} 207 | url = strProdURL + "/api/workload/" + org_id + "/core/namespace/virtual-machines/"+vmId+":power-operation" 208 | 209 | data['spec'] = { 210 | "powerOperation": powerOperation, 211 | "powerState": powerState 212 | } 213 | payload = json.dumps(data) 214 | 215 | response = requests.post(url, headers=pyvmc_header, data=payload) 216 | json_response = response.json() 217 | if response.status_code == 201: 218 | return json_response 219 | else: 220 | print("There was an error. Check the syntax.") 221 | print(f'API call failed with status code {response.status_code}. URL: {url}.') 222 | print(json_response['error_message']) 223 | return None 224 | 225 | 226 | def create_vm_from_iso(strProdURL, session_token, org_id, name, namespace_name, cpu, mem, storage, network_seg_id, guestOS, imageId): 227 | data = {} 228 | pyvmc_header = {"csp-auth-token": session_token, 229 | "Content-Type": "application/json"} 230 | url = strProdURL + "/api/workload/" + org_id + "/core/namespace/virtual-machines:create-vm" 231 | data['metadata'] = { 232 | "name": name, 233 | "namespace": namespace_name 234 | } 235 | data['spec'] = { 236 | "cpu": { 237 | "allocation": { 238 | "count": int(cpu) 239 | } 240 | }, 241 | "guestOS": guestOS, 242 | "hardwareVersion": "VMX_19", 243 | "imageName": imageId, 244 | "memory": { 245 | "allocation": { 246 | "unit": "GiB", 247 | "value": int(mem) 248 | } 249 | }, 250 | "networkInterfaces": [ 251 | { 252 | "networkName": network_seg_id 253 | } 254 | ], 255 | "placementRequirement": { 256 | "hardwareType": "GENERAL_PURPOSE", 257 | "zone": "zone-1" 258 | }, 259 | "storage": { 260 | "unit": "GiB", 261 | "value": int(storage) 262 | } 263 | } 264 | data['spec']['cpu'] = { 265 | "allocation": {"count": int(cpu)} 266 | # "reservation": { 267 | # "value": 1.0, 268 | # "unit": "GHz" 269 | # } 270 | } 271 | data['spec']['memory'] = { 272 | "allocation": { 273 | "value": int(mem), 274 | "unit": "GiB" 275 | } 276 | # "reservation": { 277 | # "value": int(mem), 278 | # "unit": "GiB" 279 | # } 280 | } 281 | data['spec']['storage'] = { 282 | "value": int(storage), 283 | "unit": "GiB" 284 | } 285 | payload = json.dumps(data) 286 | print(payload) 287 | 288 | response = requests.post(url, headers=pyvmc_header, data=payload) 289 | print(response) 290 | print(response.json()) 291 | json_response = response.json() 292 | if response.status_code == 201: 293 | return json_response 294 | else: 295 | print("There was an error. Check the syntax.") 296 | print(f'API call failed with status code {response.status_code}. URL: {url}.') 297 | print(json_response['error_message']) 298 | return None 299 | 300 | 301 | def delete_vm(strProdURL, session_token, org_id, vmId): 302 | pyvmc_header = {"csp-auth-token": session_token, 303 | "Content-Type": "application/json"} 304 | url = strProdURL + "/api/workload/" + org_id + "/core/namespace/virtual-machines/"+vmId+":delete" 305 | response = requests.post(url, headers=pyvmc_header) 306 | json_response = response.json() 307 | if response.status_code == 201: 308 | return json_response 309 | else: 310 | print("There was an error. Check the syntax.") 311 | print(f'API call failed with status code {response.status_code}. URL: {url}.') 312 | print(json_response['error_message']) 313 | return None 314 | -------------------------------------------------------------------------------- /pyvmc_vcdr.py: -------------------------------------------------------------------------------- 1 | # VCDR Python library for PyVMC 2 | 3 | ################################################################################ 4 | ### Copyright (C) 2019-2022 VMware, Inc. All rights reserved. 5 | ### SPDX-License-Identifier: BSD-2-Clause 6 | ################################################################################ 7 | 8 | import json 9 | import requests 10 | 11 | def vcdr_error_handling(fxn_response): 12 | code = fxn_response.status_code 13 | print (f'API call failed with status code {code}.') 14 | if code == 400: 15 | print(f'Error {code}: "Bad Request"') 16 | print("Request was improperly formatted or contained an invalid parameter.") 17 | elif code ==401: 18 | print(f'Error {code}: "Unauthorized"') 19 | print("The client has not authenticated.") 20 | print("It's likely your refresh token is out of date or otherwise incorrect.") 21 | elif code ==403: 22 | print(f'Error {code}: "Forbidden"') 23 | print("The client does not have sufficient privileges to execute the request.") 24 | print("The API is likely in read-only mode, or a request was made to modify a read-only property.") 25 | print("It's likely your refresh token does not provide sufficient access.") 26 | elif code == 404: 27 | print(f'Error {code}: "Bad Request"') 28 | print("Request was improperly formatted or contained an invalid parameter.") 29 | elif code ==409: 30 | print(f'Error {code}: "Temporary Redirect"') 31 | print("The request can not be performed because it conflicts with configuration on a different entity, or because another client modified the same entity.") 32 | print("If the conflict arose because of a conflict with a different entity, modify the conflicting configuration. If the problem is due to a concurrent update, re-fetch the resource, apply the desired update, and reissue the request.") 33 | elif code ==412: 34 | print(f'Error {code}: "Precondition Failed"') 35 | print("The request can not be performed because a precondition check failed. Usually, this means that the client sent a PUT or PATCH request with an out-of-date _revision property, probably because some other client has modified the entity since it was retrieved. The client should re-fetch the entry, apply any desired changes, and re-submit the operation.") 36 | elif code ==500: 37 | print(f'Error {code}: "Internal Server Error"') 38 | print("An internal error occurred while executing the request. If the problem persists, perform diagnostic system tests, or contact your support representative.") 39 | elif code ==503: 40 | print(f'Error {code}: "Service Unavailable"') 41 | print("The request can not be performed because the associated resource could not be reached or is temporarily busy. Please confirm the VCDR Orchestrator URL in your config.ini are correct.") 42 | else: 43 | print(f'Error: {code}: Unknown error') 44 | try: 45 | json_response = fxn_response.json() 46 | if 'error_message' in json_response: 47 | print(json_response['error_message']) 48 | except: 49 | print("No additional information in the error response.") 50 | return None 51 | 52 | 53 | # ============================ 54 | # Cloud File System 55 | # ============================ 56 | 57 | def get_vcdr_cloud_fs_json(strVCDRProdURL, session_token): 58 | """Get Cloud File Systems - Get a list of all deployed cloud file systems in your VMware Cloud DR organization.""" 59 | myHeader = {'x-da-access-token': session_token} 60 | myURL = f'{strVCDRProdURL}/api/vcdr/v1alpha/cloud-file-systems' 61 | response = requests.get(myURL, headers=myHeader) 62 | if response.status_code == 200: 63 | json_response = response.json() 64 | return json_response 65 | else: 66 | vcdr_error_handling(response) 67 | return None 68 | 69 | 70 | def get_vcdr_cloud_fs_details_json(strVCDRProdURL, cloud_fs_id, session_token): 71 | """Get Cloud File System Details - Get details for an individual cloud file system.""" 72 | myHeader = {'x-da-access-token': session_token} 73 | myURL = f'{strVCDRProdURL}/api/vcdr/v1alpha/cloud-file-systems/{cloud_fs_id}' 74 | response = requests.get(myURL, headers=myHeader) 75 | if response.status_code == 200: 76 | json_response = response.json() 77 | return json_response 78 | else: 79 | vcdr_error_handling(response) 80 | return None 81 | 82 | # ============================ 83 | # Protected Site 84 | # ============================ 85 | 86 | def get_vcdr_sites_json(strVCDRProdURL, cloud_fs_id, session_token): 87 | """Get Protected Sites - Get a list of all protected sites associated with an individual cloud file system.""" 88 | myHeader = {'x-da-access-token': session_token} 89 | myURL = f'{strVCDRProdURL}/api/vcdr/v1alpha/cloud-file-systems/{cloud_fs_id}/protected-sites' 90 | response = requests.get(myURL, headers=myHeader) 91 | if response.status_code == 200: 92 | json_response = response.json() 93 | return json_response 94 | else: 95 | vcdr_error_handling(response) 96 | return None 97 | 98 | def get_vcdr_site_details_json(strVCDRProdURL, cloud_fs_id, site_id, session_token): 99 | """Get Protected Site Details - Get details about an individual protected site.""" 100 | myHeader = {'x-da-access-token': session_token} 101 | myURL = f'{strVCDRProdURL}/api/vcdr/v1alpha/cloud-file-systems/{cloud_fs_id}/protected-sites/{site_id}' 102 | response = requests.get(myURL, headers=myHeader) 103 | if response.status_code == 200: 104 | json_response = response.json() 105 | return json_response 106 | else: 107 | vcdr_error_handling(response) 108 | return None 109 | 110 | # ============================ 111 | # Protected VM 112 | # ============================ 113 | 114 | def get_vcdr_vm_json(strVCDRProdURL, cloud_fs_id, session_token): 115 | """Get Protected Virtual Machines - Get a list of all protected VMs currently being replicated to the specified cloud file system.""" 116 | myHeader = {'x-da-access-token': session_token} 117 | myURL = f'{strVCDRProdURL}/api/vcdr/v1alpha/cloud-file-systems/{cloud_fs_id}/protected-vms' 118 | response = requests.get(myURL, headers=myHeader) 119 | if response.status_code == 200: 120 | json_response = response.json() 121 | return json_response 122 | else: 123 | vcdr_error_handling(response) 124 | return None 125 | 126 | # ============================ 127 | # Protection Group 128 | # ============================ 129 | 130 | def get_vcdr_pg_json(strVCDRProdURL, cloud_fs_id, session_token): 131 | """Get Protection Groups - Get a list of all protection groups associated with an individual cloud file system.""" 132 | myHeader = {'x-da-access-token': session_token} 133 | myURL = f'{strVCDRProdURL}/api/vcdr/v1alpha/cloud-file-systems/{cloud_fs_id}/protection-groups' 134 | response = requests.get(myURL, headers=myHeader) 135 | if response.status_code == 200: 136 | json_response = response.json() 137 | return json_response 138 | else: 139 | vcdr_error_handling(response) 140 | return None 141 | 142 | def get_vcdr_pg_details_json(strVCDRProdURL, cloud_fs_id, pg_id, session_token): 143 | """Get Protection Group Details - Get details for the requested protection group.""" 144 | myHeader = {'x-da-access-token': session_token} 145 | myURL = f'{strVCDRProdURL}/api/vcdr/v1alpha/cloud-file-systems/{cloud_fs_id}/protection-groups/{pg_id}' 146 | response = requests.get(myURL, headers=myHeader) 147 | if response.status_code == 200: 148 | json_response = response.json() 149 | return json_response 150 | else: 151 | vcdr_error_handling(response) 152 | return None 153 | 154 | # ============================ 155 | # Protection Group Snapshot 156 | # ============================ 157 | 158 | def get_vcdr_pg_snaps_json(strVCDRProdURL, cloud_fs_id, pg_id, session_token): 159 | """Get Protection Group Snapshots - Get a list of all snapshots in a specific protection group.""" 160 | myHeader = {'x-da-access-token': session_token} 161 | myURL = f'{strVCDRProdURL}/api/vcdr/v1alpha/cloud-file-systems/{cloud_fs_id}/protection-groups/{pg_id}/snapshots' 162 | response = requests.get(myURL, headers=myHeader) 163 | if response.status_code == 200: 164 | json_response = response.json() 165 | return json_response 166 | else: 167 | vcdr_error_handling(response) 168 | return None 169 | 170 | def get_vcdr_pg_snap_details_json(strVCDRProdURL, cloud_fs_id, pg_id, snap_id, session_token): 171 | """Get Protection Group Snapshot Details - Get detailed information for a protection group snapshot.""" 172 | myHeader = {'x-da-access-token': session_token} 173 | myURL = f'{strVCDRProdURL}/api/vcdr/v1alpha/cloud-file-systems/{cloud_fs_id}/protection-groups/{pg_id}/snapshots/{snap_id}' 174 | response = requests.get(myURL, headers=myHeader) 175 | if response.status_code == 200: 176 | json_response = response.json() 177 | return json_response 178 | else: 179 | vcdr_error_handling(response) 180 | return None 181 | 182 | # ============================ 183 | # Recovery SDDC 184 | # ============================ 185 | 186 | def get_vcdr_sddcs_json(strVCDRProdURL, session_token): 187 | """Get Recovery SDDC - List VMware Cloud (VMC) Recovery Software-Defined Datacenters (SDDCs).""" 188 | myHeader = {'x-da-access-token': session_token} 189 | myURL = f'{strVCDRProdURL}/api/vcdr/v1alpha/recovery-sddcs' 190 | response = requests.get(myURL, headers=myHeader) 191 | if response.status_code == 200: 192 | json_response = response.json() 193 | return json_response 194 | else: 195 | vcdr_error_handling(response) 196 | return None 197 | 198 | def get_vcdr_sddc_details_json(strVCDRProdURL, sddc_id, session_token): 199 | """Get Recovery SDDC Details - Get details of a specific Recovery SDDC. """ 200 | myHeader = {'x-da-access-token': session_token} 201 | myURL = f'{strVCDRProdURL}/api/vcdr/v1alpha/recovery-sddcs/{sddc_id}' 202 | response = requests.get(myURL, headers=myHeader) 203 | if response.status_code == 200: 204 | json_response = response.json() 205 | return json_response 206 | else: 207 | vcdr_error_handling(response) 208 | return None 209 | -------------------------------------------------------------------------------- /pyvmc_vmc.py: -------------------------------------------------------------------------------- 1 | # VMC on AWS Python library for PyVMC 2 | 3 | ################################################################################ 4 | ### Copyright (C) 2019-2022 VMware, Inc. All rights reserved. 5 | ### SPDX-License-Identifier: BSD-2-Clause 6 | ################################################################################ 7 | 8 | import json 9 | import sys 10 | import requests 11 | 12 | #In order to use the following function, all the functions in this file will have to be modified to use. 13 | def vmc_error_handling(fxn_response): 14 | code = fxn_response.status_code 15 | print (f'API call failed with status code {code}.') 16 | if code == 400: 17 | print(f'Error {code}: "Bad Request"') 18 | print("Request was improperly formatted or contained an invalid parameter.") 19 | elif code == 401: 20 | print(f'Error {code}: "The user is not authorized to use the API"') 21 | print("It's likely your refresh token is out of date or otherwise incorrect.") 22 | elif code == 403: 23 | print(f'Error {code}: "The user is forbidden to use the API"') 24 | print("The client does not have sufficient privileges to execute the request.") 25 | print("The API is likely in read-only mode, or a request was made to modify a read-only property.") 26 | print("It's likely your refresh token does not provide sufficient access.") 27 | elif code == 404: 28 | print(f'Error {code}: "Not Found"') 29 | print("It's possible this is a configuration error- Please confirm the ORG ID and SDDC ID entries in your config.ini are correct.") 30 | elif code == 409: 31 | print(f'Error {code}: "The request could not be processed due to a conflict"') 32 | print("The request can not be performed because it conflicts with configuration on a different entity, or because another client modified the same entity.") 33 | print("If the conflict arose because of a conflict with a different entity, modify the conflicting configuration. If the problem is due to a concurrent update, re-fetch the resource, apply the desired update, and reissue the request.") 34 | elif code == 429: 35 | print(f'Error {code}: "The user has sent too many requests"') 36 | elif code == 500: 37 | print(f'Error {code}: "An unexpected error has occurred while processing the request"') 38 | elif code == 503: 39 | print(f'Error {code}: "Service Unavailable"') 40 | print("The request can not be performed because the associated resource could not be reached or is temporarily busy. Please confirm the ORG ID and SDDC ID entries in your config.ini are correct.") 41 | elif code == 504: 42 | print(f'Error {code}: "Gateway Error"') 43 | print("The request can not be performed because there is a problem with the network path. Check your VPN, etc.") 44 | else: 45 | print(f'Error: {code}: Unknown error') 46 | try: 47 | json_response = fxn_response.json() 48 | if 'message' in json_response: 49 | print(json_response['message']) 50 | if 'error_messages' in json_response: 51 | print(json_response['error_messages'][0]) 52 | if 'related_errors' in json_response: 53 | print("Related Errors") 54 | for r in json_response['related_errors']: 55 | print(r['error_message']) 56 | except: 57 | print("No additional information in the error response.") 58 | return None 59 | 60 | # ============================ 61 | # AWS Account and VPC 62 | # ============================ 63 | 64 | 65 | def get_compatible_subnets_json(strProdURL, orgID, sessiontoken, linkedAWSID, region): 66 | """Returns all compatible subnets for linking in selected AWS Account and AWS Region""" 67 | myHeader = {'csp-auth-token': sessiontoken} 68 | myURL = f"{strProdURL}/vmc/api/orgs/{orgID}/account-link/compatible-subnets" 69 | params = {'linkedAccountId': linkedAWSID,'region': region} 70 | response = requests.get(myURL, headers=myHeader, params=params) 71 | json_response = response.json() 72 | if response.status_code == 200: 73 | return json_response 74 | else: 75 | print("There was an error. Check the syntax.") 76 | print(f'API call failed with status code {response.status_code} : {response.reason} URL: {myURL}.') 77 | if 'error_message' in json_response.keys(): 78 | print(json_response['error_message']) 79 | if 'error_messages' in json_response.keys(): 80 | if len(json_response['error_messages']) > 0: 81 | print(f"Error Message: {json_response['error_messages'][0]}") 82 | return None 83 | 84 | 85 | def get_connected_accounts_json(strProdURL, orgID, sessiontoken): 86 | """ Returns all connected AWS accounts in json format """ 87 | myHeader = {'csp-auth-token': sessiontoken} 88 | myURL = f"{strProdURL}/vmc/api/orgs/{orgID}/account-link/connected-accounts" 89 | response = requests.get(myURL, headers=myHeader) 90 | json_response = response.json() 91 | if response.status_code == 200: 92 | return json_response 93 | else: 94 | print("There was an error. Check the syntax.") 95 | print(f'API call failed with status code {response.status_code}. URL: {myURL}.') 96 | if "error_message" in json_response.keys(): 97 | print(json_response['error_message']) 98 | return None 99 | 100 | # ============================ 101 | # SDDC 102 | # ============================ 103 | 104 | def create_sddc_json(strProdURL, sessiontoken, org_id, validate_only, json_data): 105 | my_header = {'csp-auth-token': sessiontoken} 106 | my_url = f'{strProdURL}/vmc/api/orgs/{org_id}/sddcs' 107 | if validate_only: 108 | my_url = my_url + "?validateOnly=true" 109 | response = requests.post(my_url, json=json_data, headers=my_header) 110 | if response.status_code == 202: 111 | print(f"Create SDDC Started. Creation Task is: ") 112 | json_response = response.json() 113 | new_task = json_response['id'] 114 | print(f'{new_task}') 115 | return json_response 116 | elif response.status_code == 200: 117 | print("Create Task Complete: Input Validated") 118 | validated = "{'input_validated' : True}" 119 | return eval(validated) 120 | else: 121 | vmc_error_handling(response) 122 | sys.exit(1) 123 | 124 | 125 | def delete_sddc_json(strProdURL, sessiontoken, orgID, sddcID,force): 126 | """Returns task for the delete process, or None if error""" 127 | myHeader = {'csp-auth-token': sessiontoken} 128 | myURL = f"{strProdURL}/vmc/api/orgs/{orgID}/sddcs/{sddcID}/" 129 | if force: 130 | myURL = myURL + "?force=true" 131 | response = requests.delete(myURL, headers=myHeader) 132 | json_response = response.json() 133 | if response.status_code == 202: 134 | print('Delete task created. Task ID:') 135 | newTask = json_response["id"] 136 | print(f'{newTask}') 137 | return json_response 138 | else: 139 | vmc_error_handling(response) 140 | sys.exit(1) 141 | 142 | 143 | def watch_sddc_task_json(strProdURL, sessiontoken, orgID, taskid): 144 | myHeader = {'csp-auth-token': sessiontoken} 145 | myURL = f"{strProdURL}/vmc/api/orgs/{orgID}/tasks/{taskid}" 146 | response = requests.get(myURL, headers=myHeader) 147 | json_response = response.json() 148 | if response.status_code == 200: 149 | # do the right thing 150 | return json_response 151 | elif response.status_code == 401: 152 | if 'error_messages' in json_response: 153 | print(json_response["error_messages"][0]) 154 | else: 155 | print("User is unauthorized for current operation") 156 | return None 157 | elif response.status_code == 403: 158 | if 'error_messages' in json_response: 159 | print(json_response["error_messages"][0]) 160 | else: 161 | print("User is forbidden from current action") 162 | return None 163 | elif response.status_code == 404: 164 | print("Cannot find the task with given identifier") 165 | if 'error_messages' in json_response: 166 | print(json_response["error_messages"][0]) 167 | return None 168 | else: 169 | print('Unexpected error') 170 | return None 171 | return None 172 | # 173 | # https://developer.vmware.com/apis/vmc/latest/vmc/api/orgs/org/tasks/task/post/ 174 | # 175 | def cancel_sddc_task_json(strProdURL, sessiontoken, orgID, taskid): 176 | myHeader = {'csp-auth-token': sessiontoken} 177 | myURL = f"{strProdURL}/vmc/api/orgs/{orgID}/tasks/{taskid}?action=cancel" 178 | response = requests.post(myURL, headers=myHeader) 179 | json_response = response.json() 180 | if response.status_code == 200: 181 | print(f'Task {taskid} has been successfully cancelled.') 182 | return json_response 183 | elif response.status_code == 400: 184 | print("Invalid Action") 185 | if 'error_messages' in json_response: 186 | print(json_response["error_messages"][0]) 187 | return None 188 | elif response.status_code == 401: 189 | print("Unauthorized for current action") 190 | if 'error_messages' in json_response: 191 | print(json_response["error_messages"][0]) 192 | return None 193 | elif response.status_code == 403: 194 | print("Forbidden Action") 195 | if 'error_messages' in json_response: 196 | print(json_response["error_messages"][0]) 197 | return None 198 | elif response.status_code == 404: 199 | print("Cannot find the task with given identifier") 200 | if 'error_messages' in json_response: 201 | print(json_response["error_messages"][0]) 202 | return None 203 | else: 204 | print(f'unexpected response {response.status_code}') 205 | return None 206 | 207 | def get_sddcs_json(strProdURL, orgID, sessiontoken): 208 | """Returns list of all SDDCs in an Org via json""" 209 | myHeader = {'csp-auth-token': sessiontoken} 210 | myURL = f"{strProdURL}/vmc/api/orgs/{orgID}/sddcs" 211 | response = requests.get(myURL, headers=myHeader) 212 | json_response = response.json() 213 | if response.status_code == 200: 214 | return json_response 215 | else: 216 | print("There was an error. Check the syntax.") 217 | print(f'API call failed with status code {response.status_code}. URL: {myURL}.') 218 | print(json_response['error_message']) 219 | return None 220 | 221 | 222 | def get_sddc_info_json (strProdURL, orgID, sessiontoken, sddcID): 223 | """Returns SDDC info in JSON format""" 224 | myHeader = {'csp-auth-token': sessiontoken} 225 | myURL = f"{strProdURL}/vmc/api/orgs/{orgID}/sddcs/{sddcID}" 226 | response = requests.get(myURL, headers=myHeader) 227 | json_response = response.json() 228 | if response.status_code == 200: 229 | return json_response 230 | else: 231 | print("There was an error. Check the syntax.") 232 | print(f'API call failed with status code {response.status_code}. URL: {myURL}.') 233 | print(json_response['error_message']) 234 | return None 235 | 236 | 237 | 238 | def get_sddcs_json(strProdURL, orgID, sessiontoken): 239 | """Returns list of all SDDCs in an Org via json""" 240 | myHeader = {'csp-auth-token': sessiontoken} 241 | myURL = f"{strProdURL}/vmc/api/orgs/{orgID}/sddcs" 242 | response = requests.get(myURL, headers=myHeader) 243 | json_response = response.json() 244 | if response.status_code == 200: 245 | return json_response 246 | else: 247 | vmc_error_handling(response) 248 | 249 | # Docs: https://developer.vmware.com/apis/vmc/latest/vmc/api/orgs/org/sddcs/sddc/get/ 250 | def get_sddc_info_json (strProdURL, orgID, sessiontoken, sddcID): 251 | """Returns SDDC info in JSON format. Returns None if error""" 252 | myHeader = {'csp-auth-token': sessiontoken} 253 | myURL = f"{strProdURL}/vmc/api/orgs/{orgID}/sddcs/{sddcID}" 254 | response = requests.get(myURL, headers=myHeader) 255 | json_response = response.json() 256 | if response.status_code == 200: 257 | return json_response 258 | else: 259 | print("There was an error. Check the syntax.") 260 | print(f'API call failed with status code {response.status_code}. URL: {myURL}.') 261 | if 'error_messages' in json_response: 262 | print(json_response['error_messages']) 263 | return None 264 | 265 | 266 | def get_sddc_cluster1_id(vmc_url, session_token, org_id, sddc_id): 267 | """Returns cluster ID for given SDDC""" 268 | my_header = {'csp-auth-token': session_token} 269 | my_url = f'{vmc_url}/vmc/api/orgs/{org_id}/sddcs/{sddc_id}' 270 | response = requests.get(my_url, headers=my_header) 271 | json_response = response.json() 272 | if response.status_code == 200: 273 | cluster_id = json_response['resource_config']['clusters'][0]['cluster_id'] 274 | return cluster_id 275 | else: 276 | vmc_error_handling(response) 277 | sys.exit(1) 278 | 279 | 280 | def post_cluster_rename_json(vmc_url, session_token, org_id, cluster_id, json_data): 281 | """Renames selected cluster""" 282 | header = {'csp-auth-token': session_token} 283 | url = f'{vmc_url}/api/inventory/{org_id}/vmc-aws/clusters/{cluster_id}:rename-cluster' 284 | response = requests.post(url, headers=header, json=json_data) 285 | if response.status_code != 202: 286 | vmc_error_handling(response) 287 | sys.exit(1) 288 | else: 289 | return response.status_code 290 | 291 | # ============================ 292 | # TKG 293 | # ============================ 294 | 295 | 296 | def tkg_validate_cluster_json(vmc_url, org_id, sddc_id, cluster_id, session_token): 297 | """Validates whether supplied cluster in provided SDDC can support a TKG deployment. Returns task-id""" 298 | my_header = {'csp-auth-token': session_token} 299 | my_url = f'{vmc_url}/api/wcp/v1/orgs/{org_id}/deployments/{sddc_id}/clusters/{cluster_id}/operations/validate-cluster' 300 | response = requests.post(my_url, headers=my_header) 301 | json_response = response.json() 302 | if response.status_code == 200: 303 | task_id = json_response ['id'] 304 | return task_id 305 | else: 306 | vmc_error_handling(response) 307 | sys.exit(1) 308 | 309 | 310 | def get_tkg_supported_clusters_json(vmc_url, session_token, org_id, sddc_id): 311 | """Gets all clusters in the SDDC with valid support for TKG. Returns Task-ID""" 312 | my_header = {'csp-auth-token': session_token} 313 | my_url = f'{vmc_url}/api/wcp/v1/orgs/{org_id}/deployments/{sddc_id}/operations/compute-supported-clusters' 314 | response = requests.post(my_url, headers=my_header) 315 | json_response = response.json() 316 | if response.status_code == 200: 317 | task_id = json_response['id'] 318 | return task_id 319 | else: 320 | vmc_error_handling(response) 321 | sys.exit(1) 322 | 323 | 324 | def tkg_validate_network_json(vmc_url, session_token, org_id, sddc_id, cluster_id, json_body): 325 | """Validates provided network CIDRs are eligible for TKG deployment in provided cluster""" 326 | my_header = {'csp-auth-token': session_token} 327 | my_url = f'{vmc_url}/api/wcp/v1/orgs/{org_id}/deployments/{sddc_id}/clusters/{cluster_id}/operations/validate-network' 328 | response = requests.post(my_url, json=json_body, headers=my_header) 329 | json_response = response.json() 330 | if response.status_code == 200: 331 | task_id = json_response ['id'] 332 | return task_id 333 | else: 334 | vmc_error_handling(response) 335 | sys.exit(1) 336 | 337 | 338 | def enable_tkg_json(vmc_url, session_token, org_id, sddc_id, cluster_id, json_body): 339 | """Enables TKG on selected cluster. Returns Task-ID""" 340 | my_header = {'csp-auth-token': session_token} 341 | my_url = f'{vmc_url}/api/wcp/v1/orgs/{org_id}/deployments/{sddc_id}/clusters/{cluster_id}/operations/enable-wcp' 342 | response = requests.post(my_url, json=json_body, headers=my_header) 343 | json_response = response.json() 344 | if response.status_code == 200: 345 | task_id = json_response ['id'] 346 | return task_id 347 | else: 348 | vmc_error_handling(response) 349 | sys.exit(1) 350 | 351 | 352 | def disable_tkg_json(vmc_url, session_token, org_id, sddc_id, cluster_id): 353 | """Disables TKG on selected cluster and returns task-id""" 354 | my_header = {'csp-auth-token': session_token} 355 | my_url = f'{vmc_url}/api/wcp/v1/orgs/{org_id}/deployments/{sddc_id}/clusters/{cluster_id}/operations/disable-wcp' 356 | response = requests.post(my_url, headers=my_header) 357 | json_response = response.json() 358 | if response.status_code == 200: 359 | task_id = json_response ['id'] 360 | return task_id 361 | else: 362 | vmc_error_handling(response) 363 | sys.exit(1) 364 | 365 | 366 | # ============================ 367 | # VTC - AWS Operations 368 | # ============================ 369 | def connect_aws_account_json(strProdURL, account, region, resource_id, org_id, session_token): 370 | """Connect an vTGW to an AWS account""" 371 | myHeader = {'csp-auth-token': session_token} 372 | myURL = "{}/api/network/{}/aws/operations".format(strProdURL, org_id) 373 | body = { 374 | "type": "ADD_EXTERNAL_ACCOUNT", 375 | "resource_id": resource_id, 376 | "resource_type": "network-connectivity-config", 377 | "config" : { 378 | "type": "AwsAddExternalAccountConfig", 379 | "account" : { 380 | "account_number": account, 381 | "regions" : [region], 382 | "auto_approval": "true" 383 | } 384 | } 385 | } 386 | response = requests.post(myURL, json=body, headers=myHeader) 387 | return response 388 | 389 | def disconnect_aws_account_json(strProdURL, account, resource_id, org_id, session_token): 390 | """Disconnect a vTGW from an AWS account""" 391 | myHeader = {'csp-auth-token': session_token} 392 | myURL = "{}/api/network/{}/aws/operations".format(strProdURL, org_id) 393 | body = { 394 | "type": "REMOVE_EXTERNAL_ACCOUNT", 395 | "resource_id": resource_id, 396 | "resource_type": "network-connectivity-config", 397 | "config" : { 398 | "type": "AwsRemoveExternalAccountConfig", 399 | "policy_id": resource_id, 400 | "account" : { 401 | # "account_id": "1ec4c61b-3bfe-697c-8756-0b3a226bb42f", 402 | "account_number": account 403 | } 404 | } 405 | } 406 | response = requests.post(myURL, json=body, headers=myHeader) 407 | return response 408 | 409 | 410 | # ============================ 411 | # VTC - DXGW Operations 412 | # ============================ 413 | def attach_dxgw_json(strProdURL, routes, resource_id, org_id, dxgw_owner, dxgw_id, region, session_token): 414 | """Attach a Direct Connect Gateway to a vTGW""" 415 | myHeader = {'csp-auth-token': session_token} 416 | myURL = "{}/api/network/{}/aws/operations".format(strProdURL, org_id) 417 | body = { 418 | "type": "ASSOCIATE_DIRECT_CONNECT_GATEWAY", 419 | "resource_id": resource_id, 420 | "resource_type": "network-connectivity-config", 421 | "config" : { 422 | "type": "AwsAssociateDirectConnectGatewayConfig", 423 | "direct_connect_gateway_association": { 424 | "direct_connect_gateway_id": dxgw_id, 425 | "direct_connect_gateway_owner": dxgw_owner, 426 | "peering_region_configs": [ 427 | { 428 | "allowed_prefixes": routes, 429 | "region": region 430 | } 431 | ] 432 | } 433 | } 434 | } 435 | response = requests.post(myURL, json=body, headers=myHeader) 436 | json_response = response.json() 437 | if response.status_code == 201: 438 | return json_response 439 | else: 440 | print("There was an error. Check the syntax.") 441 | print(f'API call failed with status code {response.status_code}. URL: {myURL}.') 442 | print(json_response['error_message']) 443 | return None 444 | 445 | def detach_dxgw_json(strProdURL, resource_id, org_id, dxgw_id, session_token): 446 | """Detach a Direct Connect Gateway from a vTGW""" 447 | myHeader = {'csp-auth-token': session_token} 448 | myURL = "{}/api/network/{}/aws/operations".format(strProdURL, org_id) 449 | body = { 450 | "type": "DISASSOCIATE_DIRECT_CONNECT_GATEWAY", 451 | "resource_id": resource_id, 452 | "resource_type": "network-connectivity-config", 453 | "config" : { 454 | "type": "AwsDisassociateDirectConnectGatewayConfig", 455 | "direct_connect_gateway_association": { 456 | "direct_connect_gateway_id": dxgw_id 457 | } 458 | } 459 | } 460 | response = requests.post(myURL, json=body, headers=myHeader) 461 | json_response = response.json() 462 | if response.status_code == 201: 463 | return json_response 464 | else: 465 | print("There was an error. Check the syntax.") 466 | print(f'API call failed with status code {response.status_code}. URL: {myURL}.') 467 | print(response) 468 | return None 469 | 470 | # ============================ 471 | # VTC - SDDC Operations 472 | # ============================ 473 | 474 | 475 | def config_sddc_group_json(prod_url, session_token, org_id, json_body): 476 | """Function to configure SDDC Group""" 477 | my_header = {'csp-auth-token': session_token} 478 | my_url = f'{prod_url}/api/network/{org_id}/aws/operations' 479 | response = requests.post(my_url, headers=my_header, json=json_body) 480 | json_response = response.json() 481 | if response.status_code == 200: 482 | return json_response 483 | else: 484 | vmc_error_handling(response) 485 | sys.exit(1) 486 | 487 | 488 | def attach_sddc_json(strProdURL, deployment_id, resource_id, org_id, session_token): 489 | """Attach an SDDC to a vTGW""" 490 | myHeader = {'csp-auth-token': session_token} 491 | myURL = "{}/api/network/{}/aws/operations".format(strProdURL, org_id) 492 | body = { 493 | "type": "UPDATE_MEMBERS", 494 | "resource_id": resource_id, 495 | "resource_type": "network-connectivity-config", 496 | "config" : { 497 | "type": "AwsUpdateDeploymentGroupMembersConfig", 498 | "add_members": [ 499 | { 500 | "id": deployment_id 501 | } 502 | ], 503 | "remove_members": [] 504 | } 505 | } 506 | response = requests.post(myURL, json=body, headers=myHeader) 507 | return response 508 | 509 | 510 | def remove_sddc_json(strProdURL, deployment_id, resource_id, org_id, session_token): 511 | """Detach an SDDC from a vTGW""" 512 | myHeader = {'csp-auth-token': session_token} 513 | myURL = "{}/api/network/{}/aws/operations".format(strProdURL, org_id) 514 | body = { 515 | "type": "UPDATE_MEMBERS", 516 | "resource_id": resource_id, 517 | "resource_type": "network-connectivity-config", 518 | "config" : { 519 | "type": "AwsUpdateDeploymentGroupMembersConfig", 520 | "add_members": [], 521 | "remove_members": [ 522 | { 523 | "id": deployment_id 524 | } 525 | ] 526 | } 527 | } 528 | response = requests.post(myURL, json=body, headers=myHeader) 529 | return response 530 | 531 | def get_nsx_info_json( strProdURL, org_id, deployment_id, session_token): 532 | """Display NSX credentials and URLs""" 533 | myHeader = {'csp-auth-token': session_token} 534 | myURL = f"{strProdURL}/api/network/{org_id}/core/deployments/{deployment_id}/nsx" 535 | response = requests.get(myURL, headers=myHeader) 536 | json_response = response.json() 537 | if response.status_code == 200: 538 | return json_response 539 | else: 540 | print("There was an error. Check the syntax.") 541 | print(f'API call failed with status code {response.status_code}. URL: {myURL}.') 542 | print(json_response['error_message']) 543 | return None 544 | 545 | 546 | # def get_deployment_id_json(strProdURL, org_id, session_token): 547 | # myHeader = {'csp-auth-token': session_token} 548 | # myURL = "{}/api/inventory/{}/core/deployments".format(strProdURL, org_id) 549 | # response = requests.get(myURL, headers=myHeader) 550 | # json_response = response.json() 551 | # if response.status_code == 200: 552 | # return json_response 553 | # else: 554 | # print("There was an error. Check the syntax.") 555 | # print(f'API call failed with status code {response.status_code}. URL: {myURL}.') 556 | # print(json_response['error_message']) 557 | 558 | def get_deployments_json(strProdURL,org_id, session_token): 559 | """Display a list of all SDDCs""" 560 | myHeader = {'csp-auth-token': session_token} 561 | myURL = "{}/api/inventory/{}/core/deployments".format(strProdURL, org_id) 562 | response = requests.get(myURL, headers=myHeader) 563 | json_response = response.json() 564 | if response.status_code == 200: 565 | return json_response 566 | else: 567 | print("There was an error. Check the syntax.") 568 | print(f'API call failed with status code {response.status_code}. URL: {myURL}.') 569 | print(json_response['error_message']) 570 | return None 571 | 572 | def get_group_id_json(strProdURL, group, org_id, session_token): 573 | myHeader = {'csp-auth-token': session_token} 574 | myURL = "{}/api/inventory/{}/core/deployment-groups".format(strProdURL, org_id) 575 | response = requests.get(myURL, headers=myHeader) 576 | json_response = response.json() 577 | if response.status_code == 200: 578 | return json_response 579 | else: 580 | print("There was an error. Check the syntax.") 581 | print(f'API call failed with status code {response.status_code}. URL: {myURL}.') 582 | print(json_response['error_message']) 583 | return None 584 | 585 | def get_resource_id_json(strProdURL, org_id, sddc_group_id, session_token): 586 | myHeader = {'csp-auth-token': session_token} 587 | myURL = "{}/api/network/{}/core/network-connectivity-configs/?group_id={}".format(strProdURL, org_id, sddc_group_id) 588 | response = requests.get(myURL, headers=myHeader) 589 | json_response = response.json() 590 | if response.status_code == 200: 591 | return json_response 592 | else: 593 | vmc_error_handling(response) 594 | sys.exit(1) 595 | 596 | def get_sddc_groups_json(strProdURL, org_id, session_token): 597 | myHeader = {'csp-auth-token': session_token} 598 | myURL = "{}/api/inventory/{}/core/deployment-groups".format(strProdURL, org_id) 599 | response = requests.get(myURL, headers=myHeader) 600 | json_response = response.json() 601 | if response.status_code == 200: 602 | return json_response 603 | else: 604 | print("There was an error. Check the syntax.") 605 | print(f'API call failed with status code {response.status_code}. URL: {myURL}.') 606 | print(json_response['error_message']) 607 | return None 608 | 609 | def get_task_status_json(strProdURL,task_id, org_id, session_token): 610 | myHeader = {'csp-auth-token': session_token} 611 | myURL = f"{strProdURL}/api/operation/{org_id}/core/operations/{task_id}" 612 | response = requests.get(myURL, headers=myHeader) 613 | if response.status_code == 200: 614 | json_response = response.json() 615 | return json_response 616 | else: 617 | vmc_error_handling(response) 618 | return None 619 | 620 | 621 | # ============================ 622 | # VTC - SDDC Group Operations 623 | # ============================ 624 | 625 | # 626 | # No documentation. Use the API explorer. 627 | # 628 | def create_sddc_group_json(strProdURL, name, description, members, org_id, session_token): 629 | """Create an SDDC group""" 630 | myHeader = {'csp-auth-token': session_token} 631 | 632 | myURL = f"{strProdURL}/api/network/{org_id}/core/network-connectivity-configs/create-group-network-connectivity" 633 | body = { 634 | "name": name, 635 | "description": description, 636 | "members": members 637 | } 638 | response = requests.post(myURL, json=body, headers=myHeader) 639 | json_response = response.json() 640 | if response.status_code == 200: 641 | return json_response 642 | else: 643 | vmc_error_handling(response) 644 | return None 645 | 646 | def delete_sddc_group_json(strProdURL, resource_id, org_id, session_token): 647 | myHeader = {'csp-auth-token': session_token} 648 | 649 | myURL = f'{strProdURL}/api/network/{org_id}/aws/operations' 650 | body = { 651 | "type": "DELETE_DEPLOYMENT_GROUP", 652 | "resource_id": resource_id, 653 | "resource_type": "network-connectivity-config", 654 | "config" : { 655 | "type": "AwsDeleteDeploymentGroupConfig" 656 | } 657 | } 658 | response = requests.post(myURL, json=body, headers=myHeader) 659 | if response.status_code not in (200,201,202): 660 | print(f"Error on delete call for resource_id: {resource_id}. Code: {response.status_code}, Message: {response.reason}") 661 | return None 662 | else: 663 | json_response = response.json() 664 | return json_response 665 | 666 | def get_group_info_json(strProdURL, org_id, group_id, session_token): 667 | """Display details for an SDDC group""" 668 | myHeader = {'csp-auth-token': session_token} 669 | myURL = f"{strProdURL}/api/inventory/{org_id}/core/deployment-groups/{group_id}" 670 | response = requests.get(myURL, headers=myHeader) 671 | json_response = response.json() 672 | if response.status_code == 200: 673 | return json_response 674 | else: 675 | print("There was an error. Check the syntax.") 676 | print(f'API call failed with status code {response.status_code}. URL: {myURL}.') 677 | 678 | def ext_get_group_info_json(strProdURL, org_id, resource_id, session_token): 679 | myHeader = {'csp-auth-token': session_token} 680 | myURL = "{}/api/network/{}/core/network-connectivity-configs/{}/?trait=AwsVpcAttachmentsTrait,AwsRealizedSddcConnectivityTrait,AwsDirectConnectGatewayAssociationsTrait,AwsNetworkConnectivityTrait".format(strProdURL, org_id, resource_id) 681 | response = requests.get(myURL, headers=myHeader) 682 | json_response = response.json() 683 | # print(json.dumps(json_response, indent = 2)) 684 | if response.status_code == 200: 685 | return json_response 686 | else: 687 | print("There was an error. Check the syntax.") 688 | print(f'API call failed with status code {response.status_code}. URL: {myURL}.') 689 | 690 | 691 | # ============================ 692 | # VTC - TGW Operations 693 | # ============================ 694 | def get_route_tables_json(strProdURL, resource_id, org_id, session_token): 695 | myHeader = {'csp-auth-token': session_token} 696 | myURL = "{}/api/network/{}/core/network-connectivity-configs/{}/route-tables".format(strProdURL, org_id, resource_id) 697 | response = requests.get(myURL, headers=myHeader) 698 | json_response = response.json() 699 | if response.status_code == 200: 700 | return json_response 701 | else: 702 | print("There was an error. Check the syntax.") 703 | print(f'API call failed with status code {response.status_code}. URL: {myURL}.') 704 | print(json_response['error_message']) 705 | 706 | def vtgw_route_json(strProdURL, org_id, resource_id, mem_ext_id,session_token): 707 | myHeader = {'csp-auth-token': session_token} 708 | myURL = "{}/api/network/{}/core/network-connectivity-configs/{}/route-tables/{}/routes".format(strProdURL, org_id, resource_id, mem_ext_id) 709 | response = requests.get(myURL, headers=myHeader) 710 | json_response = response.json() 711 | if response.status_code == 200: 712 | return json_response 713 | else: 714 | print("There was an error. Check the syntax.") 715 | print(f'API call failed with status code {response.status_code}. URL: {myURL}.') 716 | print(json_response['error_message']) 717 | 718 | 719 | # ============================ 720 | # VTC - VPC Operations 721 | # ============================ 722 | def attach_vpc_json(strProdURL, session_token, json_body, org_id): 723 | """Attach a VPC to a vTGW""" 724 | myHeader = {'csp-auth-token': session_token} 725 | myURL = "{}/api/network/{}/aws/operations".format(strProdURL, org_id) 726 | response = requests.post(myURL, json=json_body, headers=myHeader) 727 | json_response = response.json() 728 | if not response.ok : 729 | print (" Error: " + json_response['message']) 730 | sys.exit(1) 731 | else: 732 | return json_response 733 | 734 | def detach_vpc_json(strProdURL, session_token, json_body, org_id): 735 | """Detach a VPC from a vTGW""" 736 | myHeader = {'csp-auth-token': session_token} 737 | myURL = "{}/api/network/{}/aws/operations".format(strProdURL, org_id) 738 | response = requests.post(myURL, json=json_body, headers=myHeader) 739 | json_response = response.json() 740 | if not response.ok : 741 | print (" Error: " + json_response['message']) 742 | sys.exit(1) 743 | else: 744 | return json_response 745 | 746 | def add_vpc_prefixes_json(strProdURL, session_token, json_body, org_id): 747 | """Add or remove vTGW static routes""" 748 | myHeader = {'csp-auth-token': session_token} 749 | myURL = "{}/api/network/{}/aws/operations".format(strProdURL, org_id) 750 | response = requests.post(myURL, json=json_body, headers=myHeader) 751 | json_response = response.json() 752 | # pretty_data = json.dumps(response.json(), indent=4) 753 | # print(pretty_data) 754 | if not response.ok : 755 | print (" Error: " + json_response['message']) 756 | sys.exit(1) 757 | else: 758 | return json_response 759 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | certifi==2023.7.22 2 | charset-normalizer==3.1.0 3 | deepdiff==6.3 4 | idna==3.4 5 | ordered-set==4.1.0 6 | pandas==1.5.3 7 | prettytable==3.6.0 8 | requests==2.31.0 9 | urllib3==1.26.18 10 | wcwidth==0.2.6 11 | --------------------------------------------------------------------------------