diff --git a/tools/policy/poltool.py b/tools/policy/poltool.py index 71b3c039..9325a382 100755 --- a/tools/policy/poltool.py +++ b/tools/policy/poltool.py @@ -17,21 +17,21 @@ # # Examples: # -# Create network 'test' on provider provider_test: -# python poltool.py -o create -r network -i test -a "name=test" -# -a "provider=provider_test" -# List all networks: -# python poltool.py -o get -r network -# Show network 'test': -# python poltool.py -o get -r network -i test -# Create segment seg1 on network test: -# python poltool.py -o create -r network_segment -i "seg1" -a "name=seg1" -# -a "network_id=test" +# Create tier1 'test' on tier0 provider_test: +# python poltool.py -o create -r tier1 -i test -a "name=test" +# -a "tier0=provider_test" +# List all tier1s: +# python poltool.py -o get -r tier1 +# Show tier1 'test': +# python poltool.py -o get -r tier1 -i test +# Create segment seg1 on tier1 test: +# python poltool.py -o create -r tier1_segment -i "seg1" -a "name=seg1" +# -a "tier1_id=test" # -a "subnet:gateway_address=1.1.1.1/32" # Delete segment seg1: -# python poltool.py -o delete -r network_segment -i "test:seg1" -# Delete all segments under network test: -# python poltool.py -o delete -r network_segment -i "test:all" +# python poltool.py -o delete -r tier1_segment -i "test:seg1" +# Delete all segments under tier1 test: +# python poltool.py -o delete -r tier1_segment -i "test:all" import sys @@ -52,8 +52,8 @@ path.append(os.path.abspath("../../")) OPERATIONS = ("create", "update", "delete", "get") -RESOURCES = ("domain", "service", "icmp_service", "group", "network", - "segment", "network_segment") +RESOURCES = ("domain", "service", "icmp_service", "group", "tier1", + "segment", "tier1_segment") def get_resource_api(lib, resource_type): @@ -86,11 +86,14 @@ def build_args(resource_type, resource_id, args): from vmware_nsxlib.v3 import policy_defs if "_" in resource_type: - # handle cases like network_segment_id - # type is network_segment, but id parameter is segment_id + # handle cases like tier1_segment_id + # type is tier1_segment, but id parameter is segment_id resource_type = "_".join(resource_type.split("_")[1:]) args["%s_id" % resource_type] = resource_id + if "name" not in args: + args["name"] = resource_id + subresources = {} for arg, value in args.items(): if ":" in arg: diff --git a/tools/policy/sanity.txt b/tools/policy/sanity.txt index 6bd2fc4e..78cccfd8 100644 --- a/tools/policy/sanity.txt +++ b/tools/policy/sanity.txt @@ -18,9 +18,19 @@ python poltool.py -o create -r icmp_service -i service2 -a "name=sanity" -a "icm python poltool.py -o update -r icmp_service -i service2 -a "name=insane" python poltool.py -o get -r icmp_service -i service2 -# TODO: networks, segments, network segments, comm maps, enforcement points, sites +# TIER-0 "test" needs to be pre-created for below +# tier-1s +python poltool.py -o create -r tier1 -i router1 -a "name=sanity" -a "tier0=test" +python poltool.py -o update -r tier1 -i router1 -a "name=insane" +python poltool.py -o get -r tier1 -i router1 + +# infra segments +python poltool.py -o create -r segment -i seg1 -a "name=sanity" -a "subnet:gateway_address=1.1.1.1/32" +python poltool.py -o create -r segment -i seg1 -a "name=insane" # cleanup +python poltool.py -o delete -r segment -i seg1 +python poltool.py -o delete -r tier1 -i router1 python poltool.py -o delete -r service -i service1 python poltool.py -o delete -r icmp_service -i service2 python poltool.py -o delete -r group -i "domain1:all" diff --git a/vmware_nsxlib/v3/__init__.py b/vmware_nsxlib/v3/__init__.py index 441c8c04..3da3c95e 100644 --- a/vmware_nsxlib/v3/__init__.py +++ b/vmware_nsxlib/v3/__init__.py @@ -386,8 +386,8 @@ class NsxPolicyLib(NsxLibBase): self.ip_protocol_service = ( policy_resources.NsxPolicyIPProtocolServiceApi( self.policy_api)) - self.network = policy_resources.NsxPolicyNetworkApi(self.policy_api) - self.network_segment = policy_resources.NsxPolicyNetworkSegmentApi( + self.tier1 = policy_resources.NsxPolicyTier1Api(self.policy_api) + self.tier1_segment = policy_resources.NsxPolicyTier1SegmentApi( self.policy_api) self.segment = policy_resources.NsxPolicySegmentApi(self.policy_api) self.comm_map = policy_resources.NsxPolicyCommunicationMapApi( diff --git a/vmware_nsxlib/v3/policy_constants.py b/vmware_nsxlib/v3/policy_constants.py index 546492ef..221eb9eb 100644 --- a/vmware_nsxlib/v3/policy_constants.py +++ b/vmware_nsxlib/v3/policy_constants.py @@ -45,3 +45,7 @@ CATEGORY_ENVIRONMENT = 'Environment' CATEGORY_APPLICATION = 'Application' ACTIVE_STANDBY = 'ACTIVE_STANDBY' +ACTIVE_ACTIVE = 'ACTIVE_ACTIVE' + +PREEMPTIVE = 'PREEMPTIVE' +NON_PREEMPTIVE = 'NON_PREEMPTIVE' diff --git a/vmware_nsxlib/v3/policy_defs.py b/vmware_nsxlib/v3/policy_defs.py index 85bcb0fc..8140480c 100644 --- a/vmware_nsxlib/v3/policy_defs.py +++ b/vmware_nsxlib/v3/policy_defs.py @@ -23,7 +23,7 @@ from vmware_nsxlib.v3 import policy_constants TENANTS_PATH_PATTERN = "%s/" DOMAINS_PATH_PATTERN = TENANTS_PATH_PATTERN + "domains/" PROVIDERS_PATH_PATTERN = TENANTS_PATH_PATTERN + "providers/" -NETWORKS_PATH_PATTERN = TENANTS_PATH_PATTERN + "networks/" +TIER1S_PATH_PATTERN = TENANTS_PATH_PATTERN + "tier-1s/" SERVICES_PATH_PATTERN = TENANTS_PATH_PATTERN + "services/" REALIZED_STATE_EF = (TENANTS_PATH_PATTERN + "realized-state/enforcement-points/%s/") @@ -153,27 +153,57 @@ class DomainDef(ResourceDef): return ('tenant', 'domain_id') -class NetworkDef(ResourceDef): +class RouteAdvertisement(object): + + types = {'static_routes': 'TIER1_STATIC_ROUTES', + 'subnets': 'TIER1_SUBNETS', + 'nat': 'TIER1_NAT', + 'lb_vip': 'TIER1_LB_VIP', + 'lb_snat': 'TIER1_LB_SNAT'} + + def __init__(self, + static_routes=False, + subnets=False, + nat=False, + lb_vip=False, + lb_snat=False): + self.static_routes = static_routes + self.subnets = subnets + self.nat = nat + self.lb_vip = lb_vip + self.lb_snat = lb_snat + + def get_obj_dict(self): + return [value for key, value in self.types.items() + if getattr(self, key)] + + +class Tier1Def(ResourceDef): @property def path_pattern(self): - return NETWORKS_PATH_PATTERN + return TIER1S_PATH_PATTERN @property def path_ids(self): - return ('tenant', 'network_id') + return ('tenant', 'tier1_id') def get_obj_dict(self): - body = super(NetworkDef, self).get_obj_dict() - # TODO(annak): replace with provider path when provider is exposed - body['provider'] = "/" + TENANTS_PATH_PATTERN % self.get_tenant() + \ - "providers/" + self.get_attr('provider') + body = super(Tier1Def, self).get_obj_dict() - for attr in ('ha_mode', 'force_whitelisting'): + # TODO(annak): replace with provider path when provider is exposed + tier0 = self.get_attr('tier0') + if tier0: + tenant = TENANTS_PATH_PATTERN % self.get_tenant() + body['tier0_path'] = "/%stier-0s/%s" % (tenant, tier0) + + for attr in ('failover_mode', 'force_whitelisting'): body[attr] = self.get_attr(attr) - if self.get_attr('ip_addresses'): - body['ip_addresses'] = self.get_attr('ip_addresses') + if self.get_attr('route_adv'): + body['route_advertisement_types'] = self.get_attr( + 'route_adv').get_obj_dict() + return body @@ -204,22 +234,22 @@ class BaseSegmentDef(ResourceDef): return body -class NetworkSegmentDef(BaseSegmentDef): - '''Network segments can not move to different network ''' +class Tier1SegmentDef(BaseSegmentDef): + '''Tier1 segments can not move to different tier1 ''' @property def path_pattern(self): - return NETWORKS_PATH_PATTERN + "%s/segments/" + return TIER1S_PATH_PATTERN + "%s/segments/" @property def path_ids(self): - return ('tenant', 'network_id', 'segment_id') + return ('tenant', 'tier1_id', 'segment_id') class SegmentDef(BaseSegmentDef): - '''These segments don't belong to particular network. + '''These segments don't belong to particular tier1. - And can be attached and re-attached to different networks + And can be attached and re-attached to different tier1s ''' @property @@ -230,6 +260,15 @@ class SegmentDef(BaseSegmentDef): def path_ids(self): return ('tenant', 'segment_id') + def get_obj_dict(self): + body = super(SegmentDef, self).get_obj_dict() + if self.get_attr('tier1_id'): + tier1 = Tier1Def(tier1_id=self.get_attr('tier1_id'), + tenant=self.get_tenant()) + body['connectivity_path'] = tier1.get_resource_full_path() + # TODO(annak): support also tier0 + return body + class Condition(object): def __init__(self, value, key=policy_constants.CONDITION_KEY_TAG, diff --git a/vmware_nsxlib/v3/policy_resources.py b/vmware_nsxlib/v3/policy_resources.py index 8199d39f..085e09fc 100644 --- a/vmware_nsxlib/v3/policy_resources.py +++ b/vmware_nsxlib/v3/policy_resources.py @@ -54,10 +54,6 @@ class NsxPolicyResourceBase(object): def create_or_overwrite(self, *args, **kwargs): pass - @abc.abstractmethod - def update(self, uuid, *args, **kwargs): - pass - @staticmethod def _init_obj_uuid(obj_uuid): if not obj_uuid: @@ -473,68 +469,75 @@ class NsxPolicyIPProtocolServiceApi(NsxPolicyServiceBase): protocol_number=protocol_number) -class NsxPolicyNetworkApi(NsxPolicyResourceBase): - """NSX Network API """ +# TODO(annak): add/remove route specific advertisement +class NsxPolicyTier1Api(NsxPolicyResourceBase): + """NSX Tier1 API """ @property def entry_def(self): - return policy_defs.NetworkDef + return policy_defs.Tier1Def - def create_or_overwrite(self, name, network_id=None, description=None, - provider=None, - ip_addresses=None, - ha_mode=policy_constants.ACTIVE_STANDBY, + def build_route_advertisement(self, static_routes=False, subnets=False, + nat=False, lb_vip=False, lb_snat=False): + return policy_defs.RouteAdvertisement(static_routes, subnets, + nat, lb_vip, lb_snat) + + def create_or_overwrite(self, name, tier1_id=None, description=None, + tier0=None, force_whitelisting=False, + failover_mode=policy_constants.NON_PREEMPTIVE, + route_advertisement=None, tags=None, tenant=policy_constants.POLICY_INFRA_TENANT): - network_id = self._init_obj_uuid(network_id) - network_def = self.entry_def(network_id=network_id, - name=name, - description=description, - provider=provider, - ip_addresses=ip_addresses, - ha_mode=ha_mode, - force_whitelisting=force_whitelisting, - tags=tags, - tenant=tenant) - return self.policy_api.create_or_update(network_def) + tier1_id = self._init_obj_uuid(tier1_id) + tier1_def = self.entry_def(tier1_id=tier1_id, + name=name, + description=description, + tier0=tier0, + force_whitelisting=force_whitelisting, + tags=tags, + failover_mode=failover_mode, + route_advertisement=route_advertisement, + tenant=tenant) + return self.policy_api.create_or_update(tier1_def) - def delete(self, network_id, tenant=policy_constants.POLICY_INFRA_TENANT): - network_def = self.entry_def(network_id=network_id, tenant=tenant) - self.policy_api.delete(network_def) + def delete(self, tier1_id, tenant=policy_constants.POLICY_INFRA_TENANT): + tier1_def = self.entry_def(tier1_id=tier1_id, tenant=tenant) + self.policy_api.delete(tier1_def) - def get(self, network_id, tenant=policy_constants.POLICY_INFRA_TENANT): - network_def = self.entry_def(network_id=network_id, tenant=tenant) - return self.policy_api.get(network_def) + def get(self, tier1_id, tenant=policy_constants.POLICY_INFRA_TENANT): + tier1_def = self.entry_def(tier1_id=tier1_id, tenant=tenant) + return self.policy_api.get(tier1_def) def list(self, tenant=policy_constants.POLICY_INFRA_TENANT): - network_def = self.entry_def(tenant=tenant) - return self.policy_api.list(network_def)['results'] + tier1_def = self.entry_def(tenant=tenant) + return self.policy_api.list(tier1_def)['results'] - def update(self, network_id, name=None, description=None, - ip_addresses=None, ha_mode=None, + def update(self, tier1_id, name=None, description=None, force_whitelisting=None, + failover_mode=None, + route_advertisement=None, tags=None, tenant=policy_constants.POLICY_INFRA_TENANT): - network_def = policy_defs.NetworkDef(network_id=network_id, - tenant=tenant) - network_def.update_attributes_in_body( + tier1_def = policy_defs.Tier1Def(tier1_id=tier1_id, + tenant=tenant) + tier1_def.update_attributes_in_body( name=name, description=description, - ip_addresses=ip_addresses, - ha_mode=ha_mode, force_whitelisting=force_whitelisting, + failover_mode=failover_mode, + route_advertisement=route_advertisement, tags=tags) - return self.policy_api.create_or_update(network_def) + return self.policy_api.create_or_update(tier1_def) -class NsxPolicyNetworkSegmentApi(NsxPolicyResourceBase): - """NSX Network Segment API """ +class NsxPolicyTier1SegmentApi(NsxPolicyResourceBase): + """NSX Tier1 Segment API """ @property def entry_def(self): - return policy_defs.NetworkSegmentDef + return policy_defs.Tier1SegmentDef - def create_or_overwrite(self, name, network_id=None, + def create_or_overwrite(self, name, tier1_id=None, segment_id=None, description=None, subnets=None, dns_domain_name=None, @@ -543,7 +546,7 @@ class NsxPolicyNetworkSegmentApi(NsxPolicyResourceBase): tenant=policy_constants.POLICY_INFRA_TENANT): segment_id = self._init_obj_uuid(segment_id) - segment_def = self.entry_def(network_id=network_id, + segment_def = self.entry_def(tier1_id=tier1_id, segment_id=segment_id, name=name, description=description, @@ -554,49 +557,35 @@ class NsxPolicyNetworkSegmentApi(NsxPolicyResourceBase): tenant=tenant) return self.policy_api.create_or_update(segment_def) - def delete(self, network_id, segment_id, + def delete(self, tier1_id, segment_id, tenant=policy_constants.POLICY_INFRA_TENANT): - segment_def = self.entry_def(network_id=network_id, + segment_def = self.entry_def(tier1_id=tier1_id, segment_id=segment_id, tenant=tenant) self.policy_api.delete(segment_def) - def get(self, network_id, segment_id, + def get(self, tier1_id, segment_id, tenant=policy_constants.POLICY_INFRA_TENANT): - segment_def = self.entry_def(network_id=network_id, + segment_def = self.entry_def(tier1_id=tier1_id, segment_id=segment_id, tenant=tenant) return self.policy_api.get(segment_def) - def list(self, network_id, tenant=policy_constants.POLICY_INFRA_TENANT): - segment_def = self.entry_def(network_id=network_id, tenant=tenant) + def list(self, tier1_id, tenant=policy_constants.POLICY_INFRA_TENANT): + segment_def = self.entry_def(tier1_id=tier1_id, tenant=tenant) return self.policy_api.list(segment_def)['results'] - def update(self, network_id, segment_id, - name=None, description=None, - subnets=None, tags=None, - dns_domain_name=None, - vlan_ids=None, - tenant=policy_constants.POLICY_INFRA_TENANT): - segment_def = self.entry_def(network_id, segment_id, tenant=tenant) - segment_def.update_attributes_in_body( - name=name, - description=description, - subnets=subnets, - dns_domain_name=dns_domain_name, - vlan_ids=vlan_ids, - tags=tags) - return self.policy_api.create_or_update(segment_def) - class NsxPolicySegmentApi(NsxPolicyResourceBase): - """NSX Network Segment API """ + """NSX Tier1 Segment API """ @property def entry_def(self): return policy_defs.SegmentDef - def create_or_overwrite(self, name, network_id=None, - segment_id=None, description=None, + def create_or_overwrite(self, name, + segment_id=None, + tier1_id=None, + description=None, subnets=None, dns_domain_name=None, vlan_ids=None, @@ -607,6 +596,7 @@ class NsxPolicySegmentApi(NsxPolicyResourceBase): segment_def = self.entry_def(segment_id=segment_id, name=name, description=description, + tier1_id=tier1_id, subnets=subnets, dns_domain_name=dns_domain_name, vlan_ids=vlan_ids, @@ -628,22 +618,6 @@ class NsxPolicySegmentApi(NsxPolicyResourceBase): segment_def = self.entry_def(tenant=tenant) return self.policy_api.list(segment_def)['results'] - def update(self, segment_id, - name=None, description=None, - subnets=None, tags=None, - dns_domain_name=None, - vlan_ids=None, - tenant=policy_constants.POLICY_INFRA_TENANT): - segment_def = self.entry_def(segment_id=segment_id, tenant=tenant) - segment_def.update_attributes_in_body( - name=name, - description=description, - subnets=subnets, - dns_domain_name=dns_domain_name, - vlan_ids=vlan_ids, - tags=tags) - return self.policy_api.create_or_update(segment_def) - class NsxPolicyCommunicationMapApi(NsxPolicyResourceBase): """NSX Policy CommunicationMap (Under a Domain)."""