2018-04-23 21:58:05 -04:00
|
|
|
#!/usr/bin/env python
|
|
|
|
|
|
|
|
"""
|
|
|
|
* *******************************************************
|
|
|
|
* Copyright (c) VMware, Inc. 2018. All Rights Reserved.
|
|
|
|
* SPDX-License-Identifier: MIT
|
|
|
|
* *******************************************************
|
|
|
|
*
|
|
|
|
* DISCLAIMER. THIS PROGRAM IS PROVIDED TO YOU "AS IS" WITHOUT
|
|
|
|
* WARRANTIES OR CONDITIONS OF ANY KIND, WHETHER ORAL OR WRITTEN,
|
|
|
|
* EXPRESS OR IMPLIED. THE AUTHOR SPECIFICALLY DISCLAIMS ANY IMPLIED
|
|
|
|
* WARRANTIES OR CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY,
|
|
|
|
* NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
"""
|
|
|
|
|
|
|
|
__author__ = 'VMware, Inc.'
|
|
|
|
__vcenter_version__ = 'VMware Cloud on AWS'
|
|
|
|
|
|
|
|
import random
|
|
|
|
|
2019-08-20 02:54:24 -04:00
|
|
|
from samples.vmc.helpers.sample_cli import parser, required_args, optional_args
|
2018-04-23 21:58:05 -04:00
|
|
|
from com.vmware.vmc.model_client import *
|
|
|
|
from vmware.vapi.vmc.client import create_vmc_client
|
|
|
|
from samples.vmc.helpers.vmc_task_helper import wait_for_task
|
|
|
|
|
|
|
|
|
|
|
|
class ExposePublicIP(object):
|
|
|
|
"""
|
|
|
|
Demo steps required to expose a VM to public internet
|
|
|
|
1. Request a public IP address
|
|
|
|
2. Add a firewall rule on compute gateway to access to the VM
|
|
|
|
3. Create a NAT rule to forward traffic from public IP to private IP
|
|
|
|
|
|
|
|
Sample Prerequisites:
|
|
|
|
- A VM deployed inside the SDDC with private IP address
|
|
|
|
"""
|
|
|
|
|
|
|
|
def __init__(self):
|
2019-08-20 02:54:24 -04:00
|
|
|
optional_args.add_argument('--notes',
|
2018-04-23 21:58:05 -04:00
|
|
|
default='Sample public IP ' + str(random.randint(0, 100)),
|
|
|
|
help='Notes of the new public IP')
|
|
|
|
|
2019-08-20 02:54:24 -04:00
|
|
|
optional_args.add_argument('--fw-rule-name',
|
2018-04-23 21:58:05 -04:00
|
|
|
default='Sample firewall rule ' + str(random.randint(0, 100)),
|
|
|
|
help='Name of the compute gae')
|
|
|
|
|
2019-08-20 02:54:24 -04:00
|
|
|
optional_args.add_argument('--nat-rule-description',
|
2018-04-23 21:58:05 -04:00
|
|
|
default='Sample NAT rule ' + str(random.randint(0, 100)),
|
|
|
|
help='Description for the NAT rule')
|
|
|
|
|
2019-08-20 02:54:24 -04:00
|
|
|
required_args.add_argument('--internal-ip',
|
2018-04-23 21:58:05 -04:00
|
|
|
required=True,
|
|
|
|
help='Private IP of the VM')
|
|
|
|
|
2019-08-20 02:54:24 -04:00
|
|
|
optional_args.add_argument('--cleardata',
|
2018-04-23 21:58:05 -04:00
|
|
|
action='store_true',
|
|
|
|
help='Clean up after sample run')
|
|
|
|
args = parser.parse_args()
|
|
|
|
|
|
|
|
self.network_id = None
|
|
|
|
self.edge_id = None
|
|
|
|
self.nat_rule_id = None
|
|
|
|
self.public_ip = None
|
|
|
|
self.nfwr = None
|
|
|
|
self.org_id = args.org_id
|
|
|
|
self.sddc_id = args.sddc_id
|
|
|
|
self.notes = args.notes
|
|
|
|
self.fw_rule_name = args.fw_rule_name
|
|
|
|
self.nat_rule_description = args.nat_rule_description
|
|
|
|
self.internal_ip = args.internal_ip
|
|
|
|
self.cleardata = args.cleardata
|
|
|
|
self.vmc_client = create_vmc_client(args.refresh_token)
|
|
|
|
|
|
|
|
def setup(self):
|
|
|
|
# Check if the organization exists
|
|
|
|
orgs = self.vmc_client.Orgs.list()
|
|
|
|
if self.org_id not in [org.id for org in orgs]:
|
|
|
|
raise ValueError("Org with ID {} doesn't exist".format(self.org_id))
|
|
|
|
|
|
|
|
# Check if the SDDC exists
|
|
|
|
sddcs = self.vmc_client.orgs.Sddcs.list(self.org_id)
|
|
|
|
if self.sddc_id not in [sddc.id for sddc in sddcs]:
|
|
|
|
raise ValueError("SDDC with ID {} doesn't exist in org {}".
|
|
|
|
format(self.sddc_id, self.org_id))
|
|
|
|
|
|
|
|
edges = self.vmc_client.orgs.sddcs.networks.Edges.get(
|
|
|
|
org=self.org_id,
|
|
|
|
sddc=self.sddc_id,
|
|
|
|
edge_type='gatewayServices').edge_page.data
|
|
|
|
print('\n# Setup: Compute Gateway ID: {}'.format(edges[1].id))
|
|
|
|
self.edge_id = edges[1].id
|
|
|
|
|
|
|
|
def request_public_ip(self):
|
|
|
|
print('\n# Example: Request a new IP for SDDC')
|
|
|
|
ip_spec = SddcAllocatePublicIpSpec(names=[self.notes], count=1)
|
|
|
|
task = self.vmc_client.orgs.sddcs.Publicips.create(
|
|
|
|
org=self.org_id,
|
|
|
|
sddc=self.sddc_id,
|
|
|
|
spec=ip_spec)
|
|
|
|
|
|
|
|
wait_for_task(task_client=self.vmc_client.orgs.Tasks,
|
|
|
|
org_id=self.org_id,
|
|
|
|
task_id=task.id,
|
|
|
|
interval_sec=2)
|
|
|
|
|
|
|
|
ips = self.vmc_client.orgs.sddcs.Publicips.list(
|
|
|
|
org=self.org_id,
|
|
|
|
sddc=self.sddc_id)
|
|
|
|
|
|
|
|
for ip in ips:
|
|
|
|
if ip.name == self.notes:
|
|
|
|
self.ip_id = ip.allocation_id
|
|
|
|
self.public_ip = ip.public_ip
|
|
|
|
print('# Successfully requested public IP {}'.
|
|
|
|
format(ip.public_ip))
|
|
|
|
break
|
|
|
|
else:
|
|
|
|
raise Exception("Can't find public IP with notes {}".
|
|
|
|
format(self.notes))
|
|
|
|
|
|
|
|
def create_firewall_rule_on_cgw(self):
|
|
|
|
|
|
|
|
print('\n# Example: Add a firewall rule to the compute gateway')
|
|
|
|
|
|
|
|
# Construct a new NSX firewall rule object
|
|
|
|
# which allow any to any traffic
|
|
|
|
self.nfwr = Nsxfirewallrule(rule_type='user',
|
|
|
|
name=self.fw_rule_name,
|
|
|
|
enabled=True,
|
|
|
|
action='accept',
|
|
|
|
source=AddressFWSourceDestination(
|
|
|
|
exclude=False,
|
|
|
|
ip_address=['any'],
|
|
|
|
grouping_object_id=[],
|
|
|
|
vnic_group_id=[]),
|
|
|
|
destination=AddressFWSourceDestination(
|
|
|
|
exclude=False,
|
|
|
|
ip_address=['any'],
|
|
|
|
grouping_object_id=[],
|
|
|
|
vnic_group_id=[]),
|
|
|
|
logging_enabled=False,
|
|
|
|
application=None)
|
|
|
|
|
|
|
|
self.vmc_client.orgs.sddcs.networks.edges.firewall.config.Rules.add(
|
|
|
|
org=self.org_id,
|
|
|
|
sddc=self.sddc_id,
|
|
|
|
edge_id=self.edge_id,
|
|
|
|
firewall_rules=FirewallRules([self.nfwr]))
|
|
|
|
|
2018-05-15 23:56:21 -04:00
|
|
|
print(' # New firewall rule "{}" is added'.format(self.fw_rule_name))
|
2018-04-23 21:58:05 -04:00
|
|
|
|
|
|
|
def create_net_rule(self):
|
|
|
|
|
|
|
|
print('\n# Example: Add a NAT rule to the compute gateway')
|
|
|
|
|
|
|
|
# Construct a new NSX NAT rule spec
|
|
|
|
rule = Nsxnatrule(vnic='0',
|
|
|
|
rule_type='user',
|
|
|
|
action='dnat', # Supported types are DNAT|SNAT
|
|
|
|
protocol='any',
|
|
|
|
description=self.nat_rule_description,
|
|
|
|
original_address=self.public_ip,
|
|
|
|
original_port='any',
|
|
|
|
translated_address=self.internal_ip,
|
|
|
|
translated_port='any',
|
|
|
|
enabled=True)
|
|
|
|
|
|
|
|
self.vmc_client.orgs.sddcs.networks.edges.nat.config.Rules.add(
|
|
|
|
org=self.org_id,
|
|
|
|
sddc=self.sddc_id,
|
|
|
|
edge_id=self.edge_id,
|
|
|
|
nat_rules=NatRules([rule]))
|
|
|
|
|
2018-05-15 23:56:21 -04:00
|
|
|
print(' # New NAT rule "{}" is added'.format(self.nat_rule_description))
|
2018-04-23 21:58:05 -04:00
|
|
|
|
|
|
|
def cleanup(self):
|
|
|
|
if self.cleardata:
|
|
|
|
|
|
|
|
# Delete the firewall rule
|
|
|
|
fw_rules = self.vmc_client.orgs.sddcs.networks.edges.firewall.Config.get(
|
|
|
|
org=self.org_id,
|
|
|
|
sddc=self.sddc_id,
|
|
|
|
edge_id=self.edge_id).firewall_rules.firewall_rules
|
|
|
|
|
|
|
|
for r in fw_rules:
|
|
|
|
if r.name == self.fw_rule_name:
|
|
|
|
self.vmc_client.orgs.sddcs.networks.edges.firewall.config.Rules.delete(
|
|
|
|
org=self.org_id,
|
|
|
|
sddc=self.sddc_id,
|
|
|
|
edge_id=self.edge_id,
|
|
|
|
rule_id=r.rule_id)
|
|
|
|
break
|
|
|
|
print('\n# Cleanup: Firewall rule {} is deleted'.
|
|
|
|
format(self.fw_rule_name))
|
|
|
|
|
|
|
|
# Delete the NAT rule
|
|
|
|
rules = self.vmc_client.orgs.sddcs.networks.edges.nat.Config.get(
|
|
|
|
org=self.org_id,
|
|
|
|
sddc=self.sddc_id,
|
|
|
|
edge_id=self.edge_id).rules.nat_rules_dtos
|
|
|
|
for rule in rules:
|
|
|
|
if rule.description == self.nat_rule_description:
|
|
|
|
self.vmc_client.orgs.sddcs.networks.edges.nat.config.Rules.delete(
|
|
|
|
org=self.org_id,
|
|
|
|
sddc=self.sddc_id,
|
|
|
|
edge_id=self.edge_id,
|
|
|
|
rule_id=rule.rule_id)
|
|
|
|
print('\n# Cleanup: NAT rule "{}" is deleted'.
|
|
|
|
format(self.nat_rule_description))
|
|
|
|
|
|
|
|
# Release the public IP address
|
|
|
|
self.vmc_client.orgs.sddcs.Publicips.delete(
|
|
|
|
org=self.org_id,
|
|
|
|
sddc=self.sddc_id,
|
|
|
|
id=self.ip_id)
|
|
|
|
print('\n# Cleanup: Public IP "{}" is released'.
|
|
|
|
format(self.public_ip))
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
expose_public_ip = ExposePublicIP()
|
|
|
|
expose_public_ip.setup()
|
|
|
|
expose_public_ip.request_public_ip()
|
|
|
|
expose_public_ip.create_firewall_rule_on_cgw()
|
|
|
|
expose_public_ip.create_net_rule()
|
|
|
|
expose_public_ip.cleanup()
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
main()
|