Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.
Kamil Górski edited this page Jul 4, 2023 · 3 revisions

Device Templates

Device templates allow you to save a device configuration, apply it to one or more devices, and reuse the same configuration over and over again. There are two template types:

  • Feature template
  • CLI template

Templates are available in vManage under Configuration -> Templates tab.

User stories / suppported features

Device Template Feature Template CLI Template
Create - - -
View - - -
Edit - - -
Delete - - -

  1. Creating Device template via CLI & Feature template ☐
  2. Attaching template onto device ☐
  3. View Device Templates attached to a Feature Template ☐
  4. View Devices attached to a Device Template ☐
  5. Translating CLI templates into feature templates NEW
  6. Translating Feature Template into CLI Template ☐
  7. Export into CSV format ☐
  8. Perform pararell template operations like: ** NEW in API ** ☐
  • Attaching
  • Detaching
  • Editing
  • Creating
  • Deleting
  • Editing

Links

Configure Devices

Available Feature Templates

Create a Device Template

Device templates define a device's complete operational configuration. A device template consists of a number of feature templates. Each feature template defines the configuration for a particular Cisco SD-WAN software feature. Some feature templates are mandatory, indicated with an asterisk (*), and some are optional. Each mandatory feature template, and some of the optional ones too, have a factory-default template. For software features that have a factory-default template, you can use either the factory-default template (named Factory_Default_feature-name_Template) or you can create a custom feature template.

Create a Feature Templates

Implementation details are described in open brackets.

  1. Select the type of device for which you are creating a template. (User can select multiple device models. Each device model has its own feature templates assigned. In fact, we can treat that as sets of templates, therefore operator & [and] can be applied to check user input. User has to, however, create separate feature templates for software features that are available only on the device which is being configured.)
  2. In the UI, user fills some sort of the form. In python code we will provide classes which will fully support vManage feature creation with every configurable field (These classes are dataclasses. For now, they are being called a models, f.e. TenantModel which is a model for Tenant Feature Template. We try to re-use existing dataclasses from dataclasses.py file, but some of the models, introduces a completely new objects. Every model implements FeatureTemplate interface.)
  3. After Feature Template creation user's input is validated.

Model example

Tenant:

class TenantModel(FeatureTemplate):
    tenants: List[TenantInfo] = []
    payload_path: ClassVar[Path] = Path(__file__).parent / "tenant.json.j2"

    class Config:
        arbitrary_types_allowed = True

Cisco VPN:

class CiscoVPNModel(FeatureTemplate):
    payload_path: ClassVar[Path] = Path(__file__).parent / "feature/cisco_vpn.json.j2"
    tenant_vpn: Optional[int]
    tenant_org_name: Optional[str]
    vpn_id: int
    dns: Optional[DNS] = None
    mapping: List[Mapping] = []
    ipv4route: List[IPv4Route] = []
    ipv6route: List[IPv6Route] = []

    @validator('vpn_id')
    def check_id(cls, v, values):
        if v not in [0, 512]:
            if 'tenant_org_name' not in values:
                raise ValueError('Must enter the name of the organization.')
        return v

    def generate_vpn_id(self, session: vManageSession) -> None:
        self.tenant_vpn = self.vpn_id
        payload = {"resourcePoolDataType": "vpn", "tenantId": self.tenant_org_name, "tenantVpn": self.tenant_vpn}
        url = '/dataservice/resourcepool/resource/vpn'
        response = session.put(url=url, json=payload).json()
        self.vpn_id = response['deviceVpn']

    def generate_payload(self, session: vManageSession) -> str:
        if self.vpn_id not in [0, 512]:
            self.generate_vpn_id(session=session)
        return super().generate_payload(session)

    class Config:
        arbitrary_types_allowed = True

Cisco VPN Interface Ethernet:

class CiscoVpnInterfaceEthernetModel(FeatureTemplate):
    payload_path: ClassVar[Path] = Path(__file__).parent / "feature/cisco_vpn_interface_ethernet.json.j2"
    interface_name: InterfaceType
    shutdown: Optional[bool]
    type_address: TypeAddress = TypeAddress.STATIC
    ip: Optional[str]
    tunnel: Optional[Tunnel]
    mtu: Optional[int]
    autonegotiate: Optional[bool]

    class Config:
        arbitrary_types_allowed = True

Usage Example

session is vManageSession created by create_vManageSession factory method.

Tenant:

template_api = TemplatesAPI(session)

t1 = TenantInfo(
	organization_name="vIPtela Inc Regression-Tenant1 Inc", 
	name="tier_tenant1")
t2 = TenantInfo(
	organization_name="vIPtela Inc Regression-Tenant2 Inc", 
	name="tier_tenant2")

tenants=[t1, t2]
tenant_model = TenantModel(
    name="test",
    description="test",
    tenants=tenants
)

template_api.create_feature_template(tenant_model)

Cisco VPN:

  1. Create template for VPN0
template_api = TemplatesAPI(session)
vpn0 = CiscoVPNModel(
    name="vpn0_test",
    description="vpn0_test",
    vpn_id=0
)
template_api.create_feature_template(vpn0)
  1. Create template for VPN512.
template_api = TemplatesAPI(session)
vpn512 = CiscoVPNModel(
    name="vpn512_test",
    description="vpn512_test",
    vpn_id=512
)
template_api.create_feature_template(vpn512)
  1. Create template for VPN10. It is important to provide the name of the organization and session to vmanage when creating the payload - the method must generate a vpn id.
template_api = TemplatesAPI(session)
vpn10 = CiscoVPNModel(
    name="vpn10_test",
    description="vpn10_test",
    vpn_id=10,
    tenant_org_name="organization name"
)
template_api.create_feature_template(vpn10)
  1. Create template for VPN0 with DNS (ipv4, ipv6) and mapping.
template_api = TemplatesAPI(session)
dns = DNS(
    primary="192.168.1.1",
    secondary="192.168.1.2",
    primaryv6="2001:db8:bad:cab1:e001::41",
    secondaryv6="2001:db8:bad:cab1:e001::42",
)
map1= Mapping(
    name="test_map1", 
    ips=["192.168.2.1", "192.168.2.2"]
    )
map2 = Mapping(
    name="test_map2", 
    ips=["2001:db8:bad:cab1:e001::49", "2001:db8:bad:cab1:e001::15"])
mapping = [map1, map2]
vpn0_dns_mapping = CiscoVPNModel(
    name="vpn0_dns_mapping_test",
    description="vpn0_dns_mapping_test",
    vpn_id=0,
    dns=dns,
    mapping=mapping
)
template_api.create_feature_template(vpn0_dns_mapping)
  1. Create template for VPN0 with IPv4Route.
template_api = TemplatesAPI(session)
hop1 = NextHop(address="172.16.15.1")
hop2 = NextHop(address="172.16.15.2")
hop = [hop1, hop2]
ipv4route = IPv4Route(
    prefix="192.168.15.0/25", 
    gateway=GatewayType.NEXT_HOP, 
    next_hop=hop
    )
vpn0_ipv4route = CiscoVPNModel(
    name="vpn0_ipv4route_test",
    description="vpn0_ipv4route_test",
    vpn_id=0,
    ipv4route=[ipv4route]
)
template_api.create_feature_template(vpn0_ipv4route)
  1. Create template for VPN0 with IPv6Route.
template_api = TemplatesAPI(session)
hop1 = NextHop(address="3002:0bd6:0000:0000:0000:ee00:0033:6124")
hop2 = NextHop(address="3002:0bd6:0000:0000:0000:ee00:0033:6125")
hop = [hop1, hop2]
ipv6route = IPv6Route(
    prefixv6="3002:bd6::ee00:33:6778/12", 
    gatewayv6=GatewayType.NEXT_HOP, 
    next_hopv6=hop
    )
vpn0_ipv6route = CiscoVPNModel(
    name="vpn0_ipv6route_test",
    description="vpn0_ipv6route_test",
    vpn_id=0,
    ipv6route=[ipv6route]
)
template_api.create_feature_template(vpn0_ipv6route)

Cisco VPN Interface Ethernet:

  1. Create template
template_api = TemplatesAPI(session)
encapsulation = [
  Encapsulation(EncapType.GRE),
  Encapsulation(EncapType.IPSEC, preference=1, weight=1),
]
tunnel = Tunnel(
  color=ColorType.GOLD,
  all=True,
  bgp=True,
  encapsulation=encapsulation
)
vpn_interface = CiscoVpnInterfaceEthernetModel(
  name = "test",
  description = "test",
  interface_name = InterfaceType.ETHERNET,
  type_address = TypeAddress.DYNAMIC,
  tunnel=tunnel
)
template_api.create_feature_template(vpn_interface)

The scope of the project

Current implementation includes four feature templtes:

  • AAA
  • System
  • Cisco VPN
  • Cisco VPN Interface Ethernet
  • Tenant

Only the most essential endpoints are implemented, like:

  • Creating Feature Template
  • Creating Device Template from Feature Templates
  • Creating CLI Template
  • Attaching Device Template onto the Device

Exceptions

  • TemplateAlreadyExistsError
  • TemplateNotFoundError
  • TemplateCreationError (duplicating names, wrong values, etc)
  • TemplateAttachError
  • TemplateDeleteError (template is attached, need to delete it first)

Dataclasses

  • TemplateInfo
  • TenantInfo
  • TacasServer
  • RadiusServer
  • Mapping
  • DNS
  • CiscoVPNModel
  • Encapsulation
  • Tunnel
  • CiscoVpnInterfaceEthernetModel

Enums

  • DevicelModel
  • vManageVersion
  • InterfaceType
  • TypeAddress
  • ColorType
  • EncapType