From fffe3ce962e11e148cb21efa4dc7755c71e11955 Mon Sep 17 00:00:00 2001 From: Joseph LeClerc Date: Wed, 23 Sep 2015 13:34:09 -0700 Subject: [PATCH 01/23] Basic working L4L7Cluster, L4L7Device implementations. --- .../apicPython/createL4L7Cluster.py | 48 ++++++++++++++++++ .../apicPython/createL4L7Device.py | 49 +++++++++++++++++++ 2 files changed, 97 insertions(+) create mode 100644 configuration-python/generic_code/apicPython/createL4L7Cluster.py create mode 100644 configuration-python/generic_code/apicPython/createL4L7Device.py diff --git a/configuration-python/generic_code/apicPython/createL4L7Cluster.py b/configuration-python/generic_code/apicPython/createL4L7Cluster.py new file mode 100644 index 0000000..0c8ac09 --- /dev/null +++ b/configuration-python/generic_code/apicPython/createL4L7Cluster.py @@ -0,0 +1,48 @@ + +from cobra.model.vns import LDevVip +from createMo import * + +def input_key_args(): + return input_raw_input('Device Cluster Name', required=True) + +def input_optional_args(): + args = {} + # TODO + return args + +def create_l4l7_cluster(fv_tenant, name, **args): + """Create L4L7 Cluster""" + return LDevVip(fv_tenant, name) + +class CreateL4L7Cluster(CreateMo): + def __init__(self): + self.description = 'Create an L4-L7 device cluster' + self.tenant_required = True + self.contract = None + super(CreateL4L7Cluster, self).__init__() + + def set_cli_mode(self): + super(CreateL4L7Cluster, self).set_cli_mode() + self.parser_cli.add_argument('name', help='Cluster Name') + + def read_key_args(self): + self.tenant = self.args.pop('tenant') + self.name = self.args.pop('name') + + def wizard_mode_input_args(self): + self.args['name'] = input_key_args() + if not self.delete: + self.args['optional_args'] = input_optional_args() + + def delete_mo(self): + self.check_if_mo_exist('uni/tn-'+self.tenant+'/lDevVip-', self.name, LDevVip, description='LDevVip') + super(CreateL4L7Cluster, self).delete_mo() + + def main_function(self): + # Query a tenant + fv_tenant = self.check_if_tenant_exist() + + vns_ldevvip = create_l4l7_cluster(fv_tenant, self.name, optional_args=self.optional_args) + +if __name__ == '__main__': + mo = CreateL4L7Cluster() \ No newline at end of file diff --git a/configuration-python/generic_code/apicPython/createL4L7Device.py b/configuration-python/generic_code/apicPython/createL4L7Device.py new file mode 100644 index 0000000..7697efa --- /dev/null +++ b/configuration-python/generic_code/apicPython/createL4L7Device.py @@ -0,0 +1,49 @@ + +from cobra.model.vns import CDev, LDevVip +from createMo import * + +def input_key_args(): + return input_raw_input('Concrete Device Name', required=True) + +def input_optional_args(): + args = {} + # TODO + return args + +def create_l4l7_device(parent_mo, name, **args): + """Create L4L7 Device""" + return CDev(parent_mo, name) + +class CreateL4L7Device(CreateMo): + def __init__(self): + self.description = 'Create an L4-L7 concrete device' + self.tenant_required = True + self.contract = None + super(CreateL4L7Device, self).__init__() + + def set_cli_mode(self): + super(CreateL4L7Device, self).set_cli_mode() + self.parser_cli.add_argument('cluster_name', help='Name of the parent L4-L7 Device Cluster') + self.parser_cli.add_argument('name', help='Device Name') + + def read_key_args(self): + self.tenant = self.args.pop('tenant') + self.cluster_name = self.args.pop('cluster_name') + self.name = self.args.pop('name') + + def wizard_mode_input_args(self): + self.args['name'] = input_key_args() + if not self.delete: + self.args['optional_args'] = input_optional_args() + + def delete_mo(self): + self.check_if_mo_exist('uni/tn-{tenant}/lDevVip-{cluster_name}/cDev-'.format(**self.__dict__), self.name, CDev, description='CDev') + super(CreateL4L7Device, self).delete_mo() + + def main_function(self): + # Query a tenant + parent_mo = self.check_if_mo_exist('uni/tn-{tenant}/lDevVip-'.format(**self.__dict__), self.cluster_name, LDevVip, description='LDevVip') + vns_cdev = create_l4l7_device(parent_mo, self.name, optional_args=self.optional_args) + +if __name__ == '__main__': + mo = CreateL4L7Device() \ No newline at end of file From f4c7832c61a71ffe62f0fe5e7001804d8308c00f Mon Sep 17 00:00:00 2001 From: Joseph LeClerc Date: Wed, 23 Sep 2015 15:17:24 -0700 Subject: [PATCH 02/23] Add optional args to L4L7Cluster. --- .../apicPython/createL4L7Cluster.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/configuration-python/generic_code/apicPython/createL4L7Cluster.py b/configuration-python/generic_code/apicPython/createL4L7Cluster.py index 0c8ac09..8059016 100644 --- a/configuration-python/generic_code/apicPython/createL4L7Cluster.py +++ b/configuration-python/generic_code/apicPython/createL4L7Cluster.py @@ -6,13 +6,20 @@ def input_key_args(): return input_raw_input('Device Cluster Name', required=True) def input_optional_args(): - args = {} - # TODO + args = { + 'context_aware': input_options('Context Aware', default='single-Context', options=['single-Context', 'multi-Context']), + 'device_type': input_options('Device Type', default='PHYSICAL', options=['PHYSICAL', 'VIRTUAL']), + 'function_type': input_options('Function Type', default='GoTo', options=['GoTo','GoThrough']), + } return args def create_l4l7_cluster(fv_tenant, name, **args): """Create L4L7 Cluster""" - return LDevVip(fv_tenant, name) + args = args['optional_args'] if 'optional_args' in args.keys() else args + return LDevVip(fv_tenant, name, + contextAware=args['context_aware'], + devtype=args['device_type'], + funcType=args['function_type']) class CreateL4L7Cluster(CreateMo): def __init__(self): @@ -24,6 +31,10 @@ def __init__(self): def set_cli_mode(self): super(CreateL4L7Cluster, self).set_cli_mode() self.parser_cli.add_argument('name', help='Cluster Name') + self.parser_cli.add_argument('-c', '--context_aware', default='single-Context', choices=['single-Context', 'multi-Context'], + help='The context-awareness of the Device Cluster. Single means that the device cluster cannot be shared across multiple tenants of a given type that are hosted on the provider network. Multiple means that the device cluster can be shared across multiple tenants of a given type that you are hosting on this provider network. ') + self.parser_cli.add_argument('-d', '--device_type', default='PHYSICAL', choices=['PHYSICAL', 'VIRTUAL'], help='Specifies whether the device cluster has PHYSICAL appliances or VIRTUAL appliances.') + self.parser_cli.add_argument('-f', '--function_type', default='GoThrough', choices=['GoTo','GoThrough'], help='A GoTo device has a specific destination, depending on the package. A GoThrough device is a transparent device.') def read_key_args(self): self.tenant = self.args.pop('tenant') @@ -39,9 +50,7 @@ def delete_mo(self): super(CreateL4L7Cluster, self).delete_mo() def main_function(self): - # Query a tenant fv_tenant = self.check_if_tenant_exist() - vns_ldevvip = create_l4l7_cluster(fv_tenant, self.name, optional_args=self.optional_args) if __name__ == '__main__': From 4c8d2eaa0b5e02c4ad511d942b3aca1d97f49e70 Mon Sep 17 00:00:00 2001 From: Joseph LeClerc Date: Fri, 25 Sep 2015 11:49:32 -0700 Subject: [PATCH 03/23] Add CCred, CCredSecret, CIf, CMgmt, and RsMDevAtt creation for L4-L7 Clusters. --- .../apicPython/createL4L7Cluster.py | 73 ++++++++++++++++--- 1 file changed, 62 insertions(+), 11 deletions(-) diff --git a/configuration-python/generic_code/apicPython/createL4L7Cluster.py b/configuration-python/generic_code/apicPython/createL4L7Cluster.py index 8059016..19470b5 100644 --- a/configuration-python/generic_code/apicPython/createL4L7Cluster.py +++ b/configuration-python/generic_code/apicPython/createL4L7Cluster.py @@ -1,25 +1,61 @@ -from cobra.model.vns import LDevVip +from cobra.model.vns import LDevVip, RsMDevAtt, CCred, CCredSecret, CMgmt from createMo import * +import getpass + +DEFAULT_CONTEXT_AWARENESS = 'single-Context' +DEFAULT_DEVICE_TYPE = 'PHYSICAL' +DEFAULT_FUNCTION_TYPE = 'GoTo' def input_key_args(): return input_raw_input('Device Cluster Name', required=True) def input_optional_args(): args = { - 'context_aware': input_options('Context Aware', default='single-Context', options=['single-Context', 'multi-Context']), - 'device_type': input_options('Device Type', default='PHYSICAL', options=['PHYSICAL', 'VIRTUAL']), - 'function_type': input_options('Function Type', default='GoTo', options=['GoTo','GoThrough']), + 'contextAware': input_options('L4-L7 Device Cluster - Context Awareness', default=DEFAULT_CONTEXT_AWARENESS, options=['single-Context', 'multi-Context']), + 'devtype': input_options('L4-L7 Device Cluster - Device Type', default=DEFAULT_DEVICE_TYPE, options=['PHYSICAL', 'VIRTUAL']), + 'funcType': input_options('L4-L7 Device Cluster - Function Type', default=DEFAULT_FUNCTION_TYPE, options=['GoTo','GoThrough']), + # 'device_package_vendor': input_options('L4-L7 Device Package Info: Vendor Name'), + # 'device_package_model': input_options('L4-L7 Device Package Info: Model Name'), + # 'device_package_version': input_options('L4-L7 Device Package Info: Major Version'), + # 'cluster_username': input_options('L4-L7 Device Cluster: Username'), + # 'cluster_password': getpass.getpass('L4-L7 Device Cluster: Password: '), + # 'cluster_ip': input_options('L4-L7 Device Cluster: IP'), + # 'cluster_port': input_options('L4-L7 Device Cluster: Port'), } return args def create_l4l7_cluster(fv_tenant, name, **args): """Create L4L7 Cluster""" args = args['optional_args'] if 'optional_args' in args.keys() else args - return LDevVip(fv_tenant, name, - contextAware=args['context_aware'], - devtype=args['device_type'], - funcType=args['function_type']) + valid_keys = ['contextAware', 'devtype', 'funcType'] + kwargs = {k: v for k, v in args.items() if (k in valid_keys and v)} + return LDevVip(fv_tenant, name, **kwargs) + +def add_metadata_source_relation(cluster_mo, **args): + """vnsRsMDevAtt: "A source relation to the metadata definitions for a service device type. Functions as a pointer to the device package.""" + args = args['optional_args'] if 'optional_args' in args.keys() else args + tdn = 'uni/infra/mDev-{device_package_vendor}-{device_package_model}-{device_package_version}'.format(**args) + return RsMDevAtt(cluster_mo, tDn=tdn) + +def add_concrete_device_access_credentials(cluster_mo, **args): + """The concrete device access credentials in the L4-L7 device cluster. The concrete device access credentials normally include a password that is not displayed and is stored in encrypted form.""" + args = args['optional_args'] if 'optional_args' in args.keys() else args + return CCred(cluster_mo, name='username', value=args['cluster_username']) + +def add_concrete_device_access_credentials_secret(cluster_mo, **args): + """The secret for the concrete device access credentials in the L4-L7 device cluster. The concrete device access credentials normally include a password that is not displayed and is stored in encrypted form.""" + args = args['optional_args'] if 'optional_args' in args.keys() else args + return CCredSecret(cluster_mo, name='password', value=args['cluster_password']) + +def add_management_interface(cluster_mo, **args): + """The management interface is used to manage a concrete device in the L4-L7 device cluster. The management interface is identified by a host address and port number.""" + args = args['optional_args'] if 'optional_args' in args.keys() else args + valid_keys = ['cluster_ip', 'cluster_port'] + key_map = {'cluster_ip': 'host', 'cluster_port': 'port'} + kwargs = {k: v for k, v in args.items() if (k in valid_keys and v)} + kwargs = {key_map[k]: v for k, v in kwargs.items()} + return CMgmt(cluster_mo, name='devMgmt', **kwargs) class CreateL4L7Cluster(CreateMo): def __init__(self): @@ -31,10 +67,17 @@ def __init__(self): def set_cli_mode(self): super(CreateL4L7Cluster, self).set_cli_mode() self.parser_cli.add_argument('name', help='Cluster Name') - self.parser_cli.add_argument('-c', '--context_aware', default='single-Context', choices=['single-Context', 'multi-Context'], + self.parser_cli.add_argument('-d1', '--device_package_vendor', help='Device package: --. E.g "Cisco-FirePOWER-1.0"') + self.parser_cli.add_argument('-d2', '--device_package_model', help='Device package: --. E.g "Cisco-FirePOWER-1.0"') + self.parser_cli.add_argument('-d3', '--device_package_version', help='Device package: --. E.g "Cisco-FirePOWER-1.0"') + self.parser_cli.add_argument('-f', '--function_type', choices=['GoTo','GoThrough'], dest='funcType', help='A GoTo device has a specific destination, depending on the package. A GoThrough device is a transparent device.') + self.parser_cli.add_argument('-t', '--device_type', choices=['PHYSICAL', 'VIRTUAL'], dest='devtype', help='Specifies whether the device cluster has PHYSICAL appliances or VIRTUAL appliances.') + self.parser_cli.add_argument('-u1', '--username', dest='cluster_username', help='Username for the L4-L7 cluster.') + self.parser_cli.add_argument('-u2', '--password', dest='cluster_password', help='Password for the L4-L7 cluster.') + self.parser_cli.add_argument('-i', '--ip', dest='cluster_ip', help='IP Address of the L4-L7 cluster host.') + self.parser_cli.add_argument('-j', '--port', dest='cluster_port', help='Port of the L4-L7 cluster host.') + self.parser_cli.add_argument('-x', '--context_aware', choices=['single-Context', 'multi-Context'], dest='contextAware', help='The context-awareness of the Device Cluster. Single means that the device cluster cannot be shared across multiple tenants of a given type that are hosted on the provider network. Multiple means that the device cluster can be shared across multiple tenants of a given type that you are hosting on this provider network. ') - self.parser_cli.add_argument('-d', '--device_type', default='PHYSICAL', choices=['PHYSICAL', 'VIRTUAL'], help='Specifies whether the device cluster has PHYSICAL appliances or VIRTUAL appliances.') - self.parser_cli.add_argument('-f', '--function_type', default='GoThrough', choices=['GoTo','GoThrough'], help='A GoTo device has a specific destination, depending on the package. A GoThrough device is a transparent device.') def read_key_args(self): self.tenant = self.args.pop('tenant') @@ -52,6 +95,14 @@ def delete_mo(self): def main_function(self): fv_tenant = self.check_if_tenant_exist() vns_ldevvip = create_l4l7_cluster(fv_tenant, self.name, optional_args=self.optional_args) + if 'device_package_vendor' in self.optional_args: + vns_rsmdevatt = add_metadata_source_relation(vns_ldevvip, optional_args=self.optional_args) + if 'cluster_username' in self.optional_args: + vns_ccred = add_concrete_device_access_credentials(vns_ldevvip, optional_args=self.optional_args) + if 'cluster_password' in self.optional_args: + vns_ccredsecret = add_concrete_device_access_credentials_secret(vns_ldevvip, optional_args=self.optional_args) + if 'cluster_ip' in self.optional_args or 'port' in self.optional_args: + vns_cmgmt = add_management_interface(vns_ldevvip, optional_args=self.optional_args) if __name__ == '__main__': mo = CreateL4L7Cluster() \ No newline at end of file From 5d8c76d8dac945ffd78c70fd6934755142cbd28a Mon Sep 17 00:00:00 2001 From: Joseph LeClerc Date: Fri, 25 Sep 2015 14:09:48 -0700 Subject: [PATCH 04/23] Add YAML file for L4L7Cluster. --- .../apicPython/createL4L7Cluster.yaml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 configuration-python/generic_code/apicPython/createL4L7Cluster.yaml diff --git a/configuration-python/generic_code/apicPython/createL4L7Cluster.yaml b/configuration-python/generic_code/apicPython/createL4L7Cluster.yaml new file mode 100644 index 0000000..a46e2de --- /dev/null +++ b/configuration-python/generic_code/apicPython/createL4L7Cluster.yaml @@ -0,0 +1,17 @@ + +host: 10.10.10.10 +user: admin +password: password + +tenant: my_tenant +name: my_cluster +context_aware: single-Context +device_type: PHYSICAL +function_type: GoThrough +cluster_username: admin +cluster_password: cluster_password +cluster_ip: 10.10.10.11 +cluster_port: 443 +device_package_vendor: Cisco +device_package_model: FirePOWER +device_package_version: 1.0 From 6f7f5a269b1d3b454ae76556b4bdfb4432f15690 Mon Sep 17 00:00:00 2001 From: Joseph LeClerc Date: Tue, 6 Oct 2015 09:56:51 -0700 Subject: [PATCH 05/23] Modifications to L4L7Cluster.py. --- .../apicPython/createL4L7Cluster.py | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/configuration-python/generic_code/apicPython/createL4L7Cluster.py b/configuration-python/generic_code/apicPython/createL4L7Cluster.py index 19470b5..2856a4c 100644 --- a/configuration-python/generic_code/apicPython/createL4L7Cluster.py +++ b/configuration-python/generic_code/apicPython/createL4L7Cluster.py @@ -15,13 +15,6 @@ def input_optional_args(): 'contextAware': input_options('L4-L7 Device Cluster - Context Awareness', default=DEFAULT_CONTEXT_AWARENESS, options=['single-Context', 'multi-Context']), 'devtype': input_options('L4-L7 Device Cluster - Device Type', default=DEFAULT_DEVICE_TYPE, options=['PHYSICAL', 'VIRTUAL']), 'funcType': input_options('L4-L7 Device Cluster - Function Type', default=DEFAULT_FUNCTION_TYPE, options=['GoTo','GoThrough']), - # 'device_package_vendor': input_options('L4-L7 Device Package Info: Vendor Name'), - # 'device_package_model': input_options('L4-L7 Device Package Info: Model Name'), - # 'device_package_version': input_options('L4-L7 Device Package Info: Major Version'), - # 'cluster_username': input_options('L4-L7 Device Cluster: Username'), - # 'cluster_password': getpass.getpass('L4-L7 Device Cluster: Password: '), - # 'cluster_ip': input_options('L4-L7 Device Cluster: IP'), - # 'cluster_port': input_options('L4-L7 Device Cluster: Port'), } return args @@ -33,9 +26,11 @@ def create_l4l7_cluster(fv_tenant, name, **args): return LDevVip(fv_tenant, name, **kwargs) def add_metadata_source_relation(cluster_mo, **args): - """vnsRsMDevAtt: "A source relation to the metadata definitions for a service device type. Functions as a pointer to the device package.""" + """vnsRsMDevAtt: "A source relation to the metadata definitions for a service device type. Functions as a pointer to the device package. + e.g: uni/infra/mDev-{device_package_vendor}-{device_package_model}-{device_package_version} + """ args = args['optional_args'] if 'optional_args' in args.keys() else args - tdn = 'uni/infra/mDev-{device_package_vendor}-{device_package_model}-{device_package_version}'.format(**args) + tdn = 'uni/infra/mDev-{device_package}'.format(**args) return RsMDevAtt(cluster_mo, tDn=tdn) def add_concrete_device_access_credentials(cluster_mo, **args): @@ -67,15 +62,13 @@ def __init__(self): def set_cli_mode(self): super(CreateL4L7Cluster, self).set_cli_mode() self.parser_cli.add_argument('name', help='Cluster Name') - self.parser_cli.add_argument('-d1', '--device_package_vendor', help='Device package: --. E.g "Cisco-FirePOWER-1.0"') - self.parser_cli.add_argument('-d2', '--device_package_model', help='Device package: --. E.g "Cisco-FirePOWER-1.0"') - self.parser_cli.add_argument('-d3', '--device_package_version', help='Device package: --. E.g "Cisco-FirePOWER-1.0"') + self.parser_cli.add_argument('-d', '--device_package', help='Device package, e.g "Cisco-FirePOWER-1.0"', metavar='VENDOR-MODEL-VERSION') self.parser_cli.add_argument('-f', '--function_type', choices=['GoTo','GoThrough'], dest='funcType', help='A GoTo device has a specific destination, depending on the package. A GoThrough device is a transparent device.') self.parser_cli.add_argument('-t', '--device_type', choices=['PHYSICAL', 'VIRTUAL'], dest='devtype', help='Specifies whether the device cluster has PHYSICAL appliances or VIRTUAL appliances.') self.parser_cli.add_argument('-u1', '--username', dest='cluster_username', help='Username for the L4-L7 cluster.') self.parser_cli.add_argument('-u2', '--password', dest='cluster_password', help='Password for the L4-L7 cluster.') self.parser_cli.add_argument('-i', '--ip', dest='cluster_ip', help='IP Address of the L4-L7 cluster host.') - self.parser_cli.add_argument('-j', '--port', dest='cluster_port', help='Port of the L4-L7 cluster host.') + self.parser_cli.add_argument('-p', '--port', dest='cluster_port', help='Port of the L4-L7 cluster host.') self.parser_cli.add_argument('-x', '--context_aware', choices=['single-Context', 'multi-Context'], dest='contextAware', help='The context-awareness of the Device Cluster. Single means that the device cluster cannot be shared across multiple tenants of a given type that are hosted on the provider network. Multiple means that the device cluster can be shared across multiple tenants of a given type that you are hosting on this provider network. ') @@ -95,7 +88,7 @@ def delete_mo(self): def main_function(self): fv_tenant = self.check_if_tenant_exist() vns_ldevvip = create_l4l7_cluster(fv_tenant, self.name, optional_args=self.optional_args) - if 'device_package_vendor' in self.optional_args: + if 'device_package' in self.optional_args: vns_rsmdevatt = add_metadata_source_relation(vns_ldevvip, optional_args=self.optional_args) if 'cluster_username' in self.optional_args: vns_ccred = add_concrete_device_access_credentials(vns_ldevvip, optional_args=self.optional_args) From e2d679e4536df6aa5195a7395795341cc60a8da0 Mon Sep 17 00:00:00 2001 From: Joseph LeClerc Date: Tue, 6 Oct 2015 15:59:43 -0700 Subject: [PATCH 06/23] Working LDevVip, CDev and RsCIfPathAtt objects with dynamicallyCreateApplication.py. --- .../apicPython/createL4L7Cluster.py | 26 ++++++++----- .../apicPython/createL4L7Device.py | 39 ++++++++++++++++--- .../dynamicallyCreateApplication.py | 21 ++++++++++ .../dynamicallyCreateApplication.yaml | 30 +++++++++++++- 4 files changed, 101 insertions(+), 15 deletions(-) diff --git a/configuration-python/generic_code/apicPython/createL4L7Cluster.py b/configuration-python/generic_code/apicPython/createL4L7Cluster.py index 2856a4c..17efc2e 100644 --- a/configuration-python/generic_code/apicPython/createL4L7Cluster.py +++ b/configuration-python/generic_code/apicPython/createL4L7Cluster.py @@ -2,6 +2,7 @@ from cobra.model.vns import LDevVip, RsMDevAtt, CCred, CCredSecret, CMgmt from createMo import * import getpass +import sys DEFAULT_CONTEXT_AWARENESS = 'single-Context' DEFAULT_DEVICE_TYPE = 'PHYSICAL' @@ -23,7 +24,17 @@ def create_l4l7_cluster(fv_tenant, name, **args): args = args['optional_args'] if 'optional_args' in args.keys() else args valid_keys = ['contextAware', 'devtype', 'funcType'] kwargs = {k: v for k, v in args.items() if (k in valid_keys and v)} - return LDevVip(fv_tenant, name, **kwargs) + + vns_ldevvip = LDevVip(fv_tenant, name, **kwargs) + if 'device_package' in args: + vns_rsmdevatt = add_metadata_source_relation(vns_ldevvip, optional_args=args) + if 'cluster_username' in args: + vns_ccred = add_concrete_device_access_credentials(vns_ldevvip, optional_args=args) + if 'cluster_password' in args: + vns_ccredsecret = add_concrete_device_access_credentials_secret(vns_ldevvip, optional_args=args) + if 'cluster_ip' in args or 'cluster_port' in args: + vns_cmgmt = add_management_interface(vns_ldevvip, optional_args=args) + return vns_ldevvip def add_metadata_source_relation(cluster_mo, **args): """vnsRsMDevAtt: "A source relation to the metadata definitions for a service device type. Functions as a pointer to the device package. @@ -52,6 +63,11 @@ def add_management_interface(cluster_mo, **args): kwargs = {key_map[k]: v for k, v in kwargs.items()} return CMgmt(cluster_mo, name='devMgmt', **kwargs) +def add_concrete_device(cluster_mo, **args): + """ Calls L4L7Device.py to create CDev child MO's """ + return createL4L7Device.create_l4l7_device(cluster_mo, **args) + + class CreateL4L7Cluster(CreateMo): def __init__(self): self.description = 'Create an L4-L7 device cluster' @@ -88,14 +104,6 @@ def delete_mo(self): def main_function(self): fv_tenant = self.check_if_tenant_exist() vns_ldevvip = create_l4l7_cluster(fv_tenant, self.name, optional_args=self.optional_args) - if 'device_package' in self.optional_args: - vns_rsmdevatt = add_metadata_source_relation(vns_ldevvip, optional_args=self.optional_args) - if 'cluster_username' in self.optional_args: - vns_ccred = add_concrete_device_access_credentials(vns_ldevvip, optional_args=self.optional_args) - if 'cluster_password' in self.optional_args: - vns_ccredsecret = add_concrete_device_access_credentials_secret(vns_ldevvip, optional_args=self.optional_args) - if 'cluster_ip' in self.optional_args or 'port' in self.optional_args: - vns_cmgmt = add_management_interface(vns_ldevvip, optional_args=self.optional_args) if __name__ == '__main__': mo = CreateL4L7Cluster() \ No newline at end of file diff --git a/configuration-python/generic_code/apicPython/createL4L7Device.py b/configuration-python/generic_code/apicPython/createL4L7Device.py index 7697efa..85f0be0 100644 --- a/configuration-python/generic_code/apicPython/createL4L7Device.py +++ b/configuration-python/generic_code/apicPython/createL4L7Device.py @@ -1,5 +1,5 @@ -from cobra.model.vns import CDev, LDevVip +from cobra.model.vns import CDev, LDevVip, CCred, CCredSecret, CMgmt from createMo import * def input_key_args(): @@ -12,13 +12,42 @@ def input_optional_args(): def create_l4l7_device(parent_mo, name, **args): """Create L4L7 Device""" - return CDev(parent_mo, name) + args = args['optional_args'] if 'optional_args' in args.keys() else args + valid_keys = ['name', 'vmName', 'vcenterName', 'devCtxLbl'] + kwargs = {k: v for k, v in args.items() if (k in valid_keys and v)} + vns_cdev = CDev(parent_mo, name, **kwargs) + if 'device_username' in args: + vns_ccred = add_concrete_device_access_credentials(vns_cdev, optional_args=args) + if 'device_password' in args: + vns_ccredsecret = add_concrete_device_access_credentials_secret(vns_cdev, optional_args=args) + if 'device_ip' in args or 'device_port' in args: + vns_cmgmt = add_management_interface(vns_cdev, optional_args=args) + return vns_cdev + +def add_concrete_device_access_credentials(device_mo, **args): + """The concrete device access credentials in the L4-L7 device cluster. The concrete device access credentials normally include a password that is not displayed and is stored in encrypted form.""" + args = args['optional_args'] if 'optional_args' in args.keys() else args + return CCred(device_mo, name='username', value=args['device_username']) + +def add_concrete_device_access_credentials_secret(device_mo, **args): + """The secret for the concrete device access credentials in the L4-L7 device cluster. The concrete device access credentials normally include a password that is not displayed and is stored in encrypted form.""" + args = args['optional_args'] if 'optional_args' in args.keys() else args + return CCredSecret(device_mo, name='password', value=args['device_password']) + +def add_management_interface(device_mo, **args): + """The management interface is used to manage a concrete device in the L4-L7 device cluster. The management interface is identified by a host address and port number.""" + args = args['optional_args'] if 'optional_args' in args.keys() else args + valid_keys = ['device_ip', 'device_port'] + key_map = {'device_ip': 'host', 'device_port': 'port'} + kwargs = {k: v for k, v in args.items() if (k in valid_keys and v)} + kwargs = {key_map[k]: v for k, v in kwargs.items()} + return CMgmt(device_mo, name='devMgmt', **kwargs) class CreateL4L7Device(CreateMo): def __init__(self): - self.description = 'Create an L4-L7 concrete device' - self.tenant_required = True - self.contract = None + self.description = 'Create an L4-L7 concrete device' + self.tenant_required = True + self.contract = None super(CreateL4L7Device, self).__init__() def set_cli_mode(self): diff --git a/configuration-python/generic_code/apicPython/dynamicallyCreateApplication.py b/configuration-python/generic_code/apicPython/dynamicallyCreateApplication.py index 27a9677..833a4ab 100644 --- a/configuration-python/generic_code/apicPython/dynamicallyCreateApplication.py +++ b/configuration-python/generic_code/apicPython/dynamicallyCreateApplication.py @@ -10,6 +10,9 @@ from apicPython import createApplication from apicPython import createApplicationEpg from apicPython import connectEpgContract +from apicPython import createL4L7Cluster +from apicPython import createL4L7Device +from apicPython import createL4L7ConcreteInterface class DynamicallyCreateApplication(LabScript): @@ -25,6 +28,7 @@ def __init__(self): self.application_optional_args = None self.epgs = [] self.applied_contracts = [] + self.l4l7_devices = [] super(DynamicallyCreateApplication, self).__init__() def run_yaml_mode(self): @@ -38,6 +42,7 @@ def run_yaml_mode(self): self.application_optional_args = self.args['application']['optional_args'] self.epgs = self.args['epgs'] self.applied_contracts = self.args['applied_contracts'] + self.l4l7_devices = self.args['l4l7_devices'] def run_wizard_mode(self): print 'Wizard mode is not supported in this method. Please try Yaml mode.' @@ -94,5 +99,21 @@ def main_function(self): connectEpgContract.connect_epg_contract(fv_aepg, contract['contract'], contract['type']) self.commit_change(changed_object=fv_aepg) + # add L4L7 clusters/devices + for cluster in self.l4l7_devices: + # add cluster + vns_ldevvip = createL4L7Cluster.create_l4l7_cluster(fv_tenant, **cluster) + # add devices to cluster + if is_valid_key(cluster, 'devices'): + for device in cluster['devices']: + vns_cdev = createL4L7Device.create_l4l7_device(vns_ldevvip, **device) + #self.commit_change(changed_object=vns_cdev) + # add concrete interfaces to devices + if is_valid_key(device, 'concrete_interfaces'): + for interface in device['concrete_interfaces']: + vns_cif = createL4L7ConcreteInterface.create_l4l7_concrete_interface(vns_cdev, **interface) + #self.commit_change(changed_object=vns_cif) + self.commit_change(changed_object=vns_ldevvip) + if __name__ == '__main__': mo = DynamicallyCreateApplication() diff --git a/configuration-python/generic_code/apicPython/dynamicallyCreateApplication.yaml b/configuration-python/generic_code/apicPython/dynamicallyCreateApplication.yaml index 16a86a5..4b39721 100644 --- a/configuration-python/generic_code/apicPython/dynamicallyCreateApplication.yaml +++ b/configuration-python/generic_code/apicPython/dynamicallyCreateApplication.yaml @@ -207,7 +207,7 @@ epgs: encap: vlan-13 deployment_immediacy: lazy mode: untagged - + # Specify the relationship (provided or consumed) between contract and epg. # Usage: # - contract: @@ -229,3 +229,31 @@ applied_contracts: - contract: DB_Con epg: App_EPG type: consumed + +l4l7_devices: +- #tenant: sf_test + name: my_cluster + context_aware: single-Context + device_type: PHYSICAL + function_type: GoThrough + cluster_username: admin + cluster_password: cluster_password + cluster_ip: 10.10.10.11 + cluster_port: 443 + device_package: Cisco-FirePOWER-1.0 + devices: + - name: yaml_device + device_username: admin + device_password: device_password_1 + device_ip: 10.10.10.2 + device_port: 443 + concrete_interfaces: + - name: test_interface + vnicName: "" + path: "topology/pod-1/paths-1001/pathep-[eth1/10]" + + - name: yaml_device_2 + device_username: admin + device_password: device_password_2 + device_ip: 10.10.10.3 + device_port: 443 From 5e7457140a3f057e2e0d37dfb275ce35dbdcc6d7 Mon Sep 17 00:00:00 2001 From: Joseph LeClerc Date: Wed, 7 Oct 2015 15:55:57 -0700 Subject: [PATCH 07/23] Add createL4L7LogicalInterface.py. --- .../apicPython/createL4L7LogicalInterface.py | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 configuration-python/generic_code/apicPython/createL4L7LogicalInterface.py diff --git a/configuration-python/generic_code/apicPython/createL4L7LogicalInterface.py b/configuration-python/generic_code/apicPython/createL4L7LogicalInterface.py new file mode 100644 index 0000000..bba1194 --- /dev/null +++ b/configuration-python/generic_code/apicPython/createL4L7LogicalInterface.py @@ -0,0 +1,42 @@ + +from cobra.model.vns import CDev, LIf, RsMetaIf, RsCIfAtt, RsCIfAttN +from createMo import * + +def input_key_args(): + return input_raw_input('Concrete Interface Name', required=True) + +def input_optional_args(): + args = {} + # TODO + return args + +def create_l4l7_logical_interface(parent_mo, name, **args): + """The logical interface is associated with a set of concrete interfaces from the L4-L7 device cluster. This is used to define the connection between a service graph and device interfaces.""" + args = args['optional_args'] if 'optional_args' in args.keys() else args + valid_keys = ['name', 'encap'] + kwargs = {k: v for k, v in args.items() if (k in valid_keys and v)} + vns_lif = LIf(parent_mo, name, **kwargs) + if 'interface_label' in args: + vns_rsmetaif = add_source_relation_to_interface_label(vns_lif, device_package=args['device_package'], label= args['label']) + if 'concrete_interface': + vns_rscifatt = add_association_to_concrete_interface(vns_lif, tenant=args['tenant'], cluster=args['cluster'], device=args['device'], cifname=args['cifname']) + return vns_lif + +def add_source_relation_to_interface_label(logical_interface_mo, **args): + """A source relation to an interface label. e.g: tDn='uni/infra/mDev-Cisco-FirePOWER-1.0/mIfLbl-external' """ + valid_keys = ['device_package', 'label'] + kwargs = {k: v for k, v in args.items() if (k in valid_keys and v)} + return RsMetaIf(logical_interface_mo, tDn='uni/infra/mDev-{device_package}/mIfLbl-{label}'.format(**kwargs)) + +def add_association_to_concrete_interface(logical_interface_mo, **args): + """Association to a set of concrete interfaces from the device in the cluster.""" + valid_keys = ['tenant', 'cluster', 'device', 'cifname'] + kwargs = {k: v for k, v in args.items() if (k in valid_keys and v)} + return RsCIfAtt(logical_interface_mo, tDn='uni/tn-{tenant}/lDevVip-{cluster}/cDev-{device}/cIf-{cifname}'.format(**kwargs)) + +class CreateL4L7ConcreteInterface(CreateMo): + def __init__(self): + self.description = 'Create an L4-L7 concrete device' + self.tenant_required = True + self.contract = None + super(CreateL4L7ConcreteInterface, self).__init__() \ No newline at end of file From 2022ae0beec536ef3f95e96908a3e18231559ec0 Mon Sep 17 00:00:00 2001 From: Joseph LeClerc Date: Wed, 7 Oct 2015 15:56:35 -0700 Subject: [PATCH 08/23] Add createL4L7ConcreteInterface.py. --- .../apicPython/createL4L7ConcreteInterface.py | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 configuration-python/generic_code/apicPython/createL4L7ConcreteInterface.py diff --git a/configuration-python/generic_code/apicPython/createL4L7ConcreteInterface.py b/configuration-python/generic_code/apicPython/createL4L7ConcreteInterface.py new file mode 100644 index 0000000..5274750 --- /dev/null +++ b/configuration-python/generic_code/apicPython/createL4L7ConcreteInterface.py @@ -0,0 +1,32 @@ + +from cobra.model.vns import CDev, CIf, RsCIfPathAtt +from createMo import * + +def input_key_args(): + return input_raw_input('Concrete Interface Name', required=True) + +def input_optional_args(): + args = {} + # TODO + return args + +def create_l4l7_concrete_interface(parent_mo, name, **args): + """Create L4L7 Concrete Interface""" + args = args['optional_args'] if 'optional_args' in args.keys() else args + valid_keys = ['name', 'vnicName'] + kwargs = {k: v for k, v in args.items() if (k in valid_keys and v)} + vns_cif = CIf(parent_mo, name, **kwargs) + if 'path' in args: + vns_rscifpathatt = add_source_relation_to_path_endpoint(vns_cif, args['path']) + return vns_cif + +def add_source_relation_to_path_endpoint(concrete_interface_mo, path): + """A source relation to a path endpoint. e.g: 'topology/pod-1/paths-1001/pathep-[eth1/10]' """ + return RsCIfPathAtt(concrete_interface_mo, tDn=path) + +class CreateL4L7ConcreteInterface(CreateMo): + def __init__(self): + self.description = 'Create an L4-L7 concrete device' + self.tenant_required = True + self.contract = None + super(CreateL4L7ConcreteInterface, self).__init__() \ No newline at end of file From b0aabf3519960bde1dc81453b6c50fbbee4fbc20 Mon Sep 17 00:00:00 2001 From: Joseph LeClerc Date: Wed, 7 Oct 2015 15:58:15 -0700 Subject: [PATCH 09/23] Add L4-L7 devices logical interface support to dynamicallyCreateApplication.py, update yaml file. --- .../dynamicallyCreateApplication.py | 28 +++++++++++-- .../dynamicallyCreateApplication.yaml | 41 +++++++++++++++---- 2 files changed, 58 insertions(+), 11 deletions(-) diff --git a/configuration-python/generic_code/apicPython/dynamicallyCreateApplication.py b/configuration-python/generic_code/apicPython/dynamicallyCreateApplication.py index 833a4ab..834bc6b 100644 --- a/configuration-python/generic_code/apicPython/dynamicallyCreateApplication.py +++ b/configuration-python/generic_code/apicPython/dynamicallyCreateApplication.py @@ -13,6 +13,7 @@ from apicPython import createL4L7Cluster from apicPython import createL4L7Device from apicPython import createL4L7ConcreteInterface +from apicPython import createL4L7LogicalInterface class DynamicallyCreateApplication(LabScript): @@ -101,19 +102,38 @@ def main_function(self): # add L4L7 clusters/devices for cluster in self.l4l7_devices: + # add cluster vns_ldevvip = createL4L7Cluster.create_l4l7_cluster(fv_tenant, **cluster) + self.commit_change(changed_object=vns_ldevvip) + # add devices to cluster if is_valid_key(cluster, 'devices'): for device in cluster['devices']: vns_cdev = createL4L7Device.create_l4l7_device(vns_ldevvip, **device) - #self.commit_change(changed_object=vns_cdev) + self.commit_change(changed_object=vns_cdev) + # add concrete interfaces to devices if is_valid_key(device, 'concrete_interfaces'): for interface in device['concrete_interfaces']: vns_cif = createL4L7ConcreteInterface.create_l4l7_concrete_interface(vns_cdev, **interface) - #self.commit_change(changed_object=vns_cif) - self.commit_change(changed_object=vns_ldevvip) - + self.commit_change(changed_object=vns_cif) + + # add logical interfaces to cluster + if is_valid_key(cluster, 'logical_interfaces'): + for logical_interface in cluster['logical_interfaces']: + vns_lif = createL4L7LogicalInterface.create_l4l7_logical_interface(vns_ldevvip, logical_interface['name'], device=logical_interface['device'], label=logical_interface['label'], tenant=self.tenant, cluster=cluster['name'], cifname=logical_interface['concrete_interface']) + self.commit_change(changed_object=vns_lif) +''' +def create_l4l7_logical_interface(parent_mo, name, **args): + """The logical interface is associated with a set of concrete interfaces from the L4-L7 device cluster. This is used to define the connection between a service graph and device interfaces.""" + args = args['optional_args'] if 'optional_args' in args.keys() else args + valid_keys = ['name', 'encap'] + + ... + + vns_rsmetaif = add_source_relation_to_interface_label(vns_lif, device_package= , label= ]) + if 'concrete_interface': + vns_rscifatt = add_association_to_concrete_interface(vns_lif, tenant= , cluster= , device = , interface= )''' if __name__ == '__main__': mo = DynamicallyCreateApplication() diff --git a/configuration-python/generic_code/apicPython/dynamicallyCreateApplication.yaml b/configuration-python/generic_code/apicPython/dynamicallyCreateApplication.yaml index 4b39721..fde930a 100644 --- a/configuration-python/generic_code/apicPython/dynamicallyCreateApplication.yaml +++ b/configuration-python/generic_code/apicPython/dynamicallyCreateApplication.yaml @@ -231,8 +231,7 @@ applied_contracts: type: consumed l4l7_devices: -- #tenant: sf_test - name: my_cluster +- name: my_cluster context_aware: single-Context device_type: PHYSICAL function_type: GoThrough @@ -241,19 +240,47 @@ l4l7_devices: cluster_ip: 10.10.10.11 cluster_port: 443 device_package: Cisco-FirePOWER-1.0 + devices: - - name: yaml_device + - name: my_device device_username: admin device_password: device_password_1 device_ip: 10.10.10.2 device_port: 443 concrete_interfaces: - - name: test_interface + - name: internalcinf vnicName: "" - path: "topology/pod-1/paths-1001/pathep-[eth1/10]" - - - name: yaml_device_2 + path: "topology/pod-1/paths-1001/pathep-[eth1/11]" + - name: externalcinf + vnicName: "" + path: "topology/pod-1/paths-1001/pathep-[eth1/12]" + - name: my_device_2 device_username: admin device_password: device_password_2 device_ip: 10.10.10.3 device_port: 443 + concrete_interfaces: + - name: internalcinf + vnicName: "" + path: "topology/pod-1/paths-1001/pathep-[eth1/11]" + - name: externalcinf + vnicName: "" + path: "topology/pod-1/paths-1001/pathep-[eth1/12]" + + logical_interfaces: + - name: internal + label: internal + device: my_device + concrete_interface: internalcinf + - name: internal + label: internal + device: my_device_2 + concrete_interface: internalcinf + - name: external + label: external + device: my_device + concrete_interface: externalcinf + - name: external + label: external + device: my_device_2 + concrete_interface: externalcinf \ No newline at end of file From d8d6cdf4f2701cc957cb106e121a58b6126db10f Mon Sep 17 00:00:00 2001 From: Joseph LeClerc Date: Thu, 8 Oct 2015 16:33:18 -0700 Subject: [PATCH 10/23] Small change to createL4L7LogicalInterface.py. --- .../generic_code/apicPython/createL4L7LogicalInterface.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configuration-python/generic_code/apicPython/createL4L7LogicalInterface.py b/configuration-python/generic_code/apicPython/createL4L7LogicalInterface.py index bba1194..892a80f 100644 --- a/configuration-python/generic_code/apicPython/createL4L7LogicalInterface.py +++ b/configuration-python/generic_code/apicPython/createL4L7LogicalInterface.py @@ -16,7 +16,7 @@ def create_l4l7_logical_interface(parent_mo, name, **args): valid_keys = ['name', 'encap'] kwargs = {k: v for k, v in args.items() if (k in valid_keys and v)} vns_lif = LIf(parent_mo, name, **kwargs) - if 'interface_label' in args: + if 'label' in args: vns_rsmetaif = add_source_relation_to_interface_label(vns_lif, device_package=args['device_package'], label= args['label']) if 'concrete_interface': vns_rscifatt = add_association_to_concrete_interface(vns_lif, tenant=args['tenant'], cluster=args['cluster'], device=args['device'], cifname=args['cifname']) From 88775b883894ec836bd71b86315653a0d10b8b7d Mon Sep 17 00:00:00 2001 From: Joseph LeClerc Date: Thu, 8 Oct 2015 16:34:22 -0700 Subject: [PATCH 11/23] Document L4-L7 section of dynamicallyCreateApplication.yaml. Add placeholders for virtual device property holders. --- .../dynamicallyCreateApplication.yaml | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/configuration-python/generic_code/apicPython/dynamicallyCreateApplication.yaml b/configuration-python/generic_code/apicPython/dynamicallyCreateApplication.yaml index fde930a..adf8ec7 100644 --- a/configuration-python/generic_code/apicPython/dynamicallyCreateApplication.yaml +++ b/configuration-python/generic_code/apicPython/dynamicallyCreateApplication.yaml @@ -230,6 +230,44 @@ applied_contracts: epg: App_EPG type: consumed +# Specify L4-L7 device clusters in this tenant. +# Usage: +# - name: +# context_aware: [single-Context | multi-Context] +# device_type: [PHYSICAL | VIRTUAL] +# function_type: [GoTo | GoThrough] +# cluster_username: +# cluster_password: +# cluster_ip: +# cluster_port: +# device_package: -- +# vmm_provider: VMware # for virtual devices +# vmm_domain: my_firepower_domain # for virtual devices +# +# devices: +# - name: +# vmName: # for virtual devices +# vcenterName: # for virtual devices +# vmm_provider: # for virtual devices +# vmm_domain: # for virtual devices +# vmm_controller: +# device_ip: +# device_port: +# +# concrete_interfaces: +# - name: +# vnicName: # for virtual devices +# path: # path to the physical port/PC/vPC +# +# logical_interfaces: +# - name: +# label: # Varies between device packages. See the device package device specification file for valid labels. +# device: +# concrete_interface: +# +# All args other than "name" are optional unless required by APIC. + l4l7_devices: - name: my_cluster context_aware: single-Context @@ -240,9 +278,16 @@ l4l7_devices: cluster_ip: 10.10.10.11 cluster_port: 443 device_package: Cisco-FirePOWER-1.0 + #vmm_provider: VMware + #vmm_domain: my_firepower_domain devices: - name: my_device + #vmName: Virtual3D64_a + #vcenterName: my_vCenter + #vmm_provider: VMware + #vmm_domain: my_vmm_domain + #vmm_controller: my_vCenter device_username: admin device_password: device_password_1 device_ip: 10.10.10.2 @@ -255,6 +300,11 @@ l4l7_devices: vnicName: "" path: "topology/pod-1/paths-1001/pathep-[eth1/12]" - name: my_device_2 + #vmName: Virtual3D64_b + #vcenterName: my_vCenter + #vmm_provider: VMware + #vmm_domain: my_vmm_domain + #vmm_controller: my_vCenter device_username: admin device_password: device_password_2 device_ip: 10.10.10.3 From aca154223176faec3442c1c74b546c15329aa58a Mon Sep 17 00:00:00 2001 From: Joseph LeClerc Date: Fri, 9 Oct 2015 11:27:59 -0700 Subject: [PATCH 12/23] Add virtual cluster and virtual device support. --- .../apicPython/dynamicallyCreateApplication.py | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/configuration-python/generic_code/apicPython/dynamicallyCreateApplication.py b/configuration-python/generic_code/apicPython/dynamicallyCreateApplication.py index 834bc6b..70017e7 100644 --- a/configuration-python/generic_code/apicPython/dynamicallyCreateApplication.py +++ b/configuration-python/generic_code/apicPython/dynamicallyCreateApplication.py @@ -110,7 +110,10 @@ def main_function(self): # add devices to cluster if is_valid_key(cluster, 'devices'): for device in cluster['devices']: - vns_cdev = createL4L7Device.create_l4l7_device(vns_ldevvip, **device) + if 'vmm provider' in cluster and 'vmm_domain' in cluster: + vns_cdev = createL4L7Device.create_l4l7_device(vns_ldevvip, vmm_provider=cluster['vmm_provider'], vmm_domain=cluster['vmm_domain'] **device) + else: + vns_cdev = createL4L7Device.create_l4l7_device(vns_ldevvip, **device) self.commit_change(changed_object=vns_cdev) # add concrete interfaces to devices @@ -124,16 +127,6 @@ def main_function(self): for logical_interface in cluster['logical_interfaces']: vns_lif = createL4L7LogicalInterface.create_l4l7_logical_interface(vns_ldevvip, logical_interface['name'], device=logical_interface['device'], label=logical_interface['label'], tenant=self.tenant, cluster=cluster['name'], cifname=logical_interface['concrete_interface']) self.commit_change(changed_object=vns_lif) -''' -def create_l4l7_logical_interface(parent_mo, name, **args): - """The logical interface is associated with a set of concrete interfaces from the L4-L7 device cluster. This is used to define the connection between a service graph and device interfaces.""" - args = args['optional_args'] if 'optional_args' in args.keys() else args - valid_keys = ['name', 'encap'] - ... - - vns_rsmetaif = add_source_relation_to_interface_label(vns_lif, device_package= , label= ]) - if 'concrete_interface': - vns_rscifatt = add_association_to_concrete_interface(vns_lif, tenant= , cluster= , device = , interface= )''' if __name__ == '__main__': mo = DynamicallyCreateApplication() From d771f72d27497b2341cfa405d033429b17eee091 Mon Sep 17 00:00:00 2001 From: Joseph LeClerc Date: Fri, 9 Oct 2015 11:28:48 -0700 Subject: [PATCH 13/23] Simplify YAML configuration for L4-L7 devices. --- .../dynamicallyCreateApplication.yaml | 41 ++++++++----------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/configuration-python/generic_code/apicPython/dynamicallyCreateApplication.yaml b/configuration-python/generic_code/apicPython/dynamicallyCreateApplication.yaml index adf8ec7..6e9c578 100644 --- a/configuration-python/generic_code/apicPython/dynamicallyCreateApplication.yaml +++ b/configuration-python/generic_code/apicPython/dynamicallyCreateApplication.yaml @@ -241,32 +241,31 @@ applied_contracts: # cluster_ip: # cluster_port: # device_package: -- -# vmm_provider: VMware # for virtual devices -# vmm_domain: my_firepower_domain # for virtual devices +# vmm_provider: VMware # For virtual devices. +# vmm_domain: my_firepower_domain # For virtual devices. # # devices: # - name: -# vmName: # for virtual devices -# vcenterName: # for virtual devices -# vmm_provider: # for virtual devices -# vmm_domain: # for virtual devices -# vmm_controller: # For virtual devices. +# vcenterName: # For virtual devices. +# vmm_controller: # device_ip: # device_port: # # concrete_interfaces: # - name: -# vnicName: # for virtual devices -# path: # path to the physical port/PC/vPC +# vnicName: # For virtual devices. +# path: # For physical devices. Path to the physical port/PC/vPC. # # logical_interfaces: # - name: -# label: # Varies between device packages. See the device package device specification file for valid labels. -# device: -# concrete_interface: +# label: # Mandatory. Varies between device packages. See the device package device specification file for valid labels. +# device: # Mandatory. +# concrete_interface: # Mandatory. # -# All args other than "name" are optional unless required by APIC. +# All sections are optional. All parameters other than "name" are optional, with the exception of keys in the "logical_interfaces" section. +# l4l7_devices: - name: my_cluster @@ -283,10 +282,8 @@ l4l7_devices: devices: - name: my_device - #vmName: Virtual3D64_a + #vmName: Virtual3D64 #vcenterName: my_vCenter - #vmm_provider: VMware - #vmm_domain: my_vmm_domain #vmm_controller: my_vCenter device_username: admin device_password: device_password_1 @@ -294,16 +291,14 @@ l4l7_devices: device_port: 443 concrete_interfaces: - name: internalcinf - vnicName: "" + #vnicName: Network adapter 2 path: "topology/pod-1/paths-1001/pathep-[eth1/11]" - name: externalcinf - vnicName: "" + #vnicName: Network adapter 3 path: "topology/pod-1/paths-1001/pathep-[eth1/12]" - name: my_device_2 - #vmName: Virtual3D64_b + #vmName: Virtual3D64 #vcenterName: my_vCenter - #vmm_provider: VMware - #vmm_domain: my_vmm_domain #vmm_controller: my_vCenter device_username: admin device_password: device_password_2 @@ -311,10 +306,10 @@ l4l7_devices: device_port: 443 concrete_interfaces: - name: internalcinf - vnicName: "" + #vnicName: Network adapter 4 path: "topology/pod-1/paths-1001/pathep-[eth1/11]" - name: externalcinf - vnicName: "" + #vnicName: Network adapter 5 path: "topology/pod-1/paths-1001/pathep-[eth1/12]" logical_interfaces: From b539575ade75e7bba0bd05f16d4acb96bbde92da Mon Sep 17 00:00:00 2001 From: Joseph LeClerc Date: Fri, 9 Oct 2015 11:29:29 -0700 Subject: [PATCH 14/23] Add VMM domain profile source relation support for clusters. --- .../generic_code/apicPython/createL4L7Cluster.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/configuration-python/generic_code/apicPython/createL4L7Cluster.py b/configuration-python/generic_code/apicPython/createL4L7Cluster.py index 17efc2e..57515c4 100644 --- a/configuration-python/generic_code/apicPython/createL4L7Cluster.py +++ b/configuration-python/generic_code/apicPython/createL4L7Cluster.py @@ -1,5 +1,5 @@ -from cobra.model.vns import LDevVip, RsMDevAtt, CCred, CCredSecret, CMgmt +from cobra.model.vns import LDevVip, RsMDevAtt, CCred, CCredSecret, CMgmt, RsALDevToDomP from createMo import * import getpass import sys @@ -34,6 +34,8 @@ def create_l4l7_cluster(fv_tenant, name, **args): vns_ccredsecret = add_concrete_device_access_credentials_secret(vns_ldevvip, optional_args=args) if 'cluster_ip' in args or 'cluster_port' in args: vns_cmgmt = add_management_interface(vns_ldevvip, optional_args=args) + if 'vmm_provider' in args and 'vmm_domain' in args: + vns_rsaldevtodomp = add_source_relation_to_vmm_domain_profile(vns_ldevvip, optional_args=args) return vns_ldevvip def add_metadata_source_relation(cluster_mo, **args): @@ -63,10 +65,11 @@ def add_management_interface(cluster_mo, **args): kwargs = {key_map[k]: v for k, v in kwargs.items()} return CMgmt(cluster_mo, name='devMgmt', **kwargs) -def add_concrete_device(cluster_mo, **args): - """ Calls L4L7Device.py to create CDev child MO's """ - return createL4L7Device.create_l4l7_device(cluster_mo, **args) - +def add_source_relation_to_vmm_domain_profile(cluster_mo, **args): + """A source relation to the VMM domain profile.""" + valid_keys = ['vmm_provider', 'vmm_domain'] + kwargs = {k: v for k, v in args.items() if (k in valid_keys and v)} + return RsALDevToDomP(cluster_mo, tDn='uni/vmmp-{vmm_provider}/dom-{vmm_domain}') class CreateL4L7Cluster(CreateMo): def __init__(self): From 8c795bf59f0e6ed4b21da2e62d0470f98b4b87ef Mon Sep 17 00:00:00 2001 From: Joseph LeClerc Date: Fri, 9 Oct 2015 11:31:03 -0700 Subject: [PATCH 15/23] Add VMM domain controller profile source relation support for devices. --- .../generic_code/apicPython/createL4L7Device.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/configuration-python/generic_code/apicPython/createL4L7Device.py b/configuration-python/generic_code/apicPython/createL4L7Device.py index 85f0be0..28f30f8 100644 --- a/configuration-python/generic_code/apicPython/createL4L7Device.py +++ b/configuration-python/generic_code/apicPython/createL4L7Device.py @@ -1,5 +1,5 @@ -from cobra.model.vns import CDev, LDevVip, CCred, CCredSecret, CMgmt +from cobra.model.vns import CDev, LDevVip, CCred, CCredSecret, CMgmt, RsCDevToCtrlrP from createMo import * def input_key_args(): @@ -22,6 +22,8 @@ def create_l4l7_device(parent_mo, name, **args): vns_ccredsecret = add_concrete_device_access_credentials_secret(vns_cdev, optional_args=args) if 'device_ip' in args or 'device_port' in args: vns_cmgmt = add_management_interface(vns_cdev, optional_args=args) + if 'vmm_provider' in args and 'vmm_domain' in args and 'vmm_controller' in args: + vns_rscdevtoctrlrp = add_source_relation_to_vmm_domain_controller_profile(vns_cdev, optional_args=args) return vns_cdev def add_concrete_device_access_credentials(device_mo, **args): @@ -43,6 +45,12 @@ def add_management_interface(device_mo, **args): kwargs = {key_map[k]: v for k, v in kwargs.items()} return CMgmt(device_mo, name='devMgmt', **kwargs) +def add_source_relation_to_vmm_domain_controller_profile(device_mo, **args): + """Source relation to the vmm domain controller profile for validation.""" + args = args['optional_args'] if 'optional_args' in args.keys() else args + valid_keys = ['vmm_provider','vmm_domain','vmm_controller'] + return RsCDevToCtrlrP(device_mo, tDn='uni/vmmp-{vmm_provider}/dom-{vmm_domain}/ctrlr-{vmm_controller}') + class CreateL4L7Device(CreateMo): def __init__(self): self.description = 'Create an L4-L7 concrete device' From 67fdfc0d22c8ef3a282bda3f6a83cd7a8820933f Mon Sep 17 00:00:00 2001 From: Joseph LeClerc Date: Fri, 9 Oct 2015 13:37:08 -0700 Subject: [PATCH 16/23] Add recursive L4-L7 services folder and parameter parsing. --- .../apicPython/createL4L7Cluster.py | 35 ++++++++++++++++++- .../apicPython/createL4L7Device.py | 35 ++++++++++++++++++- 2 files changed, 68 insertions(+), 2 deletions(-) diff --git a/configuration-python/generic_code/apicPython/createL4L7Cluster.py b/configuration-python/generic_code/apicPython/createL4L7Cluster.py index 57515c4..a9a34ac 100644 --- a/configuration-python/generic_code/apicPython/createL4L7Cluster.py +++ b/configuration-python/generic_code/apicPython/createL4L7Cluster.py @@ -1,5 +1,5 @@ -from cobra.model.vns import LDevVip, RsMDevAtt, CCred, CCredSecret, CMgmt, RsALDevToDomP +from cobra.model.vns import LDevVip, RsMDevAtt, CCred, CCredSecret, CMgmt, RsALDevToDomP, DevFolder, DevParam from createMo import * import getpass import sys @@ -36,6 +36,8 @@ def create_l4l7_cluster(fv_tenant, name, **args): vns_cmgmt = add_management_interface(vns_ldevvip, optional_args=args) if 'vmm_provider' in args and 'vmm_domain' in args: vns_rsaldevtodomp = add_source_relation_to_vmm_domain_profile(vns_ldevvip, optional_args=args) + if 'device_folders' in args: + add_l4l7_device_folders(vns_ldevvip, args['device_folders']) return vns_ldevvip def add_metadata_source_relation(cluster_mo, **args): @@ -71,6 +73,37 @@ def add_source_relation_to_vmm_domain_profile(cluster_mo, **args): kwargs = {k: v for k, v in args.items() if (k in valid_keys and v)} return RsALDevToDomP(cluster_mo, tDn='uni/vmmp-{vmm_provider}/dom-{vmm_domain}') +def add_l4l7_device_folders(parent_mo, folder_list): + for folder in folder_list: + add_l4l7_device_folder(parent_mo, **folder) + +def add_l4l7_device_folder(parent_mo, **args): + """Recursively add device folders and parameters to parent mo. + + @param parent_mo: The parent MO of the top level folder is the CDev, but the parent MO of a subfolder is its parent folder. + """ + args = args['optional_args'] if 'optional_args' in args.keys() else args + folder_required_keys = ['name', 'key'] + param_required_keys = ['name', 'key', 'value'] + + # parse folders + if all(k in args.keys() for k in folder_required_keys): + vns_devfolder = DevFolder(parent_mo, **{k: v for k,v in args.items() if k in folder_required_keys and v}) + + # parse params + if 'device_params' in args.keys(): # This folder contains device params + for param in args['device_params']: + if all(k in param.keys() for k in param_required_keys): + DevParam(vns_devfolder, **param) + + # parse subfolders + if 'device_folders' in args.keys(): + for folder in args['device_folders']: + add_dev_folders_params(vns_devfolder, **folder) + return vns_devfolder + else: + raise Exception('Invalid L4-L7 device folder configuration. Missing required keys "{0}": {1}'.format(folder_required_keys, repr(args))) + class CreateL4L7Cluster(CreateMo): def __init__(self): self.description = 'Create an L4-L7 device cluster' diff --git a/configuration-python/generic_code/apicPython/createL4L7Device.py b/configuration-python/generic_code/apicPython/createL4L7Device.py index 28f30f8..572e93b 100644 --- a/configuration-python/generic_code/apicPython/createL4L7Device.py +++ b/configuration-python/generic_code/apicPython/createL4L7Device.py @@ -1,5 +1,5 @@ -from cobra.model.vns import CDev, LDevVip, CCred, CCredSecret, CMgmt, RsCDevToCtrlrP +from cobra.model.vns import CDev, LDevVip, CCred, CCredSecret, CMgmt, RsCDevToCtrlrP, DevFolder, DevParam from createMo import * def input_key_args(): @@ -24,6 +24,8 @@ def create_l4l7_device(parent_mo, name, **args): vns_cmgmt = add_management_interface(vns_cdev, optional_args=args) if 'vmm_provider' in args and 'vmm_domain' in args and 'vmm_controller' in args: vns_rscdevtoctrlrp = add_source_relation_to_vmm_domain_controller_profile(vns_cdev, optional_args=args) + if 'device_folders' in args: + add_l4l7_device_folders(vns_cdev, args['device_folders']) return vns_cdev def add_concrete_device_access_credentials(device_mo, **args): @@ -51,6 +53,37 @@ def add_source_relation_to_vmm_domain_controller_profile(device_mo, **args): valid_keys = ['vmm_provider','vmm_domain','vmm_controller'] return RsCDevToCtrlrP(device_mo, tDn='uni/vmmp-{vmm_provider}/dom-{vmm_domain}/ctrlr-{vmm_controller}') +def add_l4l7_device_folders(parent_mo, folder_list): + for folder in folder_list: + add_l4l7_device_folder(parent_mo, **folder) + +def add_l4l7_device_folder(parent_mo, **args): + """Recursively add device folders and parameters to parent mo. + + @param parent_mo: The parent MO of the top level folder is the CDev, but the parent MO of a subfolder is its parent folder. + """ + args = args['optional_args'] if 'optional_args' in args.keys() else args + folder_required_keys = ['name', 'key'] + param_required_keys = ['name', 'key', 'value'] + + # parse folders + if all(k in args.keys() for k in folder_required_keys): + vns_devfolder = DevFolder(parent_mo, **{k: v for k,v in args.items() if k in folder_required_keys and v}) + + # parse params + if 'device_params' in args.keys(): # This folder contains device params + for param in args['device_params']: + if all(k in param.keys() for k in param_required_keys): + DevParam(vns_devfolder, **param) + + # parse subfolders + if 'device_folders' in args.keys(): + for folder in args['device_folders']: + add_dev_folders_params(vns_devfolder, **folder) + return vns_devfolder + else: + raise Exception('Invalid L4-L7 device folder configuration. Missing required keys "{0}": {1}'.format(folder_required_keys, repr(args))) + class CreateL4L7Device(CreateMo): def __init__(self): self.description = 'Create an L4-L7 concrete device' From 8c50ee316d4c3ec2f958b5b3630700d09c440894 Mon Sep 17 00:00:00 2001 From: Joseph LeClerc Date: Fri, 9 Oct 2015 13:48:18 -0700 Subject: [PATCH 17/23] Add support for L4-L7 device folders/parameters to dynamicallyCreateApplication.py, update dynamicallyCreateApplication.yaml and document usage. --- .../dynamicallyCreateApplication.py | 4 +- .../dynamicallyCreateApplication.yaml | 44 ++++++++++++++++--- 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/configuration-python/generic_code/apicPython/dynamicallyCreateApplication.py b/configuration-python/generic_code/apicPython/dynamicallyCreateApplication.py index 70017e7..7ba51e2 100644 --- a/configuration-python/generic_code/apicPython/dynamicallyCreateApplication.py +++ b/configuration-python/generic_code/apicPython/dynamicallyCreateApplication.py @@ -111,7 +111,7 @@ def main_function(self): if is_valid_key(cluster, 'devices'): for device in cluster['devices']: if 'vmm provider' in cluster and 'vmm_domain' in cluster: - vns_cdev = createL4L7Device.create_l4l7_device(vns_ldevvip, vmm_provider=cluster['vmm_provider'], vmm_domain=cluster['vmm_domain'] **device) + vns_cdev = createL4L7Device.create_l4l7_device(vns_ldevvip, vmm_provider=cluster['vmm_provider'], vmm_domain=cluster['vmm_domain'], **device) else: vns_cdev = createL4L7Device.create_l4l7_device(vns_ldevvip, **device) self.commit_change(changed_object=vns_cdev) @@ -125,7 +125,7 @@ def main_function(self): # add logical interfaces to cluster if is_valid_key(cluster, 'logical_interfaces'): for logical_interface in cluster['logical_interfaces']: - vns_lif = createL4L7LogicalInterface.create_l4l7_logical_interface(vns_ldevvip, logical_interface['name'], device=logical_interface['device'], label=logical_interface['label'], tenant=self.tenant, cluster=cluster['name'], cifname=logical_interface['concrete_interface']) + vns_lif = createL4L7LogicalInterface.create_l4l7_logical_interface(vns_ldevvip, logical_interface['name'], device=logical_interface['device'], label=logical_interface['label'], tenant=self.tenant, cluster=cluster['name'], cifname=logical_interface['concrete_interface'], device_package=cluster['device_package']) self.commit_change(changed_object=vns_lif) if __name__ == '__main__': diff --git a/configuration-python/generic_code/apicPython/dynamicallyCreateApplication.yaml b/configuration-python/generic_code/apicPython/dynamicallyCreateApplication.yaml index 6e9c578..c3b8b1a 100644 --- a/configuration-python/generic_code/apicPython/dynamicallyCreateApplication.yaml +++ b/configuration-python/generic_code/apicPython/dynamicallyCreateApplication.yaml @@ -231,6 +231,8 @@ applied_contracts: type: consumed # Specify L4-L7 device clusters in this tenant. +# All top-level sections are optional. All parameters other than "name" are optional, with the exception of keys in the "logical_interfaces" section. +# # Usage: # - name: # context_aware: [single-Context | multi-Context] @@ -241,6 +243,13 @@ applied_contracts: # cluster_ip: # cluster_port: # device_package: -- +# device_folders: # Recursive; device folders can contain other device folders. +# - name: +# key: +# device_params: +# - name: +# key: +# value: # vmm_provider: VMware # For virtual devices. # vmm_domain: my_firepower_domain # For virtual devices. # @@ -252,6 +261,13 @@ applied_contracts: # device_username: # device_ip: # device_port: +# device_folders: # Recursive; device folders can contain other device folders. +# - name: +# key: +# device_params: +# - name: +# key: +# value: # # concrete_interfaces: # - name: @@ -263,10 +279,6 @@ applied_contracts: # label: # Mandatory. Varies between device packages. See the device package device specification file for valid labels. # device: # Mandatory. # concrete_interface: # Mandatory. -# -# All sections are optional. All parameters other than "name" are optional, with the exception of keys in the "logical_interfaces" section. -# - l4l7_devices: - name: my_cluster context_aware: single-Context @@ -277,9 +289,15 @@ l4l7_devices: cluster_ip: 10.10.10.11 cluster_port: 443 device_package: Cisco-FirePOWER-1.0 + device_folders: + - name: DeviceRegConfig + key: DeviceRegConfig + device_params: + - name: ac_policy + key: ac_policy + value: Default Access Control #vmm_provider: VMware #vmm_domain: my_firepower_domain - devices: - name: my_device #vmName: Virtual3D64 @@ -289,6 +307,21 @@ l4l7_devices: device_password: device_password_1 device_ip: 10.10.10.2 device_port: 443 + # device_folders: + # - name: DeviceRegConfig + # key: DeviceRegConfig + # device_params: + # - name: ac_policy + # key: ac_policy + # value: Default Access Control + # - name: + # key: + # value: + # device_folders: + # - name: + # key: + # device_params: + # device_folders: concrete_interfaces: - name: internalcinf #vnicName: Network adapter 2 @@ -311,7 +344,6 @@ l4l7_devices: - name: externalcinf #vnicName: Network adapter 5 path: "topology/pod-1/paths-1001/pathep-[eth1/12]" - logical_interfaces: - name: internal label: internal From d1901bd10fae26b3b24299a3f72e1e22ddc5319a Mon Sep 17 00:00:00 2001 From: Joseph LeClerc Date: Mon, 19 Oct 2015 14:36:30 -0700 Subject: [PATCH 18/23] Add support for source relation to physical domain profile (RsALDevToDomP) --- .../apicPython/createL4L7Cluster.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/configuration-python/generic_code/apicPython/createL4L7Cluster.py b/configuration-python/generic_code/apicPython/createL4L7Cluster.py index a9a34ac..6379b79 100644 --- a/configuration-python/generic_code/apicPython/createL4L7Cluster.py +++ b/configuration-python/generic_code/apicPython/createL4L7Cluster.py @@ -1,5 +1,5 @@ -from cobra.model.vns import LDevVip, RsMDevAtt, CCred, CCredSecret, CMgmt, RsALDevToDomP, DevFolder, DevParam +from cobra.model.vns import LDevVip, RsMDevAtt, CCred, CCredSecret, CMgmt, RsALDevToDomP, RsALDevToPhysDomP, DevFolder, DevParam from createMo import * import getpass import sys @@ -36,6 +36,8 @@ def create_l4l7_cluster(fv_tenant, name, **args): vns_cmgmt = add_management_interface(vns_ldevvip, optional_args=args) if 'vmm_provider' in args and 'vmm_domain' in args: vns_rsaldevtodomp = add_source_relation_to_vmm_domain_profile(vns_ldevvip, optional_args=args) + if 'physical_domain' in args: + vns_rsaldevtophysdomp = add_source_relation_to_physical_domain_profile(vns_ldevvip, optional_args=args) if 'device_folders' in args: add_l4l7_device_folders(vns_ldevvip, args['device_folders']) return vns_ldevvip @@ -69,9 +71,17 @@ def add_management_interface(cluster_mo, **args): def add_source_relation_to_vmm_domain_profile(cluster_mo, **args): """A source relation to the VMM domain profile.""" + args = args['optional_args'] if 'optional_args' in args.keys() else args valid_keys = ['vmm_provider', 'vmm_domain'] kwargs = {k: v for k, v in args.items() if (k in valid_keys and v)} - return RsALDevToDomP(cluster_mo, tDn='uni/vmmp-{vmm_provider}/dom-{vmm_domain}') + return RsALDevToDomP(cluster_mo, tDn='uni/vmmp-{vmm_provider}/dom-{vmm_domain}'.format(**kwargs)) + +def add_source_relation_to_physical_domain_profile(cluster_mo, **args): + """A source relation to a physical domain profile.""" + args = args['optional_args'] if 'optional_args' in args.keys() else args + valid_keys = ['physical_domain'] + kwargs = {k: v for k, v in args.items() if (k in valid_keys and v)} + return RsALDevToPhysDomP(cluster_mo, tDn='uni/phys-{physical_domain}'.format(**kwargs)) def add_l4l7_device_folders(parent_mo, folder_list): for folder in folder_list: @@ -99,8 +109,7 @@ def add_l4l7_device_folder(parent_mo, **args): # parse subfolders if 'device_folders' in args.keys(): for folder in args['device_folders']: - add_dev_folders_params(vns_devfolder, **folder) - return vns_devfolder + add_l4l7_device_folder(vns_devfolder, **folder) else: raise Exception('Invalid L4-L7 device folder configuration. Missing required keys "{0}": {1}'.format(folder_required_keys, repr(args))) From 9ee16e25a5784930e0541503803ffe80c97810ed Mon Sep 17 00:00:00 2001 From: Joseph LeClerc Date: Mon, 19 Oct 2015 14:38:52 -0700 Subject: [PATCH 19/23] update l4l7 device folder parsing function --- .../generic_code/apicPython/createL4L7Device.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configuration-python/generic_code/apicPython/createL4L7Device.py b/configuration-python/generic_code/apicPython/createL4L7Device.py index 572e93b..c6f680c 100644 --- a/configuration-python/generic_code/apicPython/createL4L7Device.py +++ b/configuration-python/generic_code/apicPython/createL4L7Device.py @@ -51,7 +51,8 @@ def add_source_relation_to_vmm_domain_controller_profile(device_mo, **args): """Source relation to the vmm domain controller profile for validation.""" args = args['optional_args'] if 'optional_args' in args.keys() else args valid_keys = ['vmm_provider','vmm_domain','vmm_controller'] - return RsCDevToCtrlrP(device_mo, tDn='uni/vmmp-{vmm_provider}/dom-{vmm_domain}/ctrlr-{vmm_controller}') + kwargs = {k: v for k, v in args.items() if (k in valid_keys and v)} + return RsCDevToCtrlrP(device_mo, tDn='uni/vmmp-{vmm_provider}/dom-{vmm_domain}/ctrlr-{vmm_controller}'.format(**kwargs)) def add_l4l7_device_folders(parent_mo, folder_list): for folder in folder_list: @@ -80,7 +81,6 @@ def add_l4l7_device_folder(parent_mo, **args): if 'device_folders' in args.keys(): for folder in args['device_folders']: add_dev_folders_params(vns_devfolder, **folder) - return vns_devfolder else: raise Exception('Invalid L4-L7 device folder configuration. Missing required keys "{0}": {1}'.format(folder_required_keys, repr(args))) From d3ab179fe795b87bab55da03c3d4b50f0cb4eac3 Mon Sep 17 00:00:00 2001 From: Joseph LeClerc Date: Mon, 19 Oct 2015 14:41:16 -0700 Subject: [PATCH 20/23] Add logical device physical domain profile relation to YAML file, document. --- .../generic_code/apicPython/dynamicallyCreateApplication.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configuration-python/generic_code/apicPython/dynamicallyCreateApplication.yaml b/configuration-python/generic_code/apicPython/dynamicallyCreateApplication.yaml index c3b8b1a..e34ec45 100644 --- a/configuration-python/generic_code/apicPython/dynamicallyCreateApplication.yaml +++ b/configuration-python/generic_code/apicPython/dynamicallyCreateApplication.yaml @@ -250,6 +250,7 @@ applied_contracts: # - name: # key: # value: +# physical_domain: phys # For physical devices. # vmm_provider: VMware # For virtual devices. # vmm_domain: my_firepower_domain # For virtual devices. # @@ -296,6 +297,7 @@ l4l7_devices: - name: ac_policy key: ac_policy value: Default Access Control + physical_domain: phys #vmm_provider: VMware #vmm_domain: my_firepower_domain devices: From c675169e32e882de271df9c516df59101f6d762b Mon Sep 17 00:00:00 2001 From: Joseph LeClerc Date: Tue, 20 Oct 2015 11:51:11 -0700 Subject: [PATCH 21/23] Change formatting in createL4L7LogicalInterface.py --- .../generic_code/apicPython/createL4L7LogicalInterface.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/configuration-python/generic_code/apicPython/createL4L7LogicalInterface.py b/configuration-python/generic_code/apicPython/createL4L7LogicalInterface.py index 892a80f..99fa2ac 100644 --- a/configuration-python/generic_code/apicPython/createL4L7LogicalInterface.py +++ b/configuration-python/generic_code/apicPython/createL4L7LogicalInterface.py @@ -13,11 +13,11 @@ def input_optional_args(): def create_l4l7_logical_interface(parent_mo, name, **args): """The logical interface is associated with a set of concrete interfaces from the L4-L7 device cluster. This is used to define the connection between a service graph and device interfaces.""" args = args['optional_args'] if 'optional_args' in args.keys() else args - valid_keys = ['name', 'encap'] + valid_keys = ['encap'] kwargs = {k: v for k, v in args.items() if (k in valid_keys and v)} vns_lif = LIf(parent_mo, name, **kwargs) if 'label' in args: - vns_rsmetaif = add_source_relation_to_interface_label(vns_lif, device_package=args['device_package'], label= args['label']) + vns_rsmetaif = add_source_relation_to_interface_label(vns_lif, device_package=args['device_package'], label=args['label']) if 'concrete_interface': vns_rscifatt = add_association_to_concrete_interface(vns_lif, tenant=args['tenant'], cluster=args['cluster'], device=args['device'], cifname=args['cifname']) return vns_lif @@ -32,7 +32,7 @@ def add_association_to_concrete_interface(logical_interface_mo, **args): """Association to a set of concrete interfaces from the device in the cluster.""" valid_keys = ['tenant', 'cluster', 'device', 'cifname'] kwargs = {k: v for k, v in args.items() if (k in valid_keys and v)} - return RsCIfAtt(logical_interface_mo, tDn='uni/tn-{tenant}/lDevVip-{cluster}/cDev-{device}/cIf-{cifname}'.format(**kwargs)) + return RsCIfAtt(logical_interface_mo, tDn='uni/tn-{tenant}/lDevVip-{cluster}/cDev-{device}/cIf-[{cifname}]'.format(**kwargs)) class CreateL4L7ConcreteInterface(CreateMo): def __init__(self): From e1818d68686df3ab03cc24feaf5f18d28ccbbafa Mon Sep 17 00:00:00 2001 From: Joseph LeClerc Date: Tue, 20 Oct 2015 11:51:48 -0700 Subject: [PATCH 22/23] Refactor dynamicallyCreateApplication.py to work when missing keys (sections of YAML file) --- .../dynamicallyCreateApplication.py | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/configuration-python/generic_code/apicPython/dynamicallyCreateApplication.py b/configuration-python/generic_code/apicPython/dynamicallyCreateApplication.py index 7ba51e2..efc79cb 100644 --- a/configuration-python/generic_code/apicPython/dynamicallyCreateApplication.py +++ b/configuration-python/generic_code/apicPython/dynamicallyCreateApplication.py @@ -34,16 +34,16 @@ def __init__(self): def run_yaml_mode(self): super(DynamicallyCreateApplication, self).run_yaml_mode() - self.security_domains = self.args['security_domains'] - self.private_network = self.args['private_network'] - self.bridge_domains = self.args['bridge_domains'] - self.filters = self.args['filters'] - self.contracts = self.args['contracts'] - self.application = self.args['application']['name'] - self.application_optional_args = self.args['application']['optional_args'] - self.epgs = self.args['epgs'] - self.applied_contracts = self.args['applied_contracts'] - self.l4l7_devices = self.args['l4l7_devices'] + self.security_domains = self.args.get('security_domains', []) + self.private_network = self.args.get('private_network', []) + self.bridge_domains = self.args.get('bridge_domains', []) + self.filters = self.args.get('filters', []) + self.contracts = self.args.get('contracts', []) + self.application = self.args.get('application', {}).get('name', '') + self.application_optional_args = self.args.get('application', {}).get('optional_args', []) + self.epgs = self.args.get('epgs', []) + self.applied_contracts = self.args.get('applied_contracts', []) + self.l4l7_devices = self.args.get('l4l7_devices', []) def run_wizard_mode(self): print 'Wizard mode is not supported in this method. Please try Yaml mode.' @@ -62,7 +62,8 @@ def main_function(self): addSecurityDomain.add_security_domain(fv_tenant, security_domain) # create private network - createPrivateNetwork.create_private_network(fv_tenant, self.private_network) + if self.private_network: + createPrivateNetwork.create_private_network(fv_tenant, self.private_network) # create bridge domains for bridge_domain in self.bridge_domains: @@ -87,7 +88,8 @@ def main_function(self): createContract.add_filter_to_subject(vz_subj, filter) # create application - fv_ap = createApplication.create_application(fv_tenant, self.application, optional_args=self.application_optional_args) + if self.application: + fv_ap = createApplication.create_application(fv_tenant, self.application, optional_args=self.application_optional_args) # create EPGs for epg in self.epgs: From c842a4eec3d18f1967ee7f0a7ec06c5b3ae22987 Mon Sep 17 00:00:00 2001 From: Joseph LeClerc Date: Thu, 4 Feb 2016 13:38:43 -0800 Subject: [PATCH 23/23] Update createL4L7Device folder parsing to be in-line with createL4L7Cluster folder parsing. --- .../generic_code/apicPython/createL4L7Device.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configuration-python/generic_code/apicPython/createL4L7Device.py b/configuration-python/generic_code/apicPython/createL4L7Device.py index c6f680c..5834d93 100644 --- a/configuration-python/generic_code/apicPython/createL4L7Device.py +++ b/configuration-python/generic_code/apicPython/createL4L7Device.py @@ -80,7 +80,7 @@ def add_l4l7_device_folder(parent_mo, **args): # parse subfolders if 'device_folders' in args.keys(): for folder in args['device_folders']: - add_dev_folders_params(vns_devfolder, **folder) + add_l4l7_device_folder(vns_devfolder, **folder) else: raise Exception('Invalid L4-L7 device folder configuration. Missing required keys "{0}": {1}'.format(folder_required_keys, repr(args)))