Skip to content

Commit

Permalink
referencing #311 complete PhysDomain class. Now user can add vlan to…
Browse files Browse the repository at this point in the history
… the domain and push it to apic
  • Loading branch information
Parvin Taheri committed Oct 18, 2017
1 parent fa149f7 commit 05710d7
Show file tree
Hide file tree
Showing 3 changed files with 337 additions and 7 deletions.
128 changes: 121 additions & 7 deletions acitoolkit/acitoolkit.py
Original file line number Diff line number Diff line change
Expand Up @@ -5706,7 +5706,7 @@ class PhysDomain(BaseACIObject):
Physical Network domain
"""

def __init__(self, name, parent):
def __init__(self, name, parent=None):
"""
:param name: String containing the PhysDomain name
:param parent: An instance of DomP class representing
Expand All @@ -5717,15 +5717,63 @@ def __init__(self, name, parent):
self.name = name
super(PhysDomain, self).__init__(name, parent)

def add_network(self, network_pool):
"""
associate network pool to the physical domain
:param network_pool: vlan or vxlan pool
"""
if not isinstance(network_pool, NetworkPool):
raise TypeError('add_network not called with NetworkPool')
self._remove_all_relation(network_pool)
self._add_relation(network_pool)

def remove_network(self):
"""
removes the associated vlan or vxlan from the physical domain
:return:
"""
self._remove_all_relation(NetworkPool)

def get_network(self):
"""
Get the network pool for this domain
:returns: Instance of NetworkPool class associated to this Domain.
"""
return self._get_any_relation(NetworkPool)

def has_network(self):
"""
Check if the network pool has been set for this physical domain
:returns: True or False. True if this network pool is assigned to the\
domain.
"""
return self._has_any_relation(NetworkPool)

def get_json(self):
"""
Returns json representation of the fvTenant object
Returns json representation of the physDomP object
:returns: A json dictionary of fvTenant
:returns: A json dictionary of physical domain
"""
attr = self._generate_attributes()
children = []
if self.has_network():
network_pool = self.get_network()
infraNsDn = 'uni/infra/%sns-[%s]-%s' % (network_pool.encap_type,
network_pool.name,
network_pool.mode)
if network_pool.encap_type == 'vlan':
infraNsType = 'infraRsVlanNs'
elif network_pool.encap_type == 'vxlan':
infraNsType = 'infraRsVxlanNs'

infraRsNs = {infraNsType: {'attributes': {'tDn': infraNsDn}}}
children.append(infraRsNs)
return super(PhysDomain, self).get_json(self._get_apic_classes()[0],
attributes=attr)
attributes=attr,
children=children)

def _generate_attributes(self):
"""
Expand Down Expand Up @@ -5757,6 +5805,7 @@ def get_parent(self):
"""
return self._parent


@staticmethod
def get_url(fmt='json'):
"""
Expand Down Expand Up @@ -5799,6 +5848,7 @@ def get(cls, session):
'target-subtree-class=') + str(apic_class))
ret = session.get(query_url)
data = ret.json()['imdata']

logging.debug('response returned %s', data)
resp = []
for object_data in data:
Expand All @@ -5809,10 +5859,28 @@ def get(cls, session):
obj.dn = object_data[apic_class]['attributes']['dn']
obj.lcOwn = object_data[apic_class]['attributes']['lcOwn']
obj.childAction = object_data[apic_class]['attributes']['childAction']

obj.get_network_from_apic(session)
resp.append(obj)
return resp

def get_network_from_apic(self, session):
"""
get network from apic
:param session:
"""
apic_classes = {'infraRsVlanNs': 'vlan', 'infraRsVxlanNs': 'vxlan'}
for ac in apic_classes:
query_url = ('/api/mo/uni/phys-' + self.name + '.json?query-target=subtree&target-subtree-class=' + ac)
ret = session.get(query_url)
data_pool = ret.json()['imdata']
data_pool = data_pool[0]
if ac in data_pool:
tDn = data_pool[ac]['attributes']['tDn']
mode = tDn.split("-")[-1]
name_pool = tDn.split("-[")[1].split("]-")[0]
network = NetworkPool(name_pool, apic_classes[ac], mode)
self.add_network(network)

@classmethod
def get_by_name(cls, session, infra_name):
"""
Expand Down Expand Up @@ -6425,15 +6493,15 @@ class NetworkPool(BaseACIObject):
"""This class defines a pool of network ids
"""

def __init__(self, name, encap_type, start_id, end_id, mode):
def __init__(self, name, encap_type, mode, start_id=None, end_id=None):
super(NetworkPool, self).__init__(name)
valid_encap_types = ['vlan', 'vxlan']
if encap_type not in valid_encap_types:
raise ValueError('Encap type specified is not a valid encap type')
self.encap_type = encap_type
self.start_id = start_id
self.end_id = end_id
valid_modes = ['static', 'dynamic']
valid_modes = ['static', 'dynamic','UOL_VXLAN']
if mode not in valid_modes:
raise ValueError('Mode specified is not a valid mode')
self.mode = mode
Expand Down Expand Up @@ -6472,6 +6540,52 @@ def get_json(self):
'children': [fvnsEncapInstP]}}
return infra

@classmethod
def _get_apic_classes(cls):
"""
Get the APIC classes used by the acitoolkit class.
:returns: list of strings containing APIC class names
"""
return ['fvnsVlanInstP','fvnsVxlanInstP']

@classmethod
def get(cls, session):
"""
:param session: apic session
:returns: list of network pools
"""
toolkit_class = cls
apic_classes = cls._get_apic_classes()

logging.debug('%s.get called', cls.__name__)
resp = []
for ac in apic_classes:
query_url = (('/api/mo/uni.json?query-target=subtree&'
'target-subtree-class=') + str(ac))
ret = session.get(query_url)
data = ret.json()['imdata']

#print(data)
for object_data in data:
# print (apic_classes[0])
#print (object_data)
if ac in object_data:
#print("vlan")
name = str(object_data[ac]['attributes']['name'])
dn = object_data[ac]['attributes']['dn']
encap_type = "vlan"
if ac == 'fvnsVxlanInstP':
encap_type = "vxlan"
mode = dn.split("-")[-1]
#print(mode)
try:
obj = toolkit_class(name,encap_type,mode)
except ValueError:
pass
resp.append(obj)

return resp


class VMMCredentials(BaseACIObject):
"""This class defines the credentials used to login to a Virtual
Expand Down
94 changes: 94 additions & 0 deletions samples/aci-create-phys-domain.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#!/usr/bin/env python
################################################################################
# _ ____ ___ _____ _ _ _ _ #
# / \ / ___|_ _| |_ _|__ ___ | | | _(_) |_ #
# / _ \| | | | | |/ _ \ / _ \| | |/ / | __| #
# / ___ \ |___ | | | | (_) | (_) | | <| | |_ #
# ____ /_/ \_\____|___|___|_|\___/ \___/|_|_|\_\_|\__| #
# / ___|___ __| | ___ / ___| __ _ _ __ ___ _ __ | | ___ ___ #
# | | / _ \ / _` |/ _ \ \___ \ / _` | '_ ` _ \| '_ \| |/ _ \/ __| #
# | |__| (_) | (_| | __/ ___) | (_| | | | | | | |_) | | __/\__ \ #
# \____\___/ \__,_|\___| |____/ \__,_|_| |_| |_| .__/|_|\___||___/ #
# |_| #
################################################################################
# #
# Copyright (c) 2015 Cisco Systems #
# All Rights Reserved. #
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
# not use this file except in compliance with the License. You may obtain #
# a copy of the License at #
# #
# http://www.apache.org/licenses/LICENSE-2.0 #
# #
# Unless required by applicable law or agreed to in writing, software #
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT #
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the #
# License for the specific language governing permissions and limitations #
# under the License. #
# #
################################################################################
"""
It logs in to the APIC and will create a physical Domain.
"""
import acitoolkit.acitoolkit as aci

# Define static values to pass (edit these for your environment)

POOL_NAME = 'dvs-vlans'
ENCAP_TYPE = 'vlan'
VLAN_START = '3150'
VLAN_END = '3200'
POOL_MODE = 'dynamic'


def main():
"""
Main create VMM routine
:return: None
"""
# Get all the arguments
description = 'Create Physical Domain'
creds = aci.Credentials('apic', description)
creds.add_argument('--phys', help='name of the physical domain')
args = creds.get()

# Login to the APIC
session = aci.Session(args.url, args.login, args.password)
resp = session.login()
if not resp.ok:
print('%% Could not login to APIC')

# Define dynamic vlan range
vlans = aci.NetworkPool(POOL_NAME, ENCAP_TYPE, VLAN_START, VLAN_END, POOL_MODE)

# Commit VLAN Range
vlanresp = session.push_to_apic(vlans.get_url(), vlans.get_json())

if not vlanresp.ok:
print('%% Error: Could not push configuration to APIC')
print(vlanresp.text)


# Create Physical Domain object
if args.phys:
phys_d = aci.PhysDomain(args.phys)
else:
phys_d = aci.PhysDomain("test-phys-domain")

phys_d.add_network(vlans)

# Commit Changes
resp = session.push_to_apic(phys_d.get_url(), phys_d.get_json())

if not resp.ok:
print('%% Error: Could not push configuration to APIC')
print(resp.text)


if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
pass

0 comments on commit 05710d7

Please sign in to comment.