diff --git a/tools/policy/poltool.py b/tools/policy/poltool.py index 47eca3ad..0b3626a6 100644 --- a/tools/policy/poltool.py +++ b/tools/policy/poltool.py @@ -25,13 +25,13 @@ # Show network 'test': # python poltool.py -o get -r network -i test # Create segment seg1 on network test: -# python poltool.py -o create -r segment -i "seg1" -a "name=seg1" +# python poltool.py -o create -r network_segment -i "seg1" -a "name=seg1" # -a "network_id=test" # -a "subnet:gateway_address=1.1.1.1/32" # Delete segment seg1: -# python poltool.py -o delete -r segment -i "test:seg1" +# python poltool.py -o delete -r network_segment -i "test:seg1" # Delete all segments under network test: -# python poltool.py -o delete -r segment -i "test:all" +# python poltool.py -o delete -r network_segment -i "test:all" import copy @@ -45,7 +45,8 @@ path.append(os.path.abspath("../../")) OPERATIONS = ("create", "update", "delete", "get") -RESOURCES = ("domain", "service", "group", "network", "segment") +RESOURCES = ("domain", "service", "group", "network", + "segment", "network_segment") def get_resource_api(lib, resource_type): @@ -58,13 +59,18 @@ def build_ids(resource_id): def get_resource(lib, resource_type, resource_id): + from vmware_nsxlib.v3 import exceptions as exc api = get_resource_api(lib, resource_type) ids = build_ids(resource_id) - if ids[-1] == "all": - result = api.list(*ids[:-1]) - else: - result = api.get(*ids) + try: + if ids[-1] == "all": + result = api.list(*ids[:-1]) + else: + result = api.get(*ids) + except exc.ResourceNotFound: + print("Resource of type %s %s not found" % (resource_type, ids)) + sys.exit(2) return result @@ -72,6 +78,11 @@ def get_resource(lib, resource_type, resource_id): 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 + resource_type = "_".join(resource_type.split("_")[1:]) + args["%s_id" % resource_type] = resource_id subresources = {} for arg, value in args.items(): diff --git a/vmware_nsxlib/v3/__init__.py b/vmware_nsxlib/v3/__init__.py index ec7ca66b..441c8c04 100644 --- a/vmware_nsxlib/v3/__init__.py +++ b/vmware_nsxlib/v3/__init__.py @@ -387,6 +387,8 @@ class NsxPolicyLib(NsxLibBase): policy_resources.NsxPolicyIPProtocolServiceApi( self.policy_api)) self.network = policy_resources.NsxPolicyNetworkApi(self.policy_api) + self.network_segment = policy_resources.NsxPolicyNetworkSegmentApi( + self.policy_api) self.segment = policy_resources.NsxPolicySegmentApi(self.policy_api) self.comm_map = policy_resources.NsxPolicyCommunicationMapApi( self.policy_api) diff --git a/vmware_nsxlib/v3/policy_defs.py b/vmware_nsxlib/v3/policy_defs.py index f7b49627..9757de04 100644 --- a/vmware_nsxlib/v3/policy_defs.py +++ b/vmware_nsxlib/v3/policy_defs.py @@ -196,7 +196,40 @@ class Subnet(object): # TODO(annak) - add advanced config when supported by platform -class SegmentDef(ResourceDef): +class BaseSegmentDef(ResourceDef): + def __init__(self, + segment_id=None, + name=None, + description=None, + subnets=None, + dns_domain_name=None, + vlan_ids=None, + tenant=policy_constants.POLICY_INFRA_TENANT): + super(BaseSegmentDef, self).__init__() + self.tenant = tenant + self.id = segment_id + self.name = name + self.description = description + self.dns_domain_name = dns_domain_name + self.vlan_ids = vlan_ids + self.subnets = subnets + self.parent_ids = (tenant) + + def get_obj_dict(self): + body = super(BaseSegmentDef, self).get_obj_dict() + if self.subnets: + body['subnets'] = [subnet.get_obj_dict() + for subnet in self.subnets] + if self.dns_domain_name: + body['domain_name'] = self.dns_domain_name + if self.vlan_ids: + body['vlan_ids'] = self.vlan_ids + return body + + +class NetworkSegmentDef(BaseSegmentDef): + '''Network segments can not move to different network ''' + def __init__(self, network_id, segment_id=None, @@ -206,30 +239,25 @@ class SegmentDef(ResourceDef): dns_domain_name=None, vlan_ids=None, tenant=policy_constants.POLICY_INFRA_TENANT): - super(SegmentDef, self).__init__() - self.tenant = tenant - self.id = segment_id - self.name = name - self.description = description - self.dns_domain_name = dns_domain_name - self.vlan_ids = vlan_ids - self.subnets = subnets + super(NetworkSegmentDef, self).__init__(segment_id, name, description, + subnets, dns_domain_name, + vlan_ids) self.parent_ids = (tenant, network_id) @property def path_pattern(self): return NETWORKS_PATH_PATTERN + "%s/segments/" - def get_obj_dict(self): - body = super(SegmentDef, self).get_obj_dict() - if self.subnets: - body['subnets'] = [subnet.get_obj_dict() - for subnet in self.subnets] - if self.dns_domain_name: - body['domain_name'] = self.dns_domain_name - if self.vlan_ids: - body['vlan_ids'] = self.vlan_ids - return body + +class SegmentDef(BaseSegmentDef): + '''These segments don't belong to particular network. + + And can be attached and re-attached to different networks + ''' + + @property + def path_pattern(self): + return TENANTS_PATH_PATTERN + "segments/" class Condition(object): diff --git a/vmware_nsxlib/v3/policy_resources.py b/vmware_nsxlib/v3/policy_resources.py index 5c3fa0ab..bc77b33a 100644 --- a/vmware_nsxlib/v3/policy_resources.py +++ b/vmware_nsxlib/v3/policy_resources.py @@ -537,11 +537,11 @@ class NsxPolicyNetworkApi(NsxPolicyResourceBase): return self.policy_api.create_or_update(network_def) -class NsxPolicySegmentApi(NsxPolicyResourceBase): +class NsxPolicyNetworkSegmentApi(NsxPolicyResourceBase): """NSX Network Segment API """ @property def entry_def(self): - return policy_defs.SegmentDef + return policy_defs.NetworkSegmentDef def create_or_overwrite(self, name, network_id=None, segment_id=None, description=None, @@ -595,6 +595,63 @@ class NsxPolicySegmentApi(NsxPolicyResourceBase): return self.policy_api.create_or_update(segment_def) +class NsxPolicySegmentApi(NsxPolicyResourceBase): + """NSX Network 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, + subnets=None, + dns_domain_name=None, + vlan_ids=None, + tags=None, + tenant=policy_constants.POLICY_INFRA_TENANT): + + segment_id = self._init_obj_uuid(segment_id) + segment_def = self.entry_def(segment_id=segment_id, + name=name, + description=description, + subnets=subnets, + dns_domain_name=dns_domain_name, + vlan_ids=vlan_ids, + tenant=tenant) + if tags: + segment_def.add_tags(tags) + return self.policy_api.create_or_update(segment_def) + + def delete(self, segment_id, + tenant=policy_constants.POLICY_INFRA_TENANT): + segment_def = self.entry_def(segment_id, tenant=tenant) + self.policy_api.delete(segment_def) + + def get(self, segment_id, + tenant=policy_constants.POLICY_INFRA_TENANT): + segment_def = self.entry_def(segment_id, tenant=tenant) + return self.policy_api.get(segment_def) + + def list(self, tenant=policy_constants.POLICY_INFRA_TENANT): + 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, 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).""" def _get_last_seq_num(self, domain_id, map_id,